kafka-消费者-订阅消费消息

发布消息通常有两种模式:

 队列模式(queuing):consumers可以同时从服务端读取消息,每个消息只被其中一个consumer读到

发布-订阅模式(publish-subscribe):消息被广播到所有的consumer中,但这里订阅者是个组而不是单个consumer。

kafka消费消息机制:

 一个消息只能被consumer group 内的一个 consumer 所消费,且 consumer 消费消息时不关注 offset,最后一个 offset 由 zookeeper 保存。

因此:

如果所有的consumer都在一个组中,这就成为了传统的队列模式。

如果所有的consumer都不在不同的组中,这就成为了发布-订阅模式,
举个栗子:
 
说明:
  由两个机器组成的集群拥有4个分区 (P0-P3) 2个consumer组. A组有两个consumerB组有4个

注:

同一组中的consumer可以在不同的程序中,也可以在不同的机器上。

②当consumer正常消费消息时,offset将会"线性"的向前驱动,即消息将依次顺序被消费.但事实上consumer可以使用任意顺序消费消息,它只需要将offset重置为任意值.

 

kafka 提供了两套 consumer API:

The high-level Consumer API:不需要开发人员更多地关注细节(提供了一个消费数据的高层抽象)

The SimpleConsumer API:需要开发人员更多地关注细节

例如:high-level API而言,offset 是存于Zookeeper 中的,无法存于HDFS,而SimpleConsuemr API的 offset 是由自己去维护的,可以将之存于 HDFS 中。

 

high-level Consumer API:

consumer 可以同时实现离线处理和实时处理,只要分成不同的组就可以了;

 

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

 

注: 采用 pull 模式consumer 可自主控制消费消息的速率, 可以自己控制消费方式(批量消费/逐条消费),还可以选择不同的提交方式从而实现不同的传输语义。

 

思考:若采用push 模式,由 broker 控制消息发送速率(目标是尽可能以最快速度传递消息),很难适应消费速率不同的消费者,容易造成 consumer 来不及处理消息,发生拒绝服务以及网络拥塞的现象;

数据处理与 commit 的顺序

 

读完消息先 commit 再处理消息:   消息可能没处理 (At most once模式)
读完消息先处理再 commit:消息绝不会丢,但可能会重复处理  (At least once模式)
更好的做法:让 offset 和操作输入存在同一个地方,但注意:许多输出系统可能不支持两阶段提交
如:consumer 拿到数据后可能把数据放到 HDFS,如果把最新的 offset 和数据本身一起写到 HDFS,那就可以保证数据的输出和 offset 的更新要么都完成,要么都不完成,间接实现 Exactly once。

The SimpleConsumer API 需要自己去管理partition、offset、broker、leader ,要做大量的额外工作:

1. 必须在应用程序中跟踪 offset,从而确定下一条应该消费哪条消息

2. 应用程序需要通过程序获知每个 Partition 的 leader 是谁

3. 需要处理 leader 的变更

 

Consumer rebalance算法:重新分配消费权

当有 consumer 加入或退出、以及 partition 的改变(如 broker 加入或退出)时会触发 rebalance

1. 将目标 topic 下的所有 partirtion 排序,存于PT

2. 对某 consumer group 下所有 consumer 排序,存于 CG,第 i 个consumer 记为 Ci

3. N=size(PT)/size(CG),向上取整

4. 解除 Ci 对原来分配的 partition 的消费权(i从0开始)

5. 将第i*N到(i+1)*N-1个 partition 分配给 Ci

 

posted @ 2017-08-03 17:02  简笔话_Golden  阅读(1672)  评论(0)    收藏  举报