kafka多个消费者消费一个topic_kafka:一文读懂消费者背后的那点"猫腻"

2023-05-16

e6bb83bdb856dfb15c7343a6508bfe39.png

来自:z小赵

前言

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

文章概览

  1. 消费者与消费组的“父子关系”。
  2. Repartition 触发时机。
  3. 消费者与 ZK 的关系。
  4. 消费端工作流程。
  5. 消费者的三种消费情况。

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

eb15abb7d30db788c762149ea0be7b2c.png
消费者消费组关系图

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 操作,如下图所示。
7e276f83216b8f5ff824ba4dbdedbb4b.png
消费者宕机情况
  1. 消费组内新增消费者,触发 Repartition 操作,如下图所示。一般这种情况是为了提高消费端的消费能力,从而加快消费进度。
f098b5a7f4c191c195d3c6742628d8a7.png
新增消费者情况
  1. Topic 下的 Partition 增多,触发 Repartition 操作,如下图所示。一般这种调整 Partition 个数的情况也是为了提高消费端消费速度的,因为当消费者个数大于等于 Partition 个数时,在增加消费者个数是没有用的(原因是:在一个消费组内,消费者:Partition = 1:N,当 N 小于 1 时,相当于消费者过剩了),所以一方面增加 Partition 个数同时增加消费者个数可以提高消费端的消费速度。
0cbe0dfe599a2eaa75806d9fc4633839.png
新增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 消息流,然后通过消息流就能获得消息从而使得客户端开始消费消息。

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

f2bd398d592f61897843b5aecc5311cb.png
消费端工作流程

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

35323cb72a2f13e85527a18ff7d4602f.png
消费端与ZK之间的工作流程

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

消费者的三种消费情况

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

  1. 至少一次。即一条消息至少被消费一次,消息不可能丢失,但是可能会被重复消费。
  2. 至多一次。即一条消息最多可以被消费一次,消息不可能被重复消费,但是消息有可能丢失。
  3. 正好一次。即一条消息正好被消费一次,消息不可能丢失也不可能被重复消费。

1.至少一次

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

8a6bae60cbf43f71e66d2e7c3cc1cd8b.png
先消费后保存消费进度

2.至多一次

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

17f811c8bd5c75940ad7cfeaf377bcbd.png
先保存消费进度后消费消息

3.正好一次

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

a270507d7311a0a2649b45babcef3d78.png
正好消费一次

总结

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

特别推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下:

0cd743d81199a657f8f092dc80a2ba8a.png

长按订阅更多精彩▼

9ff77bba8b8910ebadbe9ecc17635129.png

如有收获,点个在看,诚挚感谢

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

kafka多个消费者消费一个topic_kafka:一文读懂消费者背后的那点"猫腻" 的相关文章

  • 关系数据库和NoSQL结合使用:MySQL + MongoDB

    Home Page 作者使用一个案例来说明MySQL 43 MongoDB结合使用 xff0c 发挥各自所长 xff0c 并且认为他们互补性很强 当然 xff0c 这其中不可避免引入DDD中的编程设计模式 Repository仓储模式 xf
  • 查看网卡信息及状态和网卡日志信息

    查看网卡信息 1 mii tool v w em1 em2 l0 em1 negotiated 100baseTx FD link ok product info vendor 00 aa 00 model 57 rev 1 basic m
  • 筛选出sql 查询结果中 不包含某个字符

    select from table1 where patindex 39 关键字 39 aa 61 0 select from table1 where charindex 39 关键字 39 aa 61 0 select from tab
  • IE8正式版引发VS2005和VS2008添加变量向导出错的解决方案

    1 解决办法1 xff1a 2 卸载IE8 3 解决办法2 xff1a xff08 自己使用的方法 xff09 4 5 打开注册表编辑器 6 7 选择 HKEY CURRENT USER Software Microsoft Windows
  • Visual Studio 2010中文旗舰版+大家所关心的

    下载地址 xff08 VS2010不含MSDN xff09 xff1a http download microsoft com download 2 4 7 24733615 AA11 42E9 8883 E28CDCA88ED5 X16
  • CSS列表

    CSS列表属性可以放置 改变列表项的标志 xff0c 或者将图像作为列表项标志 list style xff1a 简写属性 用于把所有用于列表的属性设置在一个声明中 list style image xff1a 将图像设置为列表项的标志 U
  • Lodash源码讲解-compact函数

    原文首发于Lodash源码讲解 这是我们阅读Lodash源码的第3篇博客 xff0c 在这篇文章里我们来学习一下Lodash的compact方法 compact函数内部没有依赖别的函数 xff0c 让我们先来看一下compact函数的源码
  • CentOS 6.5下Squid代理服务器的安装与配置

    一 系统环境 操作系统 xff1a CentOS release 6 5 Squid版本 xff1a squid 3 1 10 20 el6 5 3 x86 64 SELINUX 61 disabled HTTP Service stope
  • 修改VNCSERVER的分辨率

    使用VNC远程连接时 xff0c 最大化窗口后仍旧在中间显示一个小屏幕 xff0c 并没有随着窗口最大化 xff0c 解决该问题需要首先在VNC窗口标题栏右键 gt Options gt Scaling 选择第二项 xff1a Scale
  • XMLHttpRequest - 原始AJAX初步

    我们知道 xff0c 传统的Web应用是request response形式的 xff0c 即浏览器向服务器发送请求 xff0c 服务器进行处理 xff0c 然后再对浏览器响应 这种形式最大的缺点就是 xff1a 客户端需要等服务器处理完之
  • Python面向对象编程 - 一个记事本程序范例(二)

    给程序加上控制台菜单 menu py import sys from notebook import Notebook Note class Menu 39 39 39 Display a menu and respond to choic
  • 个人代码库の自动粘合桌面边缘

    using System Windows Forms using System namespace public partial class form 必要事件 xff1a No 1 xff1a 窗体的 Move 事件 No 2 xff1a
  • 完全参照系统自带的DatePickerDialog、TimePickerDialog的源代码仿写的DateTimePickerDialog...

    完全参照系统自带的DatePickerDialog TimePickerDialog的源代码仿写的DateTimePickerDialog 具有同时选择日期 时间的功能 在2 2 2 3平台 xff0c 显示的效果可能会有一个大背景框在后面
  • Tracking your habits in Org-mode

    纯属记录 在org mode中 xff0c 你可以跟踪你的周期性事务或辅助培养习惯 xff0c 比如每天阅读半小时 xff0c 每天完成后org mode会予以记录 如果你正计划每月培养一个好习惯 xff0c 也可以使用这个功能来记录你的完
  • 算法的力量

    算法的力量 李开复 真正学懂计算机的人 xff08 不只是 编程匠 xff09 都对数学有相当的造诣 xff0c 既能用科学家的严谨思维来求证 xff0c 也能用工程师的务实手段来解决问题 而这种思维和手段的最佳演绎就是 算法 虽然在摩尔定
  • Xstream序列化实体

    Java序列化的日期为是很标准 xff0c XStream中转换为标准的做法 import java text DateFormat import java text ParseException import java text Simp
  • Booksort 启发式函数很重要h(s1)<=h(s2)+cost(s1,s2);

    Problem Description The Leiden University Library has millions of books When a student wants to borrow a certain book he
  • FreeBSD的基本系统下Shell设置(转)

    FreeBSD的基本系统下Shell设置 转 64 more 64 命令解释程序shell是与用户关系最密切的应用程序 xff0c 用户主要通过shell使用系统 在每次登录系统之后 xff0c 就启动了一个与用户交互的shell xff0
  • 20050410:他们不过是一群政客

    从来就没有把台湾人民的利益放在眼里 xff0c 甚至不惜拿他们来做挡箭牌 xff0c 一边还对日本谄媚有加 转载于 https www cnblogs com yidinghe archive 2005 04 10 134987 html
  • 排列组合公式

    注 xff1a 排列与元素的顺序有关 xff0c 组合与顺序无关 xff0e 如231与213是两个排列 xff0c 2 xff0b 3 xff0b 1的和与2 xff0b 1 xff0b 3的和是一个组合 xff0e 1 xff0e 排列

随机推荐

  • Mybatis初始化机制

    对于任何框架而言 xff0c 在使用前都要进行一系列的初始化 xff0c MyBatis也不例外 本章将通过以下几点详细介绍MyBatis的初始化过程 1 MyBatis的初始化做了什么 2 MyBatis基于XML配置文件创建Config
  • ValidationSummary控件

    ValidationSummary控件用于在页面中的一处地方显示所有验证错误的列表 这个控件在使用大的表单时特别有用 如果用户在页面底部的表单字段中输入了错误的值 xff0c 那么这个用户可能永远也看不到错误信息 不过 xff0c 如果使用
  • 数据特征分析——概述

    一 6个基础分析思路 xff1a 1 分布分析 2 对比分析 3 统计分析 4 帕累托分析 5 正态性检验 6 相关性分析 二 分布分析 分布分析 xff1a 研究数据的分布特征和分布类型 xff0c 分定量数据 定性数据区分基本统计量 三
  • Filebeat 6.0 把日志直接输入到ES中如何自定义index

    临时搭建了一套EFK xff08 elasticsearch xff0c filebeat xff0c kibana xff09 xff0c filebeat 6 0 默认的index 是filebeat 43 时间 xff0c 这样无法满
  • 人在异乡

    为什么到了上海五年 xff0c 还是没有归属感 to be continued
  • 怎么求矩阵对应的基

    怎么求矩阵对应的基呢 xff1f 对矩阵做初等行变换 xff0c 化为上三角形 或 对角型 xff0c 主对角元素不为0的列即为该矩阵的一组基 A 61 这个矩阵对应的一个基 为 其实 xff0c 将第二行的 1 倍加到第一行上 xff0c
  • javascript弹出窗口代码

    1 最基本的弹出窗口代码 lt SCRIPT LANGUAGE 61 34 javascript 34 gt lt window open 39 page html 39 gt lt SCRIPT gt 因为着是一段javascripts代
  • 大规模异步新闻爬虫【5】:网页正文的提取

    前面我们实现的新闻爬虫 xff0c 运行起来后很快就可以抓取大量新闻网页 xff0c 存到数据库里面的都是网页的html代码 xff0c 并不是我们想要的最终结果 最终结果应该是结构化的数据 xff0c 包含的信息至少有url xff0c
  • 网络安全态势可视化

    导语 网络态势可视化技术作为一项新技术 xff0c 是网络安全态势感知与可视化技术的结合 xff0c 将网络中蕴涵的态势状况通过可视化图形方式展示给用户 xff0c 并借助于人在图形图像方面强大的处理能力 xff0c 实现对网络异常行为的分
  • 滚动窗口

    本页目录 语法案例 滚动窗口 xff08 TUMBLE xff09 将每个元素分配到一个指定大小的窗口中 通常滚动窗口有一个固定的大小 xff0c 并且不会出现重叠 例如 xff1a 如果指定了一个5分钟大小的滚动窗口 xff0c 无限流的
  • Qt5&OpenCV3 UDP协议实现实时视频传输与通信

    打算在树莓派上挂载摄像头 xff0c 通过WIFI模块传输到上位机 局域网内带宽不是问题 xff0c 为了保证实时性 xff0c 也没有必要进行复杂的视频编码和解码 xff0c 于是通过截图然后使用UDP协议传输应该是可以的 所以最近试探性
  • BeanUtils.copyProperties忽略某些字段的值及其原理

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 1 用法 例如 xff1a BeanUtils copyProperties beforeObj route new String 34 id 34 34 createDa
  • 关于C语言中的科学计数法问题。

    变量 不能作为e的指数 是的 double a 61 3 5e2 double a 61 3 5e0 double a 61 3 5e 2 只能是字面常量 xff0c 而且必须是整数 xff0c 正负0均可 double a 61 3 5e
  • Access Denied when running Spring.IocQuickStart.MovieFinder

    I just begin to learn something about Spring Net heaps of probem are waiting for me The very first one has been solved I
  • 错误提示窗口-“操作系统当前的配置不能运行此应用程序”

    有些人安装的Windows系统里的office是精简版的 xff0c 只适合普通办公处理word和excel xff0c 以及PPT xff0c 但是我们要研究一些关于数据库的知识时会受到阻碍 xff0c 大多数人会自己在网上随便找了一个A
  • matlab练习程序(倾斜校正,透视变换)

    过去也写过透视变换 xff0c 当时算法真是弱爆了 xff0c 我竟然会通过两次变换 不过那引用的三篇文章都是非常好的文章 xff0c 直到今天我才看明白 所谓的倾斜校正 xff0c 一定要有标定点 xff0c 将一个倾斜的矩形变为不倾斜的
  • 多媒体指令(数组对应元素相乘)

    include lt iostream gt using namespace std int main int argc char argv float a 8 61 1 2 3 4 5 6 7 8 float b 8 61 1 2 3 4
  • 安卓手机如何快速投屏到windows(10/8.1/7)电脑上

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 前提 手机和电脑连接的网络必须在同一局域网下 优势 手机和电脑不需要下载对应平台的应用 xff0c 完全使用全系统自带功能 附加 以下演示是安卓手机和windows操作系统
  • Webpack mode三种模式配置说明(production,development,none)

    我们都知道webpack的配置文件 webpack config js 文件中 mode 表示webpack当前的环境以及对不同的环境的配置 虽然官方文档写明了三种不同的模块的配置 xff0c 但是没有具体说明是什么意思 xff0c 我就注
  • kafka多个消费者消费一个topic_kafka:一文读懂消费者背后的那点&quot;猫腻&quot;

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