摘要

  本文主要介绍了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设计解析的更多相关文章

  1. Kafka设计解析(四)Kafka Consumer设计解析

    转载自 技术世界,原文链接 Kafka设计解析(四)- Kafka Consumer设计解析 目录 一.High Level Consumer 1. Consumer Group 2. High Le ...

  2. Kafka设计解析(十六)Kafka 0.11消息设计

    转载自 huxihx,原文链接 [原创]Kafka 0.11消息设计 目录 一.Kafka消息层次设计 1. v1格式 2. v2格式 二.v1消息格式 三.v2消息格式 四.测试对比 Kafka 0 ...

  3. Kafka设计解析(四)- Kafka Consumer设计解析

    本文转发自Jason’s Blog,原文链接 http://www.jasongj.com/2015/08/09/KafkaColumn4 摘要 本文主要介绍了Kafka High Level Con ...

  4. Kafka学习笔记之Kafka Consumer设计解析

    0x00 摘要 本文主要介绍了Kafka High Level Consumer,Consumer Group,Consumer Rebalance,Low Level Consumer实现的语义,以 ...

  5. 【原创】Kafka 0.11消息设计

    Kafka 0.11版本增加了很多新功能,包括支持事务.精确一次处理语义和幂等producer等,而实现这些新功能的前提就是要提供支持这些功能的新版本消息格式,同时也要维护与老版本的兼容性.本文将详细 ...

  6. Kafka 0.8 配置参数解析

    http://kafka.apache.org/documentation.html#configuration   Broker Configs 4个必填参数, broker.id Each bro ...

  7. Kafka 0.8 Consumer处理逻辑

    0.前言 客户端用法: kafka.javaapi.consumer.ConsumerConnector consumer = kafka.consumer.Consumer.createJavaCo ...

  8. Kafka 0.8 Consumer Rebalance

    1 Rebalance时机 0.10kafka的rebalance条件 条件1:有新的consumer加入 条件2:旧的consumer挂了 条件3:coordinator挂了,集群选举出新的coor ...

  9. Kafka 0.8 Controller设计机制和状态变化

    在kafka集群中,其中一个broker server作为中央控制器Control,负责管理分区和副本状态并执行管理着这些分区的重新分配. 下面说明如何通过中央控制器操作分区和副本的状态. 名词解释 ...

随机推荐

  1. Spark内存管理

    本文基于Spark 1.6.0之后的版本 Spark 1.6.0引入了对堆外内存的管理并对内存管理模型进行了改进,SPARK-11389. 从物理上,分为堆内内存和堆外内存:从逻辑上分为executi ...

  2. Window下mysql环境配置问题整理

    Window下mysql环境配置问题整理 参考如下链接. 无需安装解压版mysql包 创建选项配置 首次启动服务 用mysqld初始化目录 安装后设置和测试 启动服务错误信息 管理员模式打开cmd m ...

  3. Azure 基础:Queue Storage

    Azure Storage 是微软 Azure 云提供的云端存储解决方案,当前支持的存储类型有 Blob.Queue.File 和 Table. 笔者在前文中介绍了 File Storage 的基本用 ...

  4. Docker部署Registry私有镜像库

    拉取镜像 docker pull registry:2.6.2   生成账号密码文件,这里采用htpasswd方式认证 docker run --rm --entrypoint htpasswd re ...

  5. k8s之使用secret获取私有仓库镜像

    一.前言 其实这次实践算不上特别复杂,只是在实践过程中遇到了一些坑,以及填坑的方法是非常值得在以后的学习过程中参考借鉴的 二.知识准备 1.harbor是一个企业级的镜像仓库,它比起docker re ...

  6. Ubuntu环境如何上传项目到GitHub网站?

    http://blog.csdn.net/ajianyingxiaoqinghan/article/details/70544159

  7. Daily Scrumming* 2015.12.12(Day 4)

    一.团队scrum meeting照片 二.今日总结 姓名 WorkItem ID 工作内容 签入链接以及备注说明  江昊 任务1036 进行界面开发,明日准备开发第一个界面,社团展示界面 工作暂未完 ...

  8. HTML5遇到的问题

    一.Uncaught SyntaxError: Unexpected identifier 解决办法: Uncaught SyntaxError: Unexpected identifier这个问题, ...

  9. c语言四则运算

    #include<stdio.h>#define W 5main(){ int a,b,i=0,c,d,r=0; while(i<W) { i++; srand(time()); a ...

  10. express框架结合jade模板引擎使用

    在views文件夹里新建一个jade.jade文件作为模板: html head title 哈哈 body #box ul li 标题1 li 标题2 li 标题3 li 标题4 #aside 在j ...