Kafka的日志复制机制

代码星冰乐

专注成就未来

首页 归档 关于

Kafka的日志复制机制

Jan 14, 2021 | haifeiWu | Java | 阅读
文章目录
  1. 1. 保证数据一致性的方式
    1. 1.1. 多数复制
    2. 1.2. 主从复制
  2. 2. 几个概念
  3. 3. Kafka的ISR模型
  4. 4. 数据一致性与服务可用性的权衡
  5. 5. 参考文档

作 者:haifeiWu
原文链接:https://www.hchstudio.cn/article/2021/7cba/
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。


由于版权原因,请阅读原文 --> Kafka的日志复制机制

关注我们

作 者:haifeiWu
原文链接:https://www.hchstudio.cn/article/2021/7cba/
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。

作 者:haifeiWu
原文链接:https://www.hchstudio.cn/article/2021/7cba/
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。

Kafka 是一个分布式的发布-订阅消息系统。它最初是在 LinkedIn 开发的,2011年7月成为一个 Apache 项目。今天,Kafka 被 LinkedIn、 Twitter 和 Square 用于日志聚合、队列、实时监控和事件处理等应用程序。在下面的文章中,我们将讨论下 Kafka 的 replication 设计。

replication 的目的是为了提供服务的高可用, 即使有些节点出现了失败,Producer可以继续发布消息,Consumer可以继续接收消息。

保证数据一致性的方式

有两种典型的方式来保证数据的强一致。这两种方式都要求指定一个leader,所有的写都是发送给leader。leader负责接收所有的写请求,并以相同的顺序将这些写传播给其他follower。

多数复制

基于多数提交的方式。leader 要等到大多数 fellower 接收到数据之后才认为数据是可提交的状态。在 leader 失败的情况下,通过多数 fellower 的协调选出新的 leader 。这种方式的算法有raft、paxos等算法, 比如Zookeeper、 Google Spanner、etcd等。这种方式在有 2n + 1个节点的情况下,最多可以容忍n个节点失败。

主从复制

基于主从复制的方式。需要等 leader 和 fellower 都写入成功才算消息接收成功, 在有n个节点的情况下,最多可以容忍n-1节点失败。

Kafka使用的是主从复制的方式来实现集群之间的日志复制。原因如下:

基于主从复制的方式可以在相同数量的副本中容忍更多故障。 也就是说,它可以容忍带有 n + 1个副本的 n 个故障,而基于多数复制的方式通常只能容忍带有2n +1个副本的n个故障。 例如,如果只有2个副本,则基于多数复制的方式不能容忍任何故障。
Kafka的日志复制主要考虑的是同一个数据中心机器之间的数据复制,相对来说延迟并不会成为日志复制的瓶颈。

几个概念

在 Kafka 中,消息流是由 topic 定义的,topic被划分为一个或多个partition。而复制发生在 partition 级别,每个 partition 都有有一个或多个副本。

topic的逻辑关系

topic的屋里存储关系

在 Kafka 集群中,将副本均匀地分配到不同的服broker上。每个副本都在磁盘上维护一个日志。发布的消息按顺序附加到日志中,每条消息都通过日志中的单调递增offset来标识。
offset 是分区中的逻辑概念。给定一个offset,可以在每个分区副本中标识相同的消息。当 consumer 订阅某个主题时,它会跟踪每个分区中用于消费的偏移量,并使用它向 broker 发出读取请求。

如上图所示当 producer 将消息发布到topic的某个 partition 时,该消息首先被转发到该 partition 的leader副本,并追加到其日志中。fellower 的副本不断地从 leader 那里获取新的信息。一旦有足够多的副本接收到消息,leader 就提交消息。
有个问题就是说 leader 如何决定到什么程度是足够的。leader 不能总是等待所有副本的写操作完成。这样为了保证数据一致性而降低我们服务的可用性是不可行的,这是因为任何跟随者副本可以失败和领导者不能无限地等待。

Kafka的ISR模型

为了解决上面提出的问题,Kafka采用了一种折中的方案,引入了 ISR的概念。ISR是in-sync replicas的简写。ISR的副本保持和leader的同步,当然leader本身也在ISR中。初始状态所有的副本都处于ISR中,当一个消息发送给leader的时候,leader会等待ISR中所有的副本告诉它已经接收了这个消息,如果一个副本失败了,那么它会被移除ISR。下一条消息来的时候,leader就会将消息发送给当前的ISR中节点了。

同时,leader还维护这HW(high watermark),这是一个分区的最后一条消息的offset。HW会持续的将HW发送给fellower,broker可以将它写入到磁盘中以便将来恢复。

当一个失败的副本重启的时候,它首先恢复磁盘中记录的HW,然后将它的消息同步到HW这个offset。这是因为HW之后的消息不保证已经commit。这时它变成了一个fellower, 从HW开始从Leader中同步数据,一旦追上leader,它就可以再加入到ISR中。

kafka使用Zookeeper实现leader选举。如果leader失败,controller会从ISR选出一个新的leader。leader 选举的时候可能会有数据丢失,但是committed的消息保证不会丢失。

故障恢复,leader重新选举的表述~

数据一致性与服务可用性的权衡

为了保证数据的一致性,Kafka提出了ISR,在同步日志到 fellower 的时候为了提高服务的可用性,fellow在将leader同步的日志写入内存后就返回给leader日志写入成功的标志。然后这些操作都是可以通过Kafka的配置来实现的。

参考文档

  • https://kafka.apache.org/documentation/#replication
  • https://colobu.com/2017/11/02/kafka-replication/
  • https://engineering.linkedin.com/kafka/intra-cluster-replication-apache-kafka
  • https://cwiki.apache.org/confluence/display/KAFKA/kafka+Detailed+Replication+Design+V3

关注我们

作 者:haifeiWu
原文链接:https://www.hchstudio.cn/article/2021/7cba/
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。

分享
JavaKafka
从20到21
微信关注我们
分类
  • Android8
  • Go4
  • Java59
  • Kafka,Java1
  • Kotlin2
  • Linux1
  • MapReduce1
  • Python2
  • Raft1
  • Redis1
  • ThreadPoolExecutor1
  • go1
  • 工具1
  • 总结8
  • 旅游日记1
标签
Nginx ChanghuiN haifeiWu Android Java 设计模式 hexo Kotlin 算法 MySQL 源码解析 Python Redis golang web Kafka 配置中心 总结 性能优化 旅游日记 Shell Go 问题排查 译文 Docker Spring Boot 工具 学习笔记 WebFlux 性能测试 go 散列表 源码 netty Raft
最近文章
  • Kafka的日志复制机制
  • 从20到21
  • go 并发编程
  • 【译】了解Linux CPU负载-您何时应该担心?
  • Zookeeper 与分布式锁
  • 基于Redis的分布式锁到底安全吗?
  • 【译】Raft 学生指南
  • ThreadPoolExecutor 的简单梳理
  • MapReduce 的简单实现
  • 使用 Map 实现策略模式
福利专区
    免费SSL证书
      阿里云红包
        腾讯云专属福利
        Copyright © 2021 代码星冰乐. Powered by ChanghuiN. 版权所有 晋ICP备15001365号
        特别感谢: 云服务器服务商 、 CDN 服务商