Kafka Consumer1
本文的代码基于kafka的0.10.1
的版本。
重新设计的原因
0.9以前的consumer是通过zookeeper来进行状态管理里的。
- 羊群效应
- 任何Broker或者Consumer的增减都会触发所有的Consumer的Rebalance
- Split brain(大脑分裂)
- 每个Consumer分别单独通过Zookeeper判断哪些Broker和Consumer 宕机了,那么不同Consumer在同一时刻从Zookeeper“看”到的View就可能不一样,这是由Zookeeper的特性决定的,这就会造成不正确的Reblance尝试。
- 调整结果不可控
- 所有的Consumer都并不知道其它Consumer的Rebalance是否成功,这可能会导致Kafka工作在一个不正确的状态。
实现目标
在0.9, kafka 重新设计了 consumer,主要有以下几个目的:
- 更轻便的客户端
- 部分用户希望开发和使用non-java的客户端。现阶段使用non-java发SimpleConsumer比较方便,但想开发High Level Consumer并不容易。因为High Level Consumer需要实现一些复杂但必不可少的失败探测和Rebalance。如果能将消费者客户端更精简,使依赖最小化,将会极大的方便non- java用户实现自己的Consumer。
- 一个集中的协调者
- 如上文所述,当前版本的High Level Consumer存在Herd Effect和Split Brain的问题。如果将失败探测和Rebalance的逻辑放到一个高可用的中心Coordinator,那么这两个问题即可解决。同时还可大大减少 Zookeeper的负载,有利于Kafka Broker的Scale Out。
- 允许手动分配partition
- 有些系统希望将 partition 和 consumer 进行一一对应。
- 在一些高级的消费者中,他们希望停止自动的 rebalance。
- 这个实现依赖于集中的协调者。
- 允许手动管理 offset
- 一些系统希望以特定的时间间隔在自定义的数据库中管理Offset。这就要求Consumer能获取到每条消息的metadata,例如 Topic,Partition,Offset,同时还需要在Consumer启动时得到每个Partition的Offset。实现这些,需要提供新的 Consumer API。同时有个问题不得不考虑,即是否允许Consumer手工管理部分Topic的Offset,而让Kafka自动通过Zookeeper管理其它 Topic的Offset。一个可能的选项是让每个Consumer只能选取1种Offset管理机制,这可极大的简化Consumer API的设计和实现。
- 允许用户指定 callback 和 rebalance
- 一些应用可能会在内存中为每个Partition维护一些状态,Rebalance时,它们可能需要将该状态持久化。因此该需求希望支持用户实现并指定一些可插拔的并在Rebalance时触发的回调。如果用户使用手动的Offset管理,那该需求可方便得由用户实现,而如果用户希望使用Kafka提供的自动Offset管理,则需要Kafka提供该回调机制
- 非阻塞的消费API
- 该需求源于那些实现高层流处理操作,如filter by, group by, join等,的系统。现阶段的阻塞式Consumer几乎不可能实现Join操作。
Partition分配
当多个consumer 去消费topic的消息时,首先面临的问题就是哪个consuemr应该消费那些topicAndPartition。可以调用assign
手动分配partition。如果需要手动分配,Kafka提供了两种自动分配 的方式,分别为Range
和roundrobin
。
Range
Range策略是对每个主题而言的,首先对同一个主题里面的分区按照序号进行排序,并对消费者按照字母顺序进行排序。在我们的例子里面,排完序的分区将会是0, 1, 2, 3, 4, 5, 6, 7, 8, 9;消费者线程排完序将会是C1-0, C2-0, C2-1。然后将partitions的个数除于消费者线程的总数来决定每个消费者线程消费几个分区。如果除不尽,那么前面几个消费者线程将会多消费一个分区。在我们的例子里面,我们有10个分区,3个消费者线程, 10 / 3 = 3,而且除不尽,那么消费者线程 C1-0 将会多消费一个分区,所以最后分区分配的结果看起来是这样的:
- C1-0 将消费 0, 1, 2, 3 分区
- C2-0 将消费 4, 5, 6 分区
- C2-1 将消费 7, 8, 9 分区
假如我们有11个分区,那么最后分区分配的结果看起来是这样的:
- C1-0 将消费 0, 1, 2, 3 分区
- C2-0 将消费 4, 5, 6, 7 分区
- C2-1 将消费 8, 9, 10 分区
假如我们有2个主题(T1和T2),分别有10个分区,那么最后分区分配的结果看起来是这样的:
- 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 strategy
RoundRobin 策略会将所有的topicAndPartition 和 消费者进行排序。然后循环遍历每个消费者,依次分配tp。
举例两个消费者C1 和 C2, 两个 topic , t0 和 t1, 每个 topic都有3个partition,这样下来总共有t0p0, t0p1, t0p2, t1p0, t1p1, and t1p2。而最终分配的结果是:
- C0 将消费 t0p0, t0p2, t1p1 这三个分区
- C1 将消费t0p1, t1p0, t1p2 这三个分区
如果有的消费者没有订阅其中的topic, 轮训策略会使得topic分配不均匀。
有的时候效果还不如 range assigment。
ConsumerCoordinator
当集群或者消费组出现变化的时候,就会执行partition的分配,我们称这种情况为 reblance。下面几种情况都会触发reblance:
- 新的consumer加入了。
- consumer 挂了。
- consumer 执行了 unsubscribe,离开这个消费组。
- 集群中的coordinator挂了,选举了一个新的。
- topic 增加了 partition。
这些情况都是由 ConsumerCoordinator 进行处理。Coordinator通过一个特定的 broker 对 单个 消费组(consumer group) 进行管理。 Coordinator 主要负责下面几件事情:
- Group Registration : 消费组里面的每个成员会通过自己的 metadata 向 coordinator 进行注册。
- Group/Leader Selection: Coordinator 会从消费组里面的选取一个成员作为一个leader。这个leader 会进行partition的分配,并将分配结果提交给 coordinator。
- State Assignment: Coordinator 会收集消费组里面每个成员的 metadata 信息,然后为它们分配不同的状态。
- Group Stabilization: 消费组里面的每个成员会通过coordinator接收到 leader 设计的分配状态,并开始处理数据。
图1 ConsumerCoordinator 状态图 ConsumerCoordinator
图1中,consumer 首先查找服务器的 coordinator, 然后通过ensureActiveGroup
成功加入消费组里面,并启动heartBeat 线程,当heartBeat线程的通信返回错误后,重新进行上述操作。当然也可能该consumer离开了消费组,这时候其它的consumer会重复上述操作。
这个里面最重要的应该就是ensureActiveGroup
这个动作,它主要负责和服务器的Coordinator node 进行交互,并根据返回的结果做相应的处理。
- 寻找服务器的coordinator。
- 启动HeartBeat线程。
- 将consumer加入group。
- 发送JoinGroupRequest 。
- 调用JoinGroupResponseHandler 处理 response。
- 如果结果成功了,查看返回结果中是不是指定这个consumer 作为leader。如果是leader,那就执行partition分配策略,如果不是,就说明是follower,不执行分配策略。
然后leader 和 follower 都发送SyncGroupRequest给coordinator,不同的是leader的参数里包含了分配策略。 - 如果失败了,根据不同的情况进行处理。
- 如果结果成功了,查看返回结果中是不是指定这个consumer 作为leader。如果是leader,那就执行partition分配策略,如果不是,就说明是follower,不执行分配策略。
- 处理 SyncGroupResponse,从其中获取consumer 消费的topicAndPartition,并触发 ConsumerRebalanceListener。
图2 展示了ensureActiveGroup
的具体行为。
参考:
[1] Kafka设计解析(四):Kafka Consumer解析
[2] Kafka分区分配策略(Partition Assignment Strategy)
[3] Kafka源码深度解析-序列6 -Consumer -消费策略分析
[4] Kafka源码深度解析-序列7 -Consumer -coordinator协议与heartbeat实现原理
Kafka Consumer1的更多相关文章
- Kafka设计解析(四)- Kafka Consumer设计解析
本文转发自Jason’s Blog,原文链接 http://www.jasongj.com/2015/08/09/KafkaColumn4 摘要 本文主要介绍了Kafka High Level Con ...
- Kafka设计解析(一)- Kafka背景及架构介绍
本文转发自Jason’s Blog,原文链接 http://www.jasongj.com/2015/01/02/Kafka深度解析 背景介绍 Kafka简介 Kafka是一种分布式的,基于发布/订阅 ...
- ELK+Kafka集群日志分析系统
ELK+Kafka集群分析系统部署 因为是自己本地写好的word文档复制进来的.格式有些出入还望体谅.如有错误请回复.谢谢! 一. 系统介绍 2 二. 版本说明 3 三. 服务部署 3 1) JDK部 ...
- Kafka深度解析
本文转发自Jason’s Blog,原文链接 http://www.jasongj.com/2015/01/02/Kafka深度解析 背景介绍 Kafka简介 Kafka是一种分布式的,基于发布/订阅 ...
- Kafka深度解析,众人推荐,精彩好文!
作者: Jason Guo 背景介绍 Kafka简介 Kafka是一种分布式的,基于发布/订阅的消息系统.主要设计目标如下: 以时间复杂度为O(1)的方式提供消息持久化能力,并保证即使对TB级以上数据 ...
- kafka设计原理介绍
背景介绍 Kafka简介 Kafka是一种分布式的,基于发布/订阅的消息系统.主要设计目标如下: 以时间复杂度为O(1)的方式提供消息持久化能力,即使对TB级以上数据也能保证常数时间的访问性能 高吞吐 ...
- kafka基本原理学习
下载安装地址:http://kafka.apache.org/downloads.html 原文链接:http://www.jasongj.com/2015/01/02/Kafka深度解析 Kafk ...
- kafka概念
一.结构与概念解释 1.基础概念 topics: kafka通过topics维护各类信息. producer:发布消息到Kafka topic的进程. consumer:订阅kafka topic进程 ...
- Kafka入门学习随记(二)
====Kafka消费者模型 参考博客:http://www.tuicool.com/articles/fI7J3m --分区消费模型 分区消费架构图 图中kafka集群有两台服务器(Server), ...
随机推荐
- bfs初学
BFS: ** 当知道初始和目标状态的,用双向BFS: 无权图最好用BFS 不用重复如队** 实现框架: 抄来的(来源:https://www.luogu.org/blog/stephen2333/s ...
- HTML5学习笔记(三):标识文本的语义元素
1.<time>元素:标注日期和时间 日期格式:YYYY-MM-DD,如2016-04-13: 时间格式(24小时制):HH-MM,如15:31: 最后,组合以上规则就可以制定具体的日期和 ...
- ROS-turtlesim
前言:turtlesim是ros自带的一个功能包,应该是用于基础教学的功能包,帮助新手入门的一个实例,包括:节点,主题,服务以及参数的应用.通过学习使用turtlesim功能包可以了解ros的一些基础 ...
- T7316 yyy的最大公约数(者)
题目背景 全场基本暴力 题目描述 输入输出格式 输入格式: 如图 输出格式: 如图 输入输出样例 输入样例#1: 如图 输出样例#1: 如图 说明 如图 这题用到了容斥原理和线性筛的一些东西, 表示没 ...
- jQuery应用实例3:鼠标经过显示离开隐藏
效果: 代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...
- ZBrush中Flatten展平笔刷介绍
本文我们来介绍ZBrush®中的Flatten展平笔刷,Flatten笔刷能增加粗糙的平面在模型表面,利用它能够制作出完全的平面. Flatten展平笔刷 Flatten(展平):Flatten笔刷可 ...
- 浏览器渲染HTML页面步骤
渲染步骤:浏览器渲染页面时,表示网站资源已经请求成功(要了解查看:浏览器向服务器请求资源过程) 解析HTML以构建dom树--->构建render树--->布局render树---> ...
- 深度学习之入门Pytorch(1)------基础
目录: Pytorch数据类型:Tensor与Storage 创建张量 tensor与numpy数组之间的转换 索引.连接.切片等 Tensor操作[add,数学运算,转置等] GPU加速 自动求导: ...
- [置顶]
使用 maven 插件 maven-shade-plugin 对可执行 java 工程及其全部依赖 jar 进行打包
作者:chenzhou123520 出处:http://chenzhou123520.iteye.com/blog/1706242 使用 maven 插件 maven-shade-plugin 对 j ...
- Extjs获取input值的几种方法
记录一下: ExtJs获取文本框中值的几种方式 EXTHTML 1.Html文本框 如: 获取值的方式为: var tValue = Ext.getDom('test').value; 或者 var ...