在本文中,我们将介绍 Kafka 如何管理底层偏移量、您必须准备应对的故障场景,以及偏移量如何帮助您保持系统一致性(即使服务不断启动和停止)。我们还将了解其他技术如何应对类似的挑战。
关键:
- Kafka怎么记录消息读到哪儿了?
- 系统出问题时怎么办?
- 怎么保证系统数据不乱套(就算服务总重启也没事)?
我们还会看看别的技术是怎么解决类似问题的。
以前记录进度的方法方法①:
记在数据库里就像你用笔记本记作业进度。如果只有你一个人记很简单,但要是全班共用一个笔记本,大家都来改同一个进度记录,就会乱套。万一有人改到一半笔记本掉地上,其他人就不知道最新进度了。
方法②:
记在自己电脑里就像把进度存在自己手机备忘录。虽然方便,但手机丢了就完蛋。而且如果换台电脑继续干活,新电脑看不到之前的记录。
所以这些方法在人多了或者电脑可能坏的时候都不靠谱,Kafka就想了个新办法:
Kafka的改进方案
以前Kafka用ZooKeeper(像个公共布告栏)来记进度:
- 好处:人少的时候挺好用
- 坏处:人多了大家都来贴纸条,布告栏就挤爆了,经常卡住
- 不怕丢:多复印了几本放在不同地方
- 自动整理:只保留最新进度,旧记录自动清理
- 速度快:50个分类格子分开记录,不会挤在一起
这个记录本怎么用就像班级值日表:
- 每组值日生(消费者组)有专属格子
- 每次完成工作就在对应格子写"今天扫到第几排"
- 组长(协调器)会检查大家的进度
- 如果有人请假,回来直接看记录本就知道从哪继续
- 重启后直接看记录本的最后进度
- 可能最后一条消息要重新做(但不会全部重做)
其他系统是如何进行偏移跟踪的?
比较不同系统的偏移管理,可以突显设计选择、性能目标和运营需求如何影响其方法。Kafka 的主题内偏移跟踪只是一种解决方案;这里还有其他几个很好的示例和参考资料,您可以探索以获得更多见解。
MongoDB Oplog
MongoDB 的复制依赖于oplog (操作日志),该日志记录副本集中的所有写入操作(MongoDB 文档)。每个辅助节点按顺序应用 oplog 中的更改,以确保最终一致性。虽然它不是严格意义上的偏移模型,但 oplog 具有一些相似之处:
- 按时间顺序记录:操作以仅附加的方式存储,允许辅助服务器在停机后赶上进度。
- 主要用例:数据库复制,而不是事件流。
- 权衡:虽然它非常适合 MongoDB 复制,但它并非为任意消费者组或应用程序级偏移而设计。如果您需要协调处理同一数据流的多个消费者,那么仅使用 MongoDB 的 oplog 无法完全解决该场景。
EventStoreDB 的两种模型
EventStoreDB 是一个数据库,而不是流式传输解决方案,但它仍然具有流式传输功能。它为您提供了订阅有关新事件的通知的选项。它提供两种主要订阅模式:
- 持久订阅:服务器跟踪检查点,将事件分发给多个消费者。如果您希望服务器管理并发性并确保不会有多个竞争消费者同时处理任何事件,那么这种方法非常方便。不过,在重试的情况下,它无法保证顺序,而且会给数据库带来更多负担。
- 追赶订阅:客户端控制其在流中的偏移量(或“位置”)。此模型提供了更大的灵活性(例如从较旧的事件开始或在历史中的特定点重新订阅),但也增加了应用程序处理偏移量存储和恢复的责任。通常,您将偏移量存储在另一个数据库中。
RabbitMQ
RabbitMQ 是一个消息代理,它使用确认来确认消息处理(RabbitMQ 文档)。消费者处理消息后,它会向服务器发送确认,然后服务器可以从队列中删除该消息。要点:
- 每个队列确认状态:RabbitMQ 期望每次传送都有一个确认,而不是在日志中跟踪偏移量。
- 扩展:多个工作者可以使用每个队列,但是代理决定如何分发消息。
- 权衡:对于较小的设置,配置更简单。然而,在非常大的规模或多数据中心环境中,协调队列状态和处理故障转移可能比 Kafka 样式的偏移日志更复杂。
Apache Pulsar
Pulsar通过将数据保存在BookKeeper中并将消费者位置存储在元数据系统(通常是 ZooKeeper)中(Pulsar 订阅文档)来解耦存储和服务。Pulsar 将这些位置称为“游标”,其功能类似于 Kafka 的偏移量:
- 游标:每个消费者或订阅都维护自己的游标,指示其已读取的程度。
- 水平扩展:由于 BookKeeper 单独管理数据存储,因此 Pulsar 可以独立扩展存储和计算层。
- 权衡:这种方法在处理大量数据时效果很好,但操作 BookKeeper 和 ZooKeeper 会增加复杂性。了解多层组件对于长期稳定使用至关重要。
比较这些方法时,请考虑以下几点:
- 吞吐量要求:您预计每秒有多少次提交或确认?
- 故障模型:您必须自动处理哪些故障模式(节点崩溃、网络分裂等)?
- 操作复杂性:您是否能熟练操作多个组件(例如 BookKeeper、ZooKeeper)?您是否具备高级配置的能力?
- 数据访问模式:您是否需要细粒度的事件重播、事务保证或简单的队列语义?
偏移量跟踪对于在分布式系统中保持数据处理的一致性至关重要。通过在__consumer_offsets主题中保留偏移量,Kafka 可让每个消费者在崩溃、重新平衡甚至数据中心故障转移后继续准确地从中断的位置继续处理。在电子商务示例中,这意味着如果服务重新启动,您不必重播每个历史订单,从而大大降低了重复处理的风险。
简单的解决方案(例如偏移量的本地文件或数据库记录)可能在有限的条件下有效,但当您有多个消费者或需要扩展时会变得麻烦。Kafka 的内置偏移模型通过使用复制、压缩和内部事件日志来跟踪已处理的内容,解决了许多此类复杂性。
在任何大型系统中,验证偏移量的存储、提交和恢复方式都是实际故障处理的关键,尤其是在分布式系统的情况下。了解这些权衡对于设计、监控和排除实时事件驱动应用程序的故障至关重要。
总结
Kafka这个设计就像:
- 每人有专属进度条(不怕别人改乱)
- 自动存档(不怕丢)
- 随时可查(重启也不慌)