一:消费方式


consumer 采用 pull (拉)模式从 broker 中读取数据。


push (推)模式很难适应消费速率不同的消费者,因为消息发送速率是由 broker 决定的。



        它的目标是尽可能以最快速度传递消息,但是这样很容易造成 consumer 来不及处理消息, 



典型的表现就是拒绝服务以及网络拥塞。而 pull 模式则可以根据 consumer 的消费能力以适



当的速率消费消息。



        pull 模式不足之处是,如果 kafka 没有数据,消费者可能会陷入循环中,一直返回空数



据。针对这一点,Kafka 的消费者在消费数据时会传入一个时长参数 timeout,如果当前没有



数据可供消费,consumer 会等待一段时间之后再返回,这段时长即为 timeout。




二:分区分配策略



        同一个消费者组里面的消费者不能同时消费同一个主题的同一个分区。一个 consumer group 中有多个 consumer,一个 topic 有多个 partition,所以必然会涉及 到 partition 的分配问题,即确定那个 partition 由哪个 consumer 来消费。



Kafka 有两种分配策略,一是 RoundRobin,一是 Range。




RoundRobin:




        RoundRobinAssignor策略的原理是将消费组内所有消费者以及消费者所订阅的所有topic的partition按照字典序排序,然后通过轮询方式逐个将分区以此分配给每个消费者。RoundRobinAssignor策略对应的partition.assignment.strategy参数值org.apache.kafka.clients.consumer.RoundRobinAssignor。
所以这里假设前面提到的2个消费者的num.streams = 2。RoundRobin策略的工作原理:将所有主题的分区组成 TopicAndPartition 列表,然后对 TopicAndPartition 列表按照 hashCode 进行排序



最后按照round-robin风格将分区分别分配给不同的消费者线程。



在我们的例子里面,加入按照 hashCode 排序完的topic-partitions组依次为T1-5, T1-3, T1-0, T1-8, T1-2, T1-1, T1-4, T1-7, T1-6, T1-9,我们的消费者线程排序为C1-0, C1-1, C2-0, C2-1,最后分区分配的结果为:
 



C1-0 将消费 T1-5, T1-2, T1-6 分区;

C1-1 将消费 T1-3, T1-1, T1-9 分区;

C2-0 将消费 T1-0, T1-4 分区;

C2-1 将消费 T1-8, T1-7 分区;


 Range(默认策略)

        Range是对每个Topic而言的(即一个Topic一个Topic分),首先对同一个Topic里面的分区按照序号进行排序,并对消费者按照字母顺序进行排序。然后用Partitions分区的个数除以消费者线程的总数来决定每个消费者线程消费几个分区。如果除不尽,那么前面几个消费者线程将会多消费一个分区。

假设n=分区数/消费者数量,m=分区数%消费者数量,那么前m个消费者每个分配n+1个分区,后面的(消费者数量-m)个消费者每个分配n个分区。

假如有10个分区,3个消费者线程,把分区按照序号排列0,1,2,3,4,5,6,7,8,9;消费者线程为C1-0,C2-0,C2-1,那么用partition数除以消费者线程的总数来决定每个消费者线程消费几个partition,如果除不尽,前面几个消费者将会多消费一个分区。在我们的例子里面,我们有10个分区,3个消费者线程,10/3 = 3,而且除除不尽,那么消费者线程C1-0将会多消费一个分区,所以最后分区分配的结果看起来是这样的: 

C1-0:0,1,2,3

C2-0:4,5,6

C2-1:7,8,9

三:offset的存储


         由于 consumer 在消费过程中可能会出现断电宕机等故障,consumer 恢复后,需要从故


障前的位置的继续消费,所以 consumer 需要实时记录自己消费到了哪个 offset,以便故障恢


复后继续消费。


        offset是按消费者组保存,即消费者组+topic+partition来确定唯一的offset,offset存储在两个地方:本地和zookeeper



查看zookeeper里面kafka的信息:




kafka消费冷却 kafka消费模式_kafka

 



brokerid: kafka配置的id编号,这个kafka是主节点负责和zookeeper交互数据


kafka消费冷却 kafka消费模式_zookeeper_02


查看kafka集群编号,在zookeeper里面注册的kafka就是一个集群


 

kafka消费冷却 kafka消费模式_kafka_03

查看kafka集群主题

kafka消费冷却 kafka消费模式_kafka消费冷却_04

 

查看消费者组,没有指定则随机分配一个消费者组

 

kafka消费冷却 kafka消费模式_zookeeper_05

 消费者组当前消费的topic

kafka消费冷却 kafka消费模式_kafka消费冷却_06

first的分区 

kafka消费冷却 kafka消费模式_zookeeper_07

offset的信息

kafka消费冷却 kafka消费模式_kafka消费冷却_08

 

本地:


Kafka 0.9 版本之前, consumer 默认将 offset 保存在 Zookeeper 中,从 0.9 版本开始,


consumer 默认将 offset 保存在 Kafka 一个内置的 topic 中,该 topic 为 __consumer_offsets



四:高效读写了解(涉及物理层)


1)顺序写磁盘


        Kafka 的 producer 生产数据,要写入到 log 文件中,写的过程是一直追加到文件末端,


为顺序写。官网有数据表明,同样的磁盘,顺序写能到 600M/s ,而随机写只有 100K/s 。这


与磁盘的机械机构有关,顺序写之所以快,是因为其省去了大量磁头寻址的时间


2 )零复制技术



kafka消费冷却 kafka消费模式_kafka_09


 五:Zookeeper 在 Kafka 中的作用


        Kafka 集群中有一个 broker 会被选举为 Controller(kafka抢占资源快的就是Controller),负责 管理集群 broker 的上下线 ,所有 topic 的 分区副本分配 和 leader 选举 等工作。 Controller 的管理工作都是依赖于 Zookeeper 的



        选举产生leader (isr节点抢占创建Emphemeral节点 选举产生)       

kafka消费冷却 kafka消费模式_kafka_10