4.Kafka消费过程

四、Kafka消费过程分析

1.消费方式

consumer采用pull(拉)模式从broker中读取数据。
pull模式不足之处是,如果kafka没有数据,消费者可能会陷入循环中,一直返回空数据。
针对这一点,Kafka的消费者在消费数据时会传入一个时长参数timeout,如果当前没有数据可供消费,consumer会等待一段时间之后再返回,这段时长即为timeout。

2.Kafka Api

kafka提供了两套consumer API:高级Consumer API和低级Consumer API
API类型 优点 缺点
高级API 不需要自行去管理offset,系统通过zookeeper自行管理。
不需要管理分区、副本等情况,系统自动管理。
消费者断线会自动根据上一次记录在zookeeper中的offset去接着获取数据
(默认设置1分钟更新一下zookeeper中存的offset)
不能自行控制offset(对于某些特殊需求来说)
不能细化控制如分区、副本、zk等
低级API 能够让开发者自己控制offset,想从哪里读取就从哪里读取。
自行控制连接分区,对分区自定义进行负载均衡
对zookeeper的依赖性降低
(offset不一定非要靠zk存储,比如存在文件或者内存中)
太过复杂,要自行控制offset,连接哪个分区,找到分区leader。

3.消费者组

[图片上传失败...(image-bcf9f1-1575963824448)]

  1. 消费者是以consumer group消费者组的方式工作,由一个或者多个消费者组成一个组,共同消费一个topic。
  2. 每个分区在同一时间只能由group中的一个消费者读取,但是多个group可以同时消费这个partition。在图中,有一个由三个消费者组成的group,有一个消费者读取主题中的两个分区,另外两个分别读取一个分区。某个消费者读取某个分区,也可以叫做某个消费者是某个分区的拥有者。
  3. 在这种情况下,消费者可以通过水平扩展的方式同时读取大量的消息。
  4. 另外,如果一个消费者失败了,那么其他的group成员会自动负载均衡读取之前失败的消费者读取的分区。

4.分区分配策略

Kafka有两种分配策略,一是RoundRobin,一是Range。
Range 范围分区(默认的)

按照每个Topic分区

假如我们有2个主题(T1和T2),分别有10个分区
消费者线程:C1-0, C2-0, C2-1

C1-0 将消费 T1主题的 0, 1, 2, 3 分区以及 T2主题的 0, 1, 2, 3分区
C2-0 将消费 T1主题的 4, 5, 6 分区以及 T2主题的 4, 5, 6分区
C2-1 将消费 T1主题的 7, 8, 9 分区以及 T2主题的 7, 8, 9分区

C1-0 消费者线程比其他消费者线程多消费了2个分区,这就是Range strategy的一个很明显的弊端
RoundRobin(轮询分区)

所有Topic混合分区

使用RoundRobin策略有两个前提条件必须满足:
同一个Consumer Group里面的所有消费者的num.streams必须相等;
每个消费者订阅的主题必须相同;
假如我们有2个主题(T1和T2),分别有10个分区
消费者线程:C1-0, C2-0, C2-1

C1-0 将消费 T1主题的 0, 3, 6, 9 分区以及 T2主题的 2, 5, 8分区
C2-0 将消费 T1主题的 1, 4, 7 分区以及 T2主题的 0, 3, 6, 9分区
C2-1 将消费 T1主题的 2, 5, 8 分区以及 T2主题的 1, 4, 7分区

消息发送流程

[图片上传失败...(image-33ccd3-1575963824448)]

Kafka的Producer发送消息采用的是异步发送的方式。在消息发送的过程中,涉及到了两个线程——main线程和Sender线程,以及一个线程共享变量——RecordAccumulator。main线程将消息发送给RecordAccumulator,Sender线程不断从RecordAccumulator中拉取消息发送到Kafka broker。

相关参数:
batch.size:只有数据积累到batch.size之后,sender才会发送数据。
linger.ms:如果数据迟迟未达到batch.size,sender等待linger.time之后就会发送数据。

你可能感兴趣的:(4.Kafka消费过程)