揭开神秘的“位移主题”面纱 no.16

news2024/12/23 14:11:11

Kafka中神秘的内部主题(Internal Topic)__consumer_offsets。

consumer_offsets在Kafka源码中有个更为正式的名字,叫*位移主题*,即Offsets Topic。为了方便今天的讨论,我将统一使用位移主题来指代consumer_offsets。需要注意的是,它有两个下划线哦。

好了,我们开始今天的内容吧。首先,我们有必要探究一下位移主题被引入的背景及原因,即位移主题的前世今生。

在上一期中,我说过老版本Consumer的位移管理是依托于Apache ZooKeeper的,它会自动或手动地将位移数据提交到ZooKeeper中保存。当Consumer重启后,它能自动从ZooKeeper中读取位移数据,从而在上次消费截止的地方继续消费。这种设计使得Kafka Broker不需要保存位移数据,减少了Broker端需要持有的状态空间,因而有利于实现高伸缩性。

但是,ZooKeeper其实并不适用于这种高频的写操作,因此,Kafka社区自0.8.2.x版本开始,就在酝酿修改这种设计,并最终在新版本Consumer中正式推出了全新的位移管理机制,自然也包括这个新的位移主题。

新版本Consumer的位移管理机制其实也很简单,就是**将Consumer的位移数据作为一条条普通的Kafka消息,提交到**consumer_offsets中。可以这么说,**consumer_offsets的主要作用是保存Kafka消费者的位移信息。**它要求这个提交过程不仅要实现高持久性,还要支持高频的写操作。显然,Kafka的主题设计天然就满足这两个条件,因此,使用Kafka主题来保存位移这件事情,实际上就是一个水到渠成的想法了。

这里我想再次强调一下,和你创建的其他主题一样,位移主题就是普通的Kafka主题。你可以手动地创建它、修改它,甚至是删除它。只不过,它同时也是一个内部主题,大部分情况下,你其实并不需要“搭理”它,也不用花心思去管理它,把它丢给Kafka就完事了。

虽说位移主题是一个普通的Kafka主题,但它的消息格式却是Kafka自己定义的,用户不能修改,也就是说你不能随意地向这个主题写消息,因为一旦你写入的消息不满足Kafka规定的格式,那么Kafka内部无法成功解析,就会造成Broker的崩溃。事实上,Kafka Consumer有API帮你提交位移,也就是向位移主题写消息。你千万不要自己写个Producer随意向该主题发送消息。

你可能会好奇,这个主题存的到底是什么格式的消息呢?所谓的消息格式,你可以简单地理解为是一个KV对。Key和Value分别表示消息的键值和消息体,在Kafka中它们就是字节数组而已。想象一下,如果让你来设计这个主题,你觉得消息格式应该长什么样子呢?我先不说社区的设计方案,我们自己先来设计一下。

首先从Key说起。一个Kafka集群中的Consumer数量会有很多,既然这个主题保存的是Consumer的位移数据,那么消息格式中必须要有字段来标识这个位移数据是哪个Consumer的。这种数据放在哪个字段比较合适呢?显然放在Key中比较合适。

现在我们知道该主题消息的Key中应该保存标识Consumer的字段,那么,当前Kafka中什么字段能够标识Consumer呢?还记得之前我们说Consumer Group时提到的Group ID吗?没错,就是这个字段,它能够标识唯一的Consumer Group。

说到这里,我再多说几句。除了Consumer Group,Kafka还支持独立Consumer,也称Standalone Consumer。它的运行机制与Consumer Group完全不同,但是位移管理的机制却是相同的。因此,即使是Standalone Consumer,也有自己的Group ID来标识它自己,所以也适用于这套消息格式。

Okay,我们现在知道Key中保存了Group ID,但是只保存Group ID就可以了吗?别忘了,Consumer提交位移是在分区层面上进行的,即它提交的是某个或某些分区的位移,那么很显然,Key中还应该保存Consumer要提交位移的分区。

好了,我们来总结一下我们的结论。位移主题的Key中应该保存3部分内容:。如果你认同这样的结论,那么恭喜你,社区就是这么设计的!

接下来,我们再来看看消息体的设计。也许你会觉得消息体应该很简单,保存一个位移值就可以了。实际上,社区的方案要复杂得多,比如消息体还保存了位移提交的一些其他元数据,诸如时间戳和用户自定义的数据等。保存这些元数据是为了帮助Kafka执行各种各样后续的操作,比如删除过期位移消息等。但总体来说,我们还是可以简单地认为消息体就是保存了位移值。

当然了,位移主题的消息格式可不是只有这一种。事实上,它有3种消息格式。除了刚刚我们说的这种格式,还有2种格式:

  1. 用于保存Consumer Group信息的消息。
  2. 用于删除Group过期位移甚至是删除Group的消息。

第1种格式非常神秘,以至于你几乎无法在搜索引擎中搜到它的身影。不过,你只需要记住它是用来注册Consumer Group的就可以了。

第2种格式相对更加有名一些。它有个专属的名字:tombstone消息,即墓碑消息,也称delete mark。下次你在Google或百度中见到这些词,不用感到惊讶,它们指的是一个东西。这些消息只出现在源码中而不暴露给你。它的主要特点是它的消息体是null,即空消息体。

那么,何时会写入这类消息呢?一旦某个Consumer Group下的所有Consumer实例都停止了,而且它们的位移数据都已被删除时,Kafka会向位移主题的对应分区写入tombstone消息,表明要彻底删除这个Group的信息。

好了,消息格式就说这么多,下面我们来说说位移主题是怎么被创建的。通常来说,当Kafka集群中的第一个Consumer程序启动时,Kafka会自动创建位移主题。我们说过,位移主题就是普通的Kafka主题,那么它自然也有对应的分区数。但如果是Kafka自动创建的,分区数是怎么设置的呢?这就要看Broker端参数offsets.topic.num.partitions的取值了。它的默认值是50,因此Kafka会自动创建一个50分区的位移主题。如果你曾经惊讶于Kafka日志路径下冒出很多__consumer_offsets-xxx这样的目录,那么现在应该明白了吧,这就是Kafka自动帮你创建的位移主题啊。

你可能会问,除了分区数,副本数或备份因子是怎么控制的呢?答案也很简单,这就是Broker端另一个参数offsets.topic.replication.factor要做的事情了。它的默认值是3。

总结一下,如果位移主题是Kafka自动创建的,那么该主题的分区数是50,副本数是3

当然,你也可以选择手动创建位移主题,具体方法就是,在Kafka集群尚未启动任何Consumer之前,使用Kafka API创建它。手动创建的好处在于,你可以创建满足你实际场景需要的位移主题。比如很多人说50个分区对我来讲太多了,我不想要这么多分区,那么你可以自己创建它,不用理会offsets.topic.num.partitions的值。

不过我给你的建议是,还是让Kafka自动创建比较好。目前Kafka源码中有一些地方硬编码了50分区数,因此如果你自行创建了一个不同于默认分区数的位移主题,可能会碰到各种各样奇怪的问题。这是社区的一个Bug,目前代码已经修复了,但依然在审核中。

创建位移主题当然是为了用的,那么什么地方会用到位移主题呢?我们前面一直在说Kafka Consumer提交位移时会写入该主题,那Consumer是怎么提交位移的呢?目前Kafka Consumer提交位移的方式有两种:自动提交位移和手动提交位移。

Consumer端有个参数叫enable.auto.commit,如果值是true,则Consumer在后台默默地为你定期提交位移,提交间隔由一个专属的参数auto.commit.interval.ms来控制。自动提交位移有一个显著的优点,就是省事,你不用操心位移提交的事情,就能保证消息消费不会丢失。但这一点同时也是缺点。因为它太省事了,以至于丧失了很大的灵活性和可控性,你完全没法把控Consumer端的位移管理。

事实上,很多与Kafka集成的大数据框架都是禁用自动提交位移的,如Spark、Flink等。这就引出了另一种位移提交方式:手动提交位移,即设置enable.auto.commit = false。一旦设置了false,作为Consumer应用开发的你就要承担起位移提交的责任。Kafka Consumer API为你提供了位移提交的方法,如consumer.commitSync等。当调用这些方法时,Kafka会向位移主题写入相应的消息。

如果你选择的是自动提交位移,那么就可能存在一个问题:只要Consumer一直启动着,它就会无限期地向位移主题写入消息。

我们来举个极端一点的例子。假设Consumer当前消费到了某个主题的最新一条消息,位移是100,之后该主题没有任何新消息产生,故Consumer无消息可消费了,所以位移永远保持在100。由于是自动提交位移,位移主题中会不停地写入位移=100的消息。显然Kafka只需要保留这类消息中的最新一条就可以了,之前的消息都是可以删除的。这就要求Kafka必须要有针对位移主题消息特点的消息删除策略,否则这种消息会越来越多,最终撑爆整个磁盘。

Kafka是怎么删除位移主题中的过期消息的呢?答案就是Compaction。国内很多文献都将其翻译成压缩,我个人是有一点保留意见的。在英语中,压缩的专有术语是Compression,它的原理和Compaction很不相同,我更倾向于翻译成压实,或干脆采用JVM垃圾回收中的术语:整理。

不管怎么翻译,Kafka使用Compact策略来删除位移主题中的过期消息,避免该主题无限期膨胀。那么应该如何定义Compact策略中的过期呢?对于同一个Key的两条消息M1和M2,如果M1的发送时间早于M2,那么M1就是过期消息。Compact的过程就是扫描日志的所有消息,剔除那些过期的消息,然后把剩下的消息整理在一起。我在这里贴一张来自官网的图片,来说明Compact过程。

在这里插入图片描述
图中位移为0、2和3的消息的Key都是K1。Compact之后,分区只需要保存位移为3的消息,因为它是最新发送的。

Kafka提供了专门的后台线程定期地巡检待Compact的主题,看看是否存在满足条件的可删除数据。这个后台线程叫Log Cleaner。很多实际生产环境中都出现过位移主题无限膨胀占用过多磁盘空间的问题,如果你的环境中也有这个问题,我建议你去检查一下Log Cleaner线程的状态,通常都是这个线程挂掉了导致的。

小结

总结一下,今天我跟你分享了Kafka神秘的位移主题__consumer_offsets,包括引入它的契机与原因、它的作用、消息格式、写入的时机以及管理策略等,这对我们了解Kafka特别是Kafka Consumer的位移管理是大有帮助的。实际上,将很多元数据以消息的方式存入Kafka内部主题的做法越来越流行。除了Consumer位移管理,Kafka事务也是利用了这个方法,当然那是另外的一个内部主题了。

社区的想法很简单:既然Kafka天然实现了高持久性和高吞吐量,那么任何有这两个需求的子服务自然也就不必求助于外部系统,用Kafka自己实现就好了。

在这里插入图片描述

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

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

相关文章

新疆 | 金石商砼效率革命背后的逻辑

走进标杆企业,感受名企力量,探寻学习优秀企业领先之道。 本期要跟砼行们推介的标杆企业是新疆砼行业的龙头企业:新疆兵团建工金石商品混凝土有限责任公司(以下简称:新疆金石)。 从年产80万方到120万方&am…

OpenMv图片预处理

本博客讲述的是获取一张图片首先对图像进行处理,比如畸形矫正,图像滤波等操作。 1.histeq()自适应直方图均衡 # 自适应直方图均衡例子 # # 此示例展示了如何使用自适应直方图均衡来改善图像中的对比度。 #自适应直方图均衡将图像分割成区域,然后均衡这些区域中的直方图,…

React基础知识笔记

Reat简介 React:用于构建用户界面的 JavaScript 库。由 Facebook 开发且开源。是一个将视图渲染为html视图的开源库 第一章:React入门 相关js库 react.development.js :React 核心库react-dom.development.js :提供 DOM 操作的…

5月岚庭工人大会“安全就是效率、形象即是品质”

2024年5月18日、19日岚庭一月一期的“产业工人大会”和“工程大会”圆满举行初夏正当时,此次大会主要围绕“安全”与“形象”展开六场专题培训只为精益求精产业工人和装修管家全体到场。 岚庭 以绝对【安全】护家护园 安全就是生命,违章就是事故&#x…

想知道股指期货和期权有什么不同吗?

市场上目前有中金所的沪深300ETF,中证500和中证1000股指期货,期权市场有上证50ETF,沪深300etf和中证500ETF期权,股指期货和期权在买卖双方的权利义务、风险收益特征、保证金制度、上市合约数量等方面均有较大区别,下文…

地市新质生产力最新测算数据集-2005至2024年(基于工作BG)

数据简介:参考肖有智等(2024)的做法,查找各个地级市年工作BG进行词频分析,加总得到新质生产力总词频数据。数据来源:工作BG 时间范围:2005-2024年 数据范围:各地级市包含指标&…

最新!2023年台湾10米DEM地形瓦片数据

上次更新谷歌倾斜摄影转换生成OSGB瓦片V1.1版本,使用该版本生产了台北、台中、桃园三个地方的倾斜摄影OSGB数据,在OSGB可视化软件中进行展示,可视化效果和加载效率俱佳。已经很久没更新地形瓦片数据,主要是热点地区的原始数据没有…

竹云董事长在第二届ICT技术发展与企业数字化转型高峰论坛作主题演讲

5月25日,由中国服务贸易协会指导,中国服务贸易协会信息技术服务委员会主办的 “第二届ICT技术发展与企业数字化转型高峰论坛” 在北京隆重召开。 本次论坛以 “数据驱动,AI引领,打造新质生产力” 为主题,特邀业内200余…

el-pagination在删除非第一页的最后一条数据遇到的问题

文章目录 前言一、问题展示二、解决方案三、源码解析1、elementui2、elementplus 总结 前言 这个问题是element-ui中的问题,可以从源码中看出来,虽然页码更新了,active也是对的,但是未调用current-change的方法,这里就…

tinymce富文本编辑器使用

安卓富文本编辑器&#xff1a;npm i tinymce/tinymce-vue 当前项目中富文本是放在一个dialog中&#xff0c;因此部分样式会有层叠问题&#xff0c;该组件样式部分不添加scope。这里图片上传只是前端静态数据展示收集。 <template><div class"desc-editor"…

【算法工程师】(三年面试五年模拟版)总结

写在前面&#xff1a; WeThinkIn &#xff08;公主号&#xff09; 学习经验分享 目录 1、机器学习基础 2、深度学习基础 2.1 1*1卷积的作用 注&#xff1a;卷积核的个数对应输出的通道数&#xff08;channels&#xff09;&#xff0c;比如输入6*6*64&#xff0c;卷积核1…

C语言数据结构堆排序、向上调整和向下调整的时间复杂度的计算、TopK问题等的介绍

文章目录 前言一、堆排序1. 排升序&#xff08;1&#xff09;. 建堆&#xff08;2&#xff09;. 排序 2. 拍降序&#xff08;1&#xff09;. 建堆&#xff08;2&#xff09;. 排序 二、建堆时间复杂度的计算1. 向上调整时间复杂度2. 向下调整时间复杂度 三、TopK问题总结 前言 …

【数据结构与算法 | 链表篇】力扣876

1. 力扣876 : 链表的中间节点 (1). 题 给你单链表的头结点 head &#xff0c;请你找出并返回链表的中间结点。 如果有两个中间结点&#xff0c;则返回第二个中间结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[3,4,5] 解释&#xff1a;链表…

Springboot 实战运用

一&#xff0c;基本配置 1&#xff0c;pom文件配置介绍 1.1继承 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.2</version><relativePath/> <…

架构(十七)翻译监控

一、引言 作者最近做的一个功能是需要监控一个翻译转换&#xff0c;根据国家和语言进行分组&#xff0c;然后定时把监控情况放到ck里面。为什么是分组和定时监控呢&#xff1f;因为调用比较高的系统的qps在单机一万多&#xff0c;70台机器&#xff0c;可怕的高频调用注定他不能…

基于51单片机的室内空气质量检测-仿真设计

本设计是基于单片机的空气质量检测设计&#xff0c;主要实现以下功能&#xff1a; 可实现通过SGP30测量二氧化碳及甲醛浓度&#xff0c;当超过设置的最大值时&#xff0c;进行报警及通风和净化空气处理 可实现通过MQ-4测量甲烷浓度&#xff0c;当超过设置的最大值时&#xff0…

PIC单片机控制小型三相无刷直流电机

1、使用PIC12F629小型三相无刷直流电机制作电动口罩&#xff0c;涉及到电机的驱动芯片的选型&#xff0c;这里选用国产的MS39549驱动芯片&#xff1b; 2、搭建的电路图如下&#xff1a; 3、单片机给MS39549驱动芯片发送PWM占空比信号&#xff0c;即可实现对电机的转速控制&…

webpack快速入门---webpack的安装和基本使用

webpack是什么 本质上&#xff0c;webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具。当 webpack 处理应用程序时&#xff0c;它会在内部从一个或多个入口点构建一个 依赖图(dependency graph)&#xff0c;然后将你项目中所需的每一个模块组合成一个或多个 bund…

How Diffusion Models Work

introduction intuition goal 让神经网络学到图像是什么样的&#xff0c;一种方式是对数据添加不同级别的噪音&#xff0c;让神经网络能够区分细节/总体轮廓 训练一个神经网络去产生精灵 sampling nn

最新淘宝死店全自动采集私信筛选脚本,号称日赚500+【采集软件+使用教程】

原理&#xff1a; 利用脚本自动采集长时间未登录店铺&#xff0c;然后脚本自动私信对应的店铺&#xff0c;看看商家是不是不回消息来判断是否是死店&#xff0c;再下单购买死店的产品&#xff0c;超过48小时不发货就可以联系客服获得赔付&#xff0c;一单利润百分之5%-30%&…