来自:z小赵

前言

经过前几篇文章的介绍,大致了解了生产者背后的运行原理。消息有生产就得有人去消费,今天我们就来介绍下消费端消费消息背后发生的那点事儿。

文章概览

  1. 消费者与消费组的“父子关系”。

  2. Repartition 触发时机。

  3. 消费者与 ZK 的关系。

  4. 消费端工作流程。

  5. 消费者的三种消费情况。

消费者与消费组的“父子关系”

消费者消费组关系图

Kafka 消费端确保一个 Partition 在一个消费者组内只能被一个消费者消费。这句话改怎么理解呢?

  1. 在同一个消费者组内,一个 Partition 只能被一个消费者消费。

  2. 在同一个消费者组内,所有消费者组合起来必定可以消费一个 Topic 下的所有 Partition。

  3. 在同一个消费组内,一个消费者可以消费多个 Partition 的信息。

  4. 在不同消费者组内,同一个分区可以被多个消费者消费。

  5. 每个消费者组一定会完整消费一个 Topic 下的所有 Partition。

消费组存在的意义

了解了消费者与消费组的关系后,有朋友会比较疑惑消费者组有啥实际存在的意义呢?或者说消费组的作用是什么?

作者对消费组的作用归结了如下两点。

  1. 在实际生产中,对于同一个 Topic,可能有 A、B、C 等 N 个消费方想要消费。比如一份用户点击日志,A 消费方想用来做一个用户近 N 天点击过哪些商品;B 消费方想用来做一个用户近 N 天点击过前 TopN 个相似的商品;C 消费方想用来做一个根据用户点击过的商品推荐相关周边的商品需求。对于多应用场景,就可以使用消费组来隔离不同的业务使用场景,从而达到一个 Topic 可以被多个消费组重复消费的目的。

  2. 消费组与 Partition 的消费进度绑定。当有新的消费者加入或者有消费者从消费组退出时,会触发消费组的 Repartition 操作(后面会详细介绍 Repartition);在 Repartition 前,Partition1 被消费组的消费者 A 进行消费,Repartition 后,Partition1 消费组的消费者 B 进行消费,为了避免消息被重复消费,需要从消费组记录的 Partition 消费进度读取当前消费到的位置(即 OffSet 位置),然后在继续消费,从而达到消费者的平滑迁移,同时也提高了系统的可用性。

Repartition 触发时机

使用过 Kafka 消费者客户端的同学肯定知道,消费者组内偶尔会触发 Repartition 操作,所谓 Repartition 即 Partition 在某些情况下重新被分配给参与消费的消费者。基本可以分为如下几种情况。

  1. 消费组内某消费者宕机,触发 Repartition 操作,如下图所示。

消费者宕机情况
  1. 消费组内新增消费者,触发 Repartition 操作,如下图所示。一般这种情况是为了提高消费端的消费能力,从而加快消费进度。

新增消费者情况
  1. Topic 下的 Partition 增多,触发 Repartition 操作,如下图所示。一般这种调整 Partition 个数的情况也是为了提高消费端消费速度的,因为当消费者个数大于等于 Partition 个数时,在增加消费者个数是没有用的(原因是:在一个消费组内,消费者:Partition = 1:N,当 N 小于 1 时,相当于消费者过剩了),所以一方面增加 Partition 个数同时增加消费者个数可以提高消费端的消费速度。

新增Partition个数情况

消费者与 ZK 的关系

众所周知,ZK 不仅保存了消费者消费 partition 的进度,同时也保存了消费组的成员列表、partition 的所有者。消费者想要消费 Partition,需要从 ZK 中获取该消费者对应的分区信息及当前分区对应的消费进度,即 OffSert 信息。那么 Partition 应该由那个消费者进行消费,决定因素有哪些呢?从之前的图中不难得出,两个重要因素分别是:消费组中存活的消费者列表和 Topic 对应的 Partition 列表。通过这两个因素结合 Partition 分配算法,即可得出消费者与 Partition 的对应关系,然后将信息存储到 ZK 中。Kafka 有高级 API 和低级 API,如果不需要操作 OffSet 偏移量的提交,可通过高级 API 直接使用,从而降低使用者的难度。对于一些比较特殊的使用场景,比如想要消费特定 Partition 的信息,Kafka 也提供了低级 API 可进行手动操作。

消费端工作流程

在介绍消费端工作流程前,先来熟悉一下用到的一些组件。

  • KakfaConsumer:消费端,用于启动消费者进程来消费消息。

  • ConsumerConfig:消费端配置管理,用于给消费端配置相关参数,比如指定 Kafka 集群,设置自动提交和自动提交时间间隔等等参数,都由其来管理。

  • ConsumerConnector:消费者连接器,通过消费者连接器可以获得 Kafka 消息流,然后通过消息流就能获得消息从而使得客户端开始消费消息。

以上三者之间的关系可以概括为:消费端使用消费者配置管理创建出了消费者连接器,通过消费者连接器创建队列(这个队列的作用也是为了缓存数据),其中队列中的消息由专门的拉取线程从服务端拉取然后写入,最后由消费者客户端轮询队列中的消息进行消费。具体操作流程如下图所示。

消费端工作流程

我们在从消费者与 ZK 的角度来看看其工作流程是什么样的?

消费端与ZK之间的工作流程

从上图可以看出,首先拉取线程每拉取一次消息,同步更新一次拉取状态,其作用是为了下一次拉取消息时能够拉取到最新产生的消息;拉取线程将拉取到的消息写入到队列中等待消费消费线程去真正读取处理。消费线程以轮询的方式持续读取队列中的消息,只要发现队列中有消息就开始消费,消费完消息后更新消费进度,此处需要注意的是,消费线程不是每次都和 ZK 同步消费进度,而是将消费进度暂时写入本地。这样做的目的是为了减少消费者与 ZK 的频繁同步消息,从而降低 ZK 的压力。

消费者的三种消费情况

消费者从服务端的 Partition 上拉取到消息,消费消息有三种情况,分别如下:

  1. 至少一次。即一条消息至少被消费一次,消息不可能丢失,但是可能会被重复消费。

  2. 至多一次。即一条消息最多可以被消费一次,消息不可能被重复消费,但是消息有可能丢失。

  3. 正好一次。即一条消息正好被消费一次,消息不可能丢失也不可能被重复消费。

1.至少一次

消费者读取消息,先处理消息,在保存消费进度。消费者拉取到消息,先消费消息,然后在保存偏移量,当消费者消费消息后还没来得及保存偏移量,则会造成消息被重复消费。如下图所示:

先消费后保存消费进度

2.至多一次

消费者读取消息,先保存消费进度,在处理消息。消费者拉取到消息,先保存了偏移量,当保存了偏移量后还没消费完消息,消费者挂了,则会造成未消费的消息丢失。如下图所示:

先保存消费进度后消费消息

3.正好一次

正好消费一次的办法可以通过将消费者的消费进度和消息处理结果保存在一起。只要能保证两个操作是一个原子操作,就能达到正好消费一次的目的。通常可以将两个操作保存在一起,比如 HDFS 中。正好消费一次流程如下图所示。

正好消费一次

总结

本文讲解了消费组与消费者之间的关系,及 Repartition 的触发时机,然后讲述了消费端的基本工作流程,最后提出了一条消息被重复消费的几种情况。下篇文章我们来讲讲消息在服务端是怎么存储的,敬请期待。

特别推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下:长按订阅更多精彩▼如有收获,点个在看,诚挚感谢

kafka:一文读懂消费者背后的那点猫腻相关推荐

  1. kafka多个消费者消费一个topic_kafka:一文读懂消费者背后的那点quot;猫腻quot;

    来自:z小赵 前言 经过前几篇文章的介绍,大致了解了生产者背后的运行原理.消息有生产就得有人去消费,今天我们就来介绍下消费端消费消息背后发生的那点事儿. 文章概览 消费者与消费组的"父子关系 ...

  2. 一文读懂AlphaGo背后的强化学习:它的背景知识与贝尔曼方程的原理

    作者 | Joshua Greaves 译者 | 刘畅,林椿眄 本文是强化学习名作--"Reinforcement Learning: an Introduction"一书中最为重 ...

  3. 一文读懂AlphaGo背后的强化学习

    作者 | Joshua Greaves 编译 | 刘畅,林椿眄 本文是强化学习名作--"Reinforcement Learning: an Introduction"一书中最为重 ...

  4. 一文读懂:Kafka(分布式消息队列)的基础概念,教程

    [提前声明] 文章由作者:张耀峰 结合自己生产中的使用经验整理,最终形成简单易懂的文章 写作不易,转载请注明,谢谢! 代码案例地址: ?https://github.com/Mydreamandrea ...

  5. 一文读懂大数据平台——写给大数据开发初学者的话!

     一文读懂大数据平台--写给大数据开发初学者的话! 文|miao君 导读: 第一章:初识Hadoop 第二章:更高效的WordCount 第三章:把别处的数据搞到Hadoop上 第四章:把Hado ...

  6. 腾讯资深架构师干货总结:一文读懂大型分布式系统设计的方方面面

    1.引言 我们常常会听说,某个互联网应用的服务器端系统多么牛逼,比如QQ.微信.淘宝.那么,一个大型互联网应用的服务器端系统,到底牛逼在什么地方?为什么海量的用户访问,会让一个服务器端系统变得更复杂? ...

  7. 即时通讯新手入门:一文读懂什么是Nginx?它能否实现IM的负载均衡?

    本文引用了"蔷薇Nina"的"Nginx 相关介绍(Nginx是什么?能干嘛?)"一文部分内容,感谢作者的无私分享. 1.引言 Nginx(及其衍生产品)是目前 ...

  8. 从实验室走向大众,一文读懂Nanopore测序技术的发展及应用

    关键词/Nanopore测序技术    文/基因慧 随着基因测序技术不断突破,二代测序的发展也将基因检测成本大幅降低.理想的测序方法,是对原始DNA模板进行直接.准确的测序,消除PCR扩增带来的偏差, ...

  9. 一文读懂你该了解的5G知识:现在别买5G手机

    来源: 腾讯科技 2019年是中国全力布局5G的一年:三大运营商纷纷搭建基站,手机厂商发布5G手机,部分城市已经开启了5G测试--在电信日这天,腾讯科技联合知乎推出重磅策划,聚焦和5G相关的小知识,精 ...

最新文章

  1. 线上 4 台机器同一时间全部 OOM,到底发生了什么?
  2. 育果医生CEO马于堃:互联网医疗行业与产品的本质
  3. saltstack批量修改root密码
  4. java excel转word表格_java利用poi生成/读取excel表格、生成word
  5. 模态对话框和非模态对话框区别
  6. 蒙特卡洛模拟预测股票_使用蒙特卡洛模拟来预测极端天气事件
  7. mybatis-plus使用 generator 代码生成器生成实体类支持Swagger2
  8. php做姓名隐藏,PHP只显示姓名首尾字符,隐藏中间字符并用*替换
  9. promise then返回值
  10. Eclipse安装svn插件的几种方式
  11. 【概念学习】联邦学习的三个类别+【论文阅读】异步联邦学习
  12. hget和get redis_redis使用手册-hset,hget 和 hmset,hmget
  13. html分享到微博,h5页面分享到微信、朋友圈、新浪微博、QQ空间、QQ好友组件
  14. mac下安装photoshop
  15. Linux shell脚本执行后出现语法错误: 未预期的文件结尾
  16. 计算机中丢失ubiorbitapi,我的刺客信条出现无法启动此程序,因为计算机中丢失ubiorbitapi_r2_loader.dll,,怎么处理。。...
  17. 恩智浦 i.MX8X BSP 包文件目录结构
  18. 46家公司面试笔试题
  19. Windows下telnet 发送邮件
  20. Android L 64位兼容32 应用程序的认识

热门文章

  1. wtl中显示html,用WTL构建HTML界面应用程序(1)
  2. python中使用socket编程实现图片或者其他文件的传输
  3. c语言aba字母塔,打印字母金字塔,昨晚看到某个帖子的题目
  4. Luogu P5556 圣剑护符(线性基,树链剖分,线段树)
  5. 【分块】#6284. 数列分块入门 8(区间赋值为相同的值,查询区间某值个数)
  6. 【数论】数论基础合集
  7. etc下没有mysql_我在linux下,安装mysql的时候,cp support-files/my-medium.cnf /etc/my.cnf找不到my-medium.cnf...
  8. python 打印执行命令的参数_python之获取命令行参数
  9. php读取西门子plc_简单说一些PLC中模拟量的相关概念
  10. 使用 Blender* 重新拓扑 VR 和游戏素材