kafka基础知识

Kafka是一个分布式的、可分区的、可复制的消息系统。

主要特点

  1. 分布式,可扩展
  2. 低延迟(毫秒级延迟)
  3. 持久化

基本概念

  • Producer - 生产者
  • Broker - kafka服务器
  • Consumer - 消费者
  • Consumer Group - 消费者分组
  • Topic - 主题
  • Partition - 分区
  • ISR = in-sync replicas 副本同步队列
  • AR = assigned replicas 所有副本
  • HW = high watermark 高水平位
  • LEO = log end offset
    Producer消息存储
    每个partition分为多个segment,每个segment对应两个文件.index和.log。.index只存索引,.log只存数据
    producer生产的消息会不断追加到log文件末尾,为防止文件过大导致数据定位效率地下,kafka采取了分段和索引机制。

Producer三种ACK机制

ack=1(默认):leader接收数据并确认,表示发送成功。如果leader宕机,数据丢失。
ack=0: 生产者将数据发出去就不管了,可靠性最低。
ack=1: 生产者等所有follower确认后才表示发送成功,可靠性最高。

分区的原因

  1. 方便在集群中扩展,每个partition可以通过调整以适应它所在的机器。每个topic可以有多个partition组成,因此整个集群中就可以适应任意大小的数据了。
  2. 可以提高并发。因为可以以partition为单位读写数据了。
    分区的原则
    我们需要将producer发送的数据封装成一个producerRecord对象

Exactly Once精准一次性
Exactly Once = 幂等性 + At least Once
At most once: ack = 0
At least once: ack = -1
精准一次性保证数据不重复不丢失,在broker中进行去重,以为主键,只持久化一份。
幂等性:producer不论向broker发送多少重复数据,broker端都只会持久化一条。
要启用幂等性,只需要将producer的参数中enable.idompotence设为true,此时ack被设定为-1。

Consumer消费方式
consumer采用pull拉取模式从broker获取数据。
pull模式很难适应消费速率不同的消费者,因为消息发送速率是由broker决定的。
Pull模式不足之处是,如果kafka没有数据,消费者可能陷入循环中,一直返回空数据。可以设置timeout参数。
消费策略
哪个partition由哪个consumer消费
kafka有两种分区消费策略:

  1. RoundRobin轮循:前提是消费者订阅的主题是一样的。
  2. Range(默认):按照范围分配

zookeeper的作用

新版的kafka减少了对ZK的依赖,主要是ZK的写性能不太好。
ZK现在主要用来作为leader的选举和检测broker是否存活,通过心跳机制。
Herd effect
任何broker或consumer增减都会触发所有的consumer进行rebalance。

kafka实现有序
kafka每个partition中的消息在写入时都是有序的,消费时,每个partition只能被每个group中的一个消费者消费,保证了消费时也是有序的。

什么场景使用消息队列

  1. 生产者不需要从消费者处获得反馈。
  2. 容许短暂的不一致性。
    个人认为消息队列的主要特点是异步处理,主要目的是减少请求响应时间和解耦。所以主要的使用场景就是将比较耗时而且不需要即时(同步)返回结果的操作作为消息放入消息队列。
    Kafka、ActiveMQ、RabbitMQ、RocketMQ 等这几种。
    ActiveMQ和RabbitMQ这两着因为吞吐量还有GitHub的社区活跃度的原因,在各大互联网公司都已经基本上绝迹了。
    基于Kafka和RocketMQ,吞吐量、可靠性、时效性等都很可观。
    Kafka和rocketmq单机十万吞吐量,延迟在毫秒级,分布式架构。
    kafka常用于日志采集和实时计算。
    消息队列带来的问题
  3. 如果消息服务挂掉,直接会导致整个依赖于消息服务的功能不可用。
  4. 系统一致性降低。
  5. 系统复杂性增高。是否有重复消费的情况这属于幂等消费问题。
    服务发现
    一个HTTP服务器既可以是服务提供者对外提供服务,也可以是消费者需要别的服务提供者提供的服务,这就是服务依赖。
    一个HTTP服务器,提供了API服务,有一个IP端口作为服务地址。
    服务发现有三个角色,服务提供者、服务消费者和服务中介。
    服务提供者将自己提供的服务地址注册到服务中介,服务消费者从服务中介那里查找自己想要的服务地址,然后使用这个服务。 服务中介提供多个服务,每个服务对应多个服务提供者。
    服务中介就是一个字典,字典里有很多key-value键值对,key是服务名称,value是服务提供者的地址列表。服务注册就是调用字典的put方法放东西,服务查找就是调用字典的get方法获取东西。
    Redis作为服务中介
    现流行的服务发现系统都是使用分布式数据库zookeeper etcd consul等来作为服务中介,他们是分布式的多节点的,挂掉了一个节点没关系。
    其实还有个redis-sentinel可以消除redis的单点问题,redis-sentinel可以在主节点挂掉的时候,自动升级从节点为主节点。所以拿redis干这件事也是可以的。用redis干服务发现确实非常简单,虽然这种方式非常不流行。
    kafka在业务中存在的问题
    在kafka中, 每个group有一个petition,每个consumer只能消费这个partition中的内容,并且kafka有默认的心跳机制1分钟,如果一分钟内没有动静,则视为某个consumer死掉了,或者某个consumer没有拉取数据也会视为死掉了。没有consumer中没有commit的数据会被视为没有消费掉,此时Kafka会将这些数据rebalance后重新分配给其他consumer去消费。之所以没有commit是因为某个consumer的处理时间太长了。这种情况同样可能传递到新的consumer上面,也就是造成问题扩散。

CDN

CDN是将源站内容分发至最接近用户的节点,使用户可就近取得所需内容,提高用户访问的响应速度和成功率。解决因分布、带宽、服务器性能带来的访问延迟问题,适用于站点加速、点播、直播等场景。
mq
优点:解耦/异步/削峰
缺点:系统可用性降低,系统复杂性增加。
中小型公司:rabbitmq
大型公司:rocketmq和kafka
如果有日志采集功能首选kafka
如何保证消息队列高可用:多master多slave异步复制,讲解producer和nameserver及broker的通行模式。
如何保证消息不被重复消费:
RabbitMQ是发送一个ACK确认消息,RocketMQ是返回一个CONSUME_SUCCESS成功标志,kafka实际上有个offset的概念,就是每一个消息都有一个offset,kafka消费过消息后,需要提交offset,让消息队列知道自己已经消费过了。

你可能感兴趣的:(Java)