消费者组到底是什么?no.15

news2024/11/17 16:03:52

Kafka的消费者组。

消费者组,即Consumer Group,应该算是Kafka比较有亮点的设计了。那么何谓Consumer Group呢?用一句话概括就是:Consumer Group是Kafka提供的可扩展且具有容错性的消费者机制。既然是一个组,那么组内必然可以有多个消费者或消费者实例(Consumer Instance),它们共享一个公共的ID,这个ID被称为Group ID。组内的所有消费者协调在一起来消费订阅主题(Subscribed Topics)的所有分区(Partition)。当然,每个分区只能由同一个消费者组内的一个Consumer实例来消费。个人认为,理解Consumer Group记住下面这三个特性就好了。

  1. Consumer Group下可以有一个或多个Consumer实例。这里的实例可以是一个单独的进程,也可以是同一进程下的线程。在实际场景中,使用进程更为常见一些。
  2. Group ID是一个字符串,在一个Kafka集群中,它标识唯一的一个Consumer Group。
  3. Consumer Group下所有实例订阅的主题的单个分区,只能分配给组内的某个Consumer实例消费。这个分区当然也可以被其他的Group消费。

你应该还记得我在专栏第1期中提到的两种消息引擎模型吧?它们分别是点对点模型和发布/订阅模型,前者也称为消费队列。当然,你要注意区分很多架构文章中涉及的消息队列与这里的消息队列。国内很多文章都习惯把消息中间件这类框架统称为消息队列,我在这里不评价这种提法是否准确,只是想提醒你注意这里所说的消息队列,特指经典的消息引擎模型。

好了,传统的消息引擎模型就是这两大类,它们各有优劣。我们来简单回顾一下。传统的消息队列模型的缺陷在于消息一旦被消费,就会从队列中被删除,而且只能被下游的一个Consumer消费。严格来说,这一点不算是缺陷,只能算是它的一个特性。但很显然,这种模型的伸缩性(scalability)很差,因为下游的多个Consumer都要“抢”这个共享消息队列的消息。发布/订阅模型倒是允许消息被多个Consumer消费,但它的问题也是伸缩性不高,因为每个订阅者都必须要订阅主题的所有分区。这种全量订阅的方式既不灵活,也会影响消息的真实投递效果。

如果有这么一种机制,既可以避开这两种模型的缺陷,又兼具它们的优点,那就太好了。幸运的是,Kafka的Consumer Group就是这样的机制。当Consumer Group订阅了多个主题后,组内的每个实例不要求一定要订阅主题的所有分区,它只会消费部分分区中的消息。

Consumer Group之间彼此独立,互不影响,它们能够订阅相同的一组主题而互不干涉。再加上Broker端的消息留存机制,Kafka的Consumer Group完美地规避了上面提到的伸缩性差的问题。可以这么说,Kafka仅仅使用Consumer Group这一种机制,却同时实现了传统消息引擎系统的两大模型:如果所有实例都属于同一个Group,那么它实现的就是消息队列模型;如果所有实例分别属于不同的Group,那么它实现的就是发布/订阅模型。

在了解了Consumer Group以及它的设计亮点之后,你可能会有这样的疑问:在实际使用场景中,我怎么知道一个Group下该有多少个Consumer实例呢?理想情况下,Consumer实例的数量应该等于该Group订阅主题的分区总数。

举个简单的例子,假设一个Consumer Group订阅了3个主题,分别是A、B、C,它们的分区数依次是1、2、3(总共是6个分区),那么通常情况下,为该Group设置6个Consumer实例是比较理想的情形,因为它能最大限度地实现高伸缩性。

你可能会问,我能设置小于或大于6的实例吗?当然可以!如果你有3个实例,那么平均下来每个实例大约消费2个分区(6 / 3 = 2);如果你设置了8个实例,那么很遗憾,有2个实例(8 – 6 = 2)将不会被分配任何分区,它们永远处于空闲状态。因此,在实际使用过程中一般不推荐设置大于总分区数的Consumer实例。设置多余的实例只会浪费资源,而没有任何好处。

好了,说完了Consumer Group的设计特性,我们来讨论一个问题:针对Consumer Group,Kafka是怎么管理位移的呢?你还记得吧,消费者在消费的过程中需要记录自己消费了多少数据,即消费位置信息。在Kafka中,这个位置信息有个专门的术语:位移(Offset)。

看上去该Offset就是一个数值而已,其实对于Consumer Group而言,它是一组KV对,Key是分区,V对应Consumer消费该分区的最新位移。如果用Java来表示的话,你大致可以认为是这样的数据结构,即Map,其中TopicPartition表示一个分区,而Long表示位移的类型。当然,我必须承认Kafka源码中并不是这样简单的数据结构,而是要比这个复杂得多,不过这并不会妨碍我们对Group位移的理解。

我在专栏第4期中提到过Kafka有新旧客户端API之分,那自然也就有新旧Consumer之分。老版本的Consumer也有消费者组的概念,它和我们目前讨论的Consumer Group在使用感上并没有太多的不同,只是它管理位移的方式和新版本是不一样的。

老版本的Consumer Group把位移保存在ZooKeeper中。Apache ZooKeeper是一个分布式的协调服务框架,Kafka重度依赖它实现各种各样的协调管理。将位移保存在ZooKeeper外部系统的做法,最显而易见的好处就是减少了Kafka Broker端的状态保存开销。现在比较流行的提法是将服务器节点做成无状态的,这样可以自由地扩缩容,实现超强的伸缩性。Kafka最开始也是基于这样的考虑,才将Consumer Group位移保存在独立于Kafka集群之外的框架中。

不过,慢慢地人们发现了一个问题,即ZooKeeper这类元框架其实并不适合进行频繁的写更新,而Consumer Group的位移更新却是一个非常频繁的操作。这种大吞吐量的写操作会极大地拖慢ZooKeeper集群的性能,因此Kafka社区渐渐有了这样的共识:将Consumer位移保存在ZooKeeper中是不合适的做法。

于是,在新版本的Consumer Group中,Kafka社区重新设计了Consumer Group的位移管理方式,采用了将位移保存在Kafka内部主题的方法。这个内部主题就是让人既爱又恨的__consumer_offsets。我会在专栏后面的内容中专门介绍这个神秘的主题。不过,现在你需要记住新版本的Consumer Group将位移保存在Broker端的内部主题中。

最后,我们来说说Consumer Group端大名鼎鼎的重平衡,也就是所谓的Rebalance过程。我形容其为“大名鼎鼎”,从某种程度上来说其实也是“臭名昭著”,因为有关它的bug真可谓是此起彼伏,从未间断。这里我先卖个关子,后面我会解释它“遭人恨”的地方。我们先来了解一下什么是Rebalance。

Rebalance本质上是一种协议,规定了一个Consumer Group下的所有Consumer如何达成一致,来分配订阅Topic的每个分区。比如某个Group下有20个Consumer实例,它订阅了一个具有100个分区的Topic。正常情况下,Kafka平均会为每个Consumer分配5个分区。这个分配的过程就叫Rebalance。

那么Consumer Group何时进行Rebalance呢?Rebalance的触发条件有3个。

  1. 组成员数发生变更。比如有新的Consumer实例加入组或者离开组,抑或是有Consumer实例崩溃被“踢出”组。
  2. 订阅主题数发生变更。Consumer Group可以使用正则表达式的方式订阅主题,比如consumer.subscribe(Pattern.compile(“t.*c”))就表明该Group订阅所有以字母t开头、字母c结尾的主题。在Consumer Group的运行过程中,你新创建了一个满足这样条件的主题,那么该Group就会发生Rebalance。
  3. 订阅主题的分区数发生变更。Kafka当前只能允许增加一个主题的分区数。当分区数增加时,就会触发订阅该主题的所有Group开启Rebalance。

Rebalance发生时,Group下所有的Consumer实例都会协调在一起共同参与。你可能会问,每个Consumer实例怎么知道应该消费订阅主题的哪些分区呢?这就需要分配策略的协助了。

当前Kafka默认提供了3种分配策略,每种策略都有一定的优势和劣势,我们今天就不展开讨论了,你只需要记住社区会不断地完善这些策略,保证提供最公平的分配策略,即每个Consumer实例都能够得到较为平均的分区数。比如一个Group内有10个Consumer实例,要消费100个分区,理想的分配策略自然是每个实例平均得到10个分区。这就叫公平的分配策略。如果出现了严重的分配倾斜,势必会出现这种情况:有的实例会“闲死”,而有的实例则会“忙死”。

我们举个简单的例子来说明一下Consumer Group发生Rebalance的过程。假设目前某个Consumer Group下有两个Consumer,比如A和B,当第三个成员C加入时,Kafka会触发Rebalance,并根据默认的分配策略重新为A、B和C分配分区,如下图所示:

在这里插入图片描述
显然,Rebalance之后的分配依然是公平的,即每个Consumer实例都获得了2个分区的消费权。这是我们希望出现的情形。

讲完了Rebalance,现在我来说说它“遭人恨”的地方。

首先,Rebalance过程对Consumer Group消费过程有极大的影响。如果你了解JVM的垃圾回收机制,你一定听过万物静止的收集方式,即著名的stop the world,简称STW。在STW期间,所有应用线程都会停止工作,表现为整个应用程序僵在那边一动不动。Rebalance过程也和这个类似,在Rebalance过程中,所有Consumer实例都会停止消费,等待Rebalance完成。这是Rebalance为人诟病的一个方面。

其次,目前Rebalance的设计是所有Consumer实例共同参与,全部重新分配所有分区。其实更高效的做法是尽量减少分配方案的变动。例如实例A之前负责消费分区1、2、3,那么Rebalance之后,如果可能的话,最好还是让实例A继续消费分区1、2、3,而不是被重新分配其他的分区。这样的话,实例A连接这些分区所在Broker的TCP连接就可以继续用,不用重新创建连接其他Broker的Socket资源。

最后,Rebalance实在是太慢了。曾经,有个国外用户的Group内有几百个Consumer实例,成功Rebalance一次要几个小时!这完全是不能忍受的。最悲剧的是,目前社区对此无能为力,至少现在还没有特别好的解决方案。所谓“本事大不如不摊上”,也许最好的解决方案就是避免Rebalance的发生吧。

小结

总结一下,今天我跟你分享了Kafka Consumer Group的方方面面,包括它是怎么定义的,它解决了哪些问题,有哪些特性。同时,我们也聊到了Consumer Group的位移管理以及著名的Rebalance过程。希望在你开发Consumer应用时,它们能够助你一臂之力。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1713563.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LLM - 模型下载与 git-lfs 安装

目录 一.引言 二.安装 git lfs 1.使用 apt-get 安装 2.使用 Brew 安装 3.LFS 验证 三.总结 一.引言 在 HuggingFace 上下载模型时提供一个 git clone 的指令,执行后可以下载对应模型的模型文件: 但是本机还没有 git lfs 命令: git: lfs is not a git comman…

从这些原理中,读懂迅软DSE加密系统

加密技术是保护信息安全的系统,通过对原始数据进行加密,使得未经授权的人无法读取这些信息。 一、迅软DSE加密系统干什么用的? ★保护隐私:加密确保个人、机构的敏感信息在传输和存储过程中不被未授权的人访问。 ★防止数据泄露…

从简单到复杂,红酒配餐的层次感与变化

红酒配餐是一种艺术,通过不同层次的搭配,可以呈现出丰富的味觉变化,使每一口都充满惊喜。云仓酒庄雷盛红酒以其卓着的品质和与众不同的口感,为红酒配餐提供了无限可能。从简单到复杂,红酒配餐的层次感与变化如下&#…

CAD石墨烯生成器 V1.0 渊鱼

插件介绍 CAD石墨烯生成器插件可用于在AutoCAD软件内参数化建立石墨烯几何模型。插件建立石墨烯的球棍模型,可控制模型的尺寸、碳原子环的尺寸、原子直径、化学键直径,并可控制模型的起伏形态。插件生成的实体模型可进行修改或绘图渲染,用于…

flutter开发实战-类似微博帖子列表及下拉刷新上拉加载效果

flutter开发实战-类似微博帖子列表及下拉刷新上拉加载效果 在之前处理类似微博帖子列表及下拉刷新上拉加载效果,刷新使用的是EasyRefresh 一、引入EasyRefresh与likeButton 在工程的pubspec.yaml中引入插件 # 下拉刷新、上拉更多easy_refresh: ^3.3.21pull_to_re…

每天写两道(二)LRU缓存、数组中最大的第k个元素

146.LRU 缓存 . - 力扣(LeetCode) 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类: LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 key 存在于缓存…

【考研数学】数学一和数学二哪个更难?如何复习才能上90分?

很明显考研数学一更难! 不管是复习量还是题目难度 对比项考研数学一考研数学二适用专业理工科类及部分经济学类理工科类考试科目高等数学、线性代数、概率论与数理统计高等数学、线性代数试卷满分150分150分考试时间180分钟180分钟试卷内容结构高等数学约60%&…

精通推荐算法7:多任务学习 -- 总体架构

1 多任务学习的总体架构 目前的互联网主流推荐场景在大多数情况下需要优化多个业务目标。例如在淘宝商品推荐中,需要兼顾点击率和转化率。在抖音短视频推荐中,需要考虑完播率、播放时长、点赞率、评论率、关注率等目标。为了提升各项业务目标&#xff0…

虹科Pico汽车示波器 | 免拆诊断案例 | 2017款吉利帝豪GL车发动机偶尔无法起动

故障现象  一辆2017款吉利帝豪GL车,搭载JLC-4G18发动机和手动变速器,累计行驶里程约为39.3万km。车主反映,该车发动机偶尔无法起动。故障发生频率比较频繁,冷机状态下故障比较容易出现。 故障诊断  接车后试车,故…

一款超好用的国产Redis可视化工具

一、简介 1、这是一款追求极致性能(它可以支持前面100万数据的展示。)海量数据下低内存占用、极简布局、高效交互、跨平台、支持反序列化Java字节码的redis可视化客户端工具。 支持三大操作系统Windows、MacOS、Linux,适合不同操作系统口味的…

树莓派开箱

1.树莓派4B配置 CPU:64位1.5GHZ四核处理器。 GPU:Broadcom VideoCore VI500MHZ 蓝牙5.0 电源Type C(5V 3A),也可以使用排针链接5V锂电池最大放电电流必须达到3A。 还有千兆以太网等以后用到再说。 接下来进入文章重点 2.镜像文件烧录 前期准备:1…

ChatGPT魔法,定制个性化提示词!

扮演Prompt创作者的角色 我想让你成为我的Prompt创作者。你的目标是帮助我创建最佳的Prompt,这个Prompt将由 你ChatGPT使用。 你将遵循以下过程: 1.首先,你会问我Prompt是关于什么的。我会告诉你,但我们需要通过不断的重复来改进…

在 CentOS 上安装 PostgreSQL 的全面指南

PostgreSQL 是一种功能强大的开源关系型数据库管理系统,广泛应用于各种领域。它提供了诸如事务处理、并发控制和数据完整性等高级功能,因此深受开发者和企业的欢迎。本指南将逐步引导您在 CentOS 上安装 PostgreSQL,以便您充分利用其众多优势…

Facebook:社交世界的接口

在当今数字时代,社交媒体已经成为了人们生活中不可或缺的一部分,而Facebook作为其中的巨头之一,扮演着至关重要的角色。本文将带您深入探索Facebook这张社交世界的画卷,全面了解这个令人着迷的平台。 起源与历程 Facebook的故事始…

无线麦克风什么牌子的音质效果好?一文读懂无线领夹麦克风哪款好

​在当今的数字时代,无线技术已经深入到我们生活的方方面面,无线领夹麦克风便是其中的佼佼者。它们为讲者、表演者以及那些需要在移动中讲话的人们提供了解放双手和自由移动的可能。本文旨在探讨无线领夹麦克风的多种用途,以及如何挑选最适合…

Pycharm打开django支持

在 PyCharm 中打开 “Settings/Preferences” -> “Languages & Frameworks” -> “Django”。 勾上Enable Django support 然后配置好文件根目录就好了

基于PTP实现主机与相机系统时钟同步功能

基于PTP实现主机与相机系统时钟同步功能 一、PTP简介二、工业相机PTP功能支持三、工业相机时间戳介绍3.1基本概念3.2海康工业相机时间戳介绍3.2.1相机参数时间戳3.2.2图像嵌入式时间戳3.2.3相机event事件时间戳3.2.4各种时间戳的时序关系3.2.5通过工业相机SDK获取相机时间戳 四…

如何将md文件精确的转换成docx文件

如何将md文件转换成docx? 文章目录 如何将md文件转换成docx?一、如何将MD文件比较完美的转换成word呢?二、方法3 步骤1、下载一个可用的MarkDown编辑器2、下载Pandoc安装 三、来进行转化了 一、如何将MD文件比较完美的转换成word呢&#xff1…

MySQL实战行转列(或称为PIVOT)实战sales的表记录了不同产品在不同月份的销售情况,进行输出

有一个sales的表,它记录了不同产品在不同月份的销售情况: productJanuaryFebruaryMarchProduct AJanuary10Product AFebruary20Product BJanuary5Product BFebruary15Product CJanuary8Product CFebruary12 客户需求展示为如下的样子: pro…

【优选算法】分治 {三分快排:三指针优化,随机选key,快速选择算法;归并排序:统计数组中的逆序对,统计数组中的翻转对;相关编程题解析}

一、经验总结 1.1 三分快排 优化一:三指针优化 之前学习的快速排序无法妥善处理相等或重复序列的排序问题(有序且三数取中无效),使快速排序的效率无法达到最优。 为了解决重复序列的问题,我们将原先的双指针法&…