Kafka 0.8 Consumer设计解析
摘要
本文主要介绍了Kafka High Level Consumer,Consumer Group,Consumer Rebalance,Low Level Consumer实现的语义,以及适用场景。以及未来版本中对High Level Consumer的重新设计–使用Consumer Coordinator解决Split Brain和Herd等问题。
1.High Level Consumer
很多时候,客户程序只是希望从Kafka读取数据,不太关心消息offset的处理。同时也希望提供一些语义,例如同一条消息只被某一个Consumer消费(单播)或被所有Consumer消费(广播)。因此,Kafka Hight Level Consumer提供了一个从Kafka消费数据的高层抽象,从而屏蔽掉其中的细节并提供丰富的语义。
1.1 Consumer Group
High Level Consumer将从某个Partition读取的最后一条消息的offset存于Zookeeper中。这个offset基于Consumer Group来识别的。Consumer Group是整个Kafka集群全局的,而非某个Topic的。每一个High Level Consumer实例都属于一个Consumer Group。
(Kafka从0.8.2版本开始同时支持将offset存于Zookeeper中与将offset存于专用的Kafka Topic:__consumer_offsets中)
Zookeeper中Consumer相关节点如下图所示
为了实现传统Message Queue消息只被消费一次的语义,Kafka保证每条消息在同一个Consumer Group里只会被某一个Consumer消费。与传统Message Queue不同的是,Kafka还允许不同Consumer Group同时消费同一条消息,这一特性可以为消息的多元化处理提供支持。
Kafka的设计理念之一就是同时提供离线处理和实时处理。
1.2 High Level Consumer Rebalance
(本节所讲述Rebalance相关内容均基于Kafka High Level Consumer-0.8版本的)
Rebalance的触发条件,自己复习复习。
Consumer Rebalance的算法如下:
- 将目标Topic下的所有Partirtion排序,存于Pt
- 对某Consumer Group下所有Consumer排序,存于Cg,第i个Consumer记为Ci
N = size(Pt) / size(Cg)
,向上取整- 解除Ci对原来分配的Partition的消费权(i从0开始)
- 将第i∗N到
(i+1)∗N−1
个Partition分配给Ci
最新版(0.8.2.1)Kafka的Consumer Rebalance的控制策略是由每一个Consumer通过在Zookeeper上注册Watch完成的。每个Consumer被创建时会触发Consumer Group的Rebalance,具体启动流程如下:
- High Level Consumer启动时将其ID注册到其Consumer Group下,在Zookeeper上的路径为
/consumers/[consumer group]/ids/[consumer id]
- 在/consumers/[consumer group]/ids上注册Watch
- 在/brokers/ids上注册Watch
- 如果Consumer通过Topic Filter创建消息流,则它会同时在/brokers/topics上也创建Watch
- 强制自己在其Consumer Group内启动Rebalance流程
在这种策略下,每一个Consumer或者Broker的增加或者减少都会触发Consumer Rebalance。因为每个Consumer只负责调整自己所消费的Partition,为了保证整个Consumer Group
的一致性,当一个Consumer触发了Rebalance时,该Consumer Group内的其它所有其它Consumer也应该同时触发Rebalance。
该方式有如下缺陷:
- Herd effect
任何Broker或者Consumer的增减都会触发所有的Consumer的Rebalance - Split Brain
每个Consumer分别单独通过Zookeeper判断哪些Broker和Consumer 宕机了,那么不同Consumer在同一时刻从Zookeeper“看”到的View就可能不一样,这是由Zookeeper的特性决定的,这就会造成不正确的Reblance尝试。 - 调整结果不可控
所有的Consumer都并不知道其它Consumer的Rebalance是否成功,这可能会导致Kafka工作在一个不正确的状态。
1.3 Coordinator
当前版本的High Level Consumer存在Herd Effect和Split Brain的问题。如果将失败探测和Rebalance的逻辑放到一个高可用的中心Coordinator,那么这两个问题即可解决。同时还可大大减少Zookeeper的负载,有利于Kafka Broker的Scale Out。
每一个Broker将被选举为某些Consumer Group的Coordinator。某个Cosnumer Group的Coordinator负责在该Consumer Group的成员变化或者所订阅的Topic的Partititon变化时协调Rebalance操作。
Consumer状态机
- Down:Consumer停止工作
- Start up & discover coordinator:Consumer检测其所在Group的Coordinator。一旦它检测到Coordinator,即向其发送JoinGroupRequest。
- Part of a group:该状态下,Consumer已经是该Group的成员,并周期性发送HeartbeatRequest。如HeartbeatResponse包含IllegalGeneration错误码,则转换到Stopped Consumption状态。若连接丢失,HeartbeatResponse包含NotCoordinatorForGroup错误码,则转换到Rediscover coordinator状态。
- Rediscover coordinator:该状态下,Consumer不停止消费而是尝试通过发送ConsumerMetadataRequest来探测新的Coordinator,并且等待直到获得无错误码的响应。
- Stopped consumption:该状态下,Consumer停止消费并提交offset,直到它再次加入Group。
3.Low Level Consumer
使用Low Level Consumer (Simple Consumer)的主要原因是,用户希望比Consumer Group更好的控制数据的消费。比如:
- 同一条消息读多次
- 只读取某个Topic的部分Partition
- 管理事务,从而确保每条消息被处理一次,且仅被处理一次
与Consumer Group相比,Low Level Consumer要求用户做大量的额外工作。
- 必须在应用程序中跟踪offset,从而确定下一条应该消费哪条消息
- 应用程序需要通过程序获知每个Partition的Leader是谁
- 必须处理Leader的变化
使用Low Level Consumer的一般流程如下
- 查找到一个“活着”的Broker,并且找出每个Partition的Leader
- 找出每个Partition的Follower
- 定义好请求,该请求应该能描述应用程序需要哪些数据
- Fetch数据
- 识别Leader的变化,并对之作出必要的响应
如果kafka partition 的leader发生了切换,是如何影响正在消费的consumer的?
- consumer监听了topicPartition的更新,所以可以正常的切换到新的leader。有offset的存在,high water的存在,从上次的 offset 开始读,那就不会有不一致的问题。
- 所以在一般正常情况下,当 kafka 发生 failover 的时候,consumer 是不会读到不一致数据的。特例的情况就是,当前 leader 是唯一有效的 replica,其他replica都处在完全不同步状态,这样发生 leader 切换,一定是会丢数据的,并会发生 offset 不一致。
Kafka 0.8 Consumer设计解析的更多相关文章
- Kafka设计解析(四)Kafka Consumer设计解析
转载自 技术世界,原文链接 Kafka设计解析(四)- Kafka Consumer设计解析 目录 一.High Level Consumer 1. Consumer Group 2. High Le ...
- Kafka设计解析(十六)Kafka 0.11消息设计
转载自 huxihx,原文链接 [原创]Kafka 0.11消息设计 目录 一.Kafka消息层次设计 1. v1格式 2. v2格式 二.v1消息格式 三.v2消息格式 四.测试对比 Kafka 0 ...
- Kafka设计解析(四)- Kafka Consumer设计解析
本文转发自Jason’s Blog,原文链接 http://www.jasongj.com/2015/08/09/KafkaColumn4 摘要 本文主要介绍了Kafka High Level Con ...
- Kafka学习笔记之Kafka Consumer设计解析
0x00 摘要 本文主要介绍了Kafka High Level Consumer,Consumer Group,Consumer Rebalance,Low Level Consumer实现的语义,以 ...
- 【原创】Kafka 0.11消息设计
Kafka 0.11版本增加了很多新功能,包括支持事务.精确一次处理语义和幂等producer等,而实现这些新功能的前提就是要提供支持这些功能的新版本消息格式,同时也要维护与老版本的兼容性.本文将详细 ...
- Kafka 0.8 配置参数解析
http://kafka.apache.org/documentation.html#configuration Broker Configs 4个必填参数, broker.id Each bro ...
- Kafka 0.8 Consumer处理逻辑
0.前言 客户端用法: kafka.javaapi.consumer.ConsumerConnector consumer = kafka.consumer.Consumer.createJavaCo ...
- Kafka 0.8 Consumer Rebalance
1 Rebalance时机 0.10kafka的rebalance条件 条件1:有新的consumer加入 条件2:旧的consumer挂了 条件3:coordinator挂了,集群选举出新的coor ...
- Kafka 0.8 Controller设计机制和状态变化
在kafka集群中,其中一个broker server作为中央控制器Control,负责管理分区和副本状态并执行管理着这些分区的重新分配. 下面说明如何通过中央控制器操作分区和副本的状态. 名词解释 ...
随机推荐
- Django高并发负载均衡
1 什么是负载均衡? 当一台服务器的性能达到极限时,我们可以使用服务器集群来提高网站的整体性能.那么,在服务器集群中,需要有一台服务器充当调度者的角色,用户的所有请求都会首先由它接收,调度者再根据每台 ...
- MFC学习笔记(一): 不用MFC向导如何新建一个MFC程序
使用Visual Studio新建一个空项目,项目命名为HelloMFC,完成后,打开项目属性页面,将配置属性选项卡中的常规项打开,将其中的MFC的使用属性栏改为:在静态库中使用MFC或者在共享DLL ...
- 做游戏的小伙伴们注意了,DDoS还可以这样破!
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯游戏云发表于云+社区专栏 作者:腾讯DDoS安全专家.腾讯云游戏安全专家haroldchen 摘要:在游戏出海的过程中,DDoS攻 ...
- 06-docker组件如何协作
容器启动过程如下: Docker 客户端执行 docker run 命令. Docker daemon 发现本地没有 httpd 镜像. daemon 从 Docker Hub 下载镜像. 下载完成, ...
- PAT-1010 Radix
1010 Radix (25 分) Given a pair of positive integers, for example, 6 and 110, can this equation 6 = 1 ...
- Spring学习总结之面向切面(AOP)
AOP术语 通知(advice):定义切面是什么以及什么时候使用 连接点(join point):应用在执行过程中能够插入切面的点 切点(pointcut):切点的定义会匹配通知所要织入的一个或多个连 ...
- 团队作业4--第一次项目冲刺(Alpha版本)日志集合处
第一次 http://www.cnblogs.com/p-12/p/7861231.html 第二次 http://www.cnblogs.com/p-12/p/7861835.html 第三次 ht ...
- 给VMware下的Linux扩展磁盘空间(以CentOS6.3为例)
参照这篇文章进行的,但是和作者的步骤有些不一样. #查看挂载点:df -h#显示: 文件系统 容量 已用 可用 已用%% 挂载点/dev/mapper/vg_dc01-lv_root 47G 12G ...
- [windows]转帖 windows 版本的含义
1.N是None的意思,由于欧洲反垄断法不让系统捆绑浏览器ie和播放器.LTSB全称为Long Term Support Branch,意思为长期支持分支,是给Windows 10企业用户的一个更新选 ...
- 默认css修改
input-------------------------------------------------- .input-item input{ width: 100%; height: 60px ...