持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第16天,点击查看活动详情
前言
今天是我 Kafka 学习学习的第 17 天,今天学习的内容是日志同步机制。
在分布式系统中,日志同步机制既要保证数据的一致性,也要保证数据的顺序性。虽然有许多方式可以实现这些功能,但最简单高效的方式还是从集群中选出一个 leader 来负责处理数据写入的顺序性。只要 leader 还处于存活状态,那么 follower 只需按照 leader 中的写入顺序来进行同步即可。
那么当 leader 节点挂掉之后如何保证数据不丢失呢?下面我们一起看下。
日志同步机制
日志同步机制的一个基本原则就是:如果告知客户端已经成功提交了某条消息,那么即使 leader宕机,也要保证新选举出来的 leader 中能够包含这条消息。
这里就有一个需要权衡(tradeoff)的地方,如果 leader 在消息被提交前需要等待更多的 follower 确认,那么在它宕机之后就可以有更多的 follower 替代它,不过这也会造成性能的下降。
少数服从多数
对于这种 tradeoff,一种常见的做法是“少数服从多数”,它可以用来负责提交决策和选举决策。
在这种方式下,如果我们有 2f+1 个副本,那么在提交之前必须保证有 f+1 个副本同步完消息。同时为了保证能正确选举出新的 leader,至少要保证有 f+1 个副本节点完成日志同步并从同步完成的副本中选举出新的 leader 节点。并且在不超过 f 个副本节点失败的情况下,新的 leader 需要保证不会丢失已经提交过的全部消息。这样在任意组合的 f+1 个副本中,理论上可以确保至少有一个副本能够包含已提交的全部消息,这个副本的日志拥有最全的消息,因此会有资格被选举为新的 leader 来对外提供服务。
优劣势
“少数服从多数”的方式有一个很大的优势,系统的延迟取决于最快的几个节点,比如副本数为 3,那么延迟就取决于最快的那个 follower 而不是最慢的那个(除了 leader,只需要另一个 follower 确认即可)。
不过它也有一些劣势,为了保证 leader 选举的正常进行,它所能容忍的失败 follower 数比较少,如果要容忍 1 个 follower 失败,那么至少要有 3 个副本,如果要容忍 2 个 follower 失败,必须要有 5 个副本。也就是说,在生产环境下为了保证较高的容错率,必须要有大量的副本,而大量的副本又会在大数据量下导致性能的急剧下降。这也就是“少数服从多数”的这种 Quorum 模型常被用作共享集群配置(比如 ZooKeeper),而很少用于主流的数据存储中的原因。
ISR 集合选举
Kafka 采用的是另外一种方式。
在 Kafka 中动态维护着一个 ISR 集合,处于 ISR 集合内的节点保持与 leader 相同的高水位(HW),只有位列其中的副本才有资格被选为新的 leader。写入消息时只有等到所有 ISR 集合中的副本都确认收到之后才能被认为已经提交。位于 ISR 中的任何副本节点都有资格成为leader。
优劣势
这种方式选举过程简单、开销低,这也是 Kafka 选用此模型的重要因素。Kafka 中包含大量的分区,leader 副本的均衡保障了整体负载的均衡,所以这一因素也极大地影响 Kafka 的性能指标。
在采用 ISR 模型和(f+1)个副本数的配置下,一个 Kafka 分区能够容忍最大 f 个节点失败,相比于“少数服从多数”的方式所需的节点数大幅减少。
在需要相同确认信息数的情况下,采用 ISR 的方式所需要的副本总数变少,复制带来的集群开销也就更低,“少数服从多数”的优势在于它可以绕开最慢副本的确认信息,降低提交的延迟,而对Kafka 而言,这种能力可以交由客户端自己去选择。
参考文档
- 《深入理解 Kafka:核心设计与实践原理》—— 朱忠华
往期文章
- Kafka 进阶学习(二)—— 生产者客户端架构
- Kafka 进阶学习(三)—— 一些生产者配置的关键参数
- Kafka 进阶学习(四)—— 消费者和消费组
- Kafka 进阶学习(五)—— 如何合理选择合适的分区数
- Kafka 进阶学习(六)—— 文件目录布局
- Kafka 进阶学习(七)—— 日志索引
- Kafka 进阶学习(八)—— 日志清理
- Kafka 进阶学习(九)—— 磁盘存储
- Kafka 进阶学习(十)—— 协议设计
- Kafka 进阶学习(十一)—— 时间轮
- Kafka 进阶学习(十二)—— 延时操作
- Kafka 进阶学习(十三)—— 控制器
- Kafka 进阶学习(十四)—— 分区分配策略
- Kafka 进阶学习(十五)—— 事务
- Kafka 进阶学习(十六)—— 副本