kafka replication副本
- 所谓副本,通产指分布式系统中不同机器中保存相同的数据拷贝,本质就是一个只能追加写消息的提交日志
- 提供数据冗余。即使系统部分组件失效,系统依然能够继续运转,因而增加了整体可用性以及数据持久性。
- 提供高伸缩性。支持横向扩展,能够通过增加机器的方式来提升读性能,进而提高读操作吞吐量。
- 改善数据局部性。允许将数据放入与用户地理位置相近的地方,从而降低系统延时。
假如kafka一个主题有3个分区3个副本部署在三台Broker上,在实际生产环境中,每台 Broker 都可能保存有各个主题下不同分区的不同副本,因此,单个 Broker 上存有成百上千个副本的现象是非常正常的。
关键性问题:如何保证副本中的数据是一致的?
kafka采用了常见的解决方案:基于领导者(Leader-based)的副本机制
这样做的优缺点:
- 没能提供读操作横向扩展以及改善局部性。
- 方面实现立即读Read-your-writes,写完就能读到
- 方面实现单调读Monotonic Reads,同一消费者,多次消费消息,不会看到某条消息一会存在一会儿不存在
kafka同步副本集合In-sync Replicas(ISR)
如何定义同步,追随者副本到底在什么条件下才算与 Leader 同步。kafka引入了同步副本ISR集合,ISR 中的副本都是与 Leader 同步的副本,凡是在ISR集合中的副本都认为是同步的。
上图中哪些follower副本是同步的,kafka it depends,视情况而定,不一定是严格的相同
- Broker参数replica.lag.time.max.ms ,默认10秒钟
- 如果一个follower在这个时间内没有发送fetch请求或消费leader日志到结束的offset,leader将从ISR中移除这个follower,并认为这个follower已经挂了
倘若该副本后面慢慢地追上了 Leader 的进度,那么它是能够重新被加回 ISR 的。这也表明,ISR 是一个动态调整的集合,而非静态不变的。
如果ISR为空该如何选举
因为 Leader 副本天然就在 ISR 中,如果 ISR 为空了,就说明 Leader 副本也挂掉了,此时该怎么选举新 Leader 。
Kafka 把所有不在 ISR 中的存活副本都称为非同步副本。通常来说,非同步副本落后 Leader 太多,如果选择这些副本作为新 Leader,就可能出现数据丢失的情况。在 Kafka 中,选举这种副本的过程称为 Unclean 领导者选举。
Broker 端参数 unclean.leader.election.enable 控制是否允许 Unclean 领导者选举。
如果想保证数据的一致性,禁用Unclean。
一个分布式系统通常只能同时满足一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)中的两个。显然,在这个问题上,Kafka 赋予你选择 C 或 A 的权利。
ISR副本同步机制
与 Leader 副本保持同步的条件有两个:
1.该远程 Follower 副本在 ISR 中。
2.该远程 Follower 副本 LEO 值落后于 Leader 副本 LEO 值的时间,不超过 Broker 端参数 replica.lag.time.max.ms 的值。如果使用默认值的话,就是不超过 10 秒。
- Committed Message:已提交消息,已经被所有ISR同步的消息。
- Lagging Message:未提交消息,没有达到所有ISR同步的消息。
- Hight Watermark:副本高水位值,表示分区中最新一条已提交(Committed)的消息的Offset。位移值等于高水位的消息也属于未提交消息。也就是说,高水位上的消息是不能被消费者消费的。
- LEO:Log End Offset,Leader中最新消息的Offset,它表示副本写入下一条消息的位移值。
- 高水位和 LEO 是副本对象的两个重要属性。Kafka 所有副本都有对应的高水位和 LEO 值,而不仅仅是 Leader 副本。只不过 Leader 副本比较特殊,Kafka 使用 Leader 副本的高水位来定义所在分区的高水位。换句话说,分区的高水位就是其 Leader 副本的高水位。
kafka高水位更新机制
Kafka 所有副本都有对应的高水位和 LEO 值,在 Leader 副本所在的 Broker 上,还保存了其他 Follower 副本的 LEO 值。
leader副本更新HW和LEO流程:
1.处理生产者请求的逻辑如下:
- 获取 Leader 副本所在 Broker 端保存的所有远程副本 LEO 值{LEO-1,LEO-2,……,LEO-n}。
获取 Leader 副本高水位值:currentHW。 - 更新 currentHW = min(currentHW, LEO-1,LEO-2,……,LEO-n)。
- 写入消息到本地磁盘。
- 更新分区高水位值。
2.处理 Follower 副本拉取消息的逻辑如下:
- 读取磁盘(或页缓存)中的消息数据。
- 使用 Follower 副本发送请求中的位移值更新远程副本 LEO 值。
- 更新分区高水位值(具体步骤与处理生产者请求的步骤相同)
Follower 副本更新HW和LEO流程
从 Leader 拉取消息的处理逻辑如下: a.获取 Leader 发送的高水位值:currentHW。 b.获取步骤 2 中更新过的 LEO 值:currentLEO。 c.更新高水位为 min(currentHW, currentLEO)。 c1.写入消息到本地磁盘。 c2. 更新 LEO 值。 c3.更新高水位值。
下一节预告
- kafka副本同步机制Leader Epoch
推荐阅读
- 深入浅出kafka原理-1-初识只作乍见之欢
- 深入浅出kafka原理-2-Kafka为何那么快(高效)
- 深入浅出kafka原理-3-高效文件存储设计特点