持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情
一、前言
光靠多副本机制不能保证
Kafka高可用。 举个栗子:
leader节点宕机,但leader上的数据还没同步到follower上- 此时即使选举了新的
leader,但那个期间的数据已经丢失
ISR(In-sync replica) :跟 leader partition 保持同步的 follower partition 数量,只有处于 ISR 列表中的 follower 才可以在 leader 宕机之后被选举为新的 leader,因为在这个 ISR 列表里代表他的数据跟 leader 同步的。
一些概念:
AR(Assigned Repllicas)一个partition的所有副本(就是replica,不区分leader或follower)ISR(In-Sync Replicas) 能够和Leader保持同步的follower + leader本身 组成的集合。OSR(Out-Sync Relipcas)不能和Leader保持同步的follower集合
如果要保证写入 Kafka 数据不丢失:
- 首先需要保证
ISR中至少有一个follower - 一条数据写入
leader partition之后,要求复制给ISR中所有的follower partition,才能代表这条数据已提交
这里就不得不提 Producer 的一个重要的参数:acks
acks=0:不需要等待服务器的确认. 这是retries设置无效. 响应里来自服务端的offset总是-1,producer只管发不管发送成功与否。延迟低,容易丢失数据。acks=1:表示leader写入成功(但是并没有刷新到磁盘)后即向producer响应。延迟中等,一旦leader副本挂了,就会丢失数据。acks=all:等待数据完成副本的复制, 等同于-1. 假如需要保证消息不丢失, 需要使用该设置. 同时需要设置unclean.leader.election.enable为true, 保证当ISR列表为空时, 选择其他存活的副本作为新的leader.
当使用 acks=all 时,还需要搭配一个参数 min.insync.replicas。
举个栗子:broker 副本数为 3、最小同步数为2 (min.insync.replicas=2)
producer设置acks=all,发送消息- 此时,
Broker 3宕机 - 根据
min.insync.replicas=2, 此消息不会在broker中写入 - 并且会返回
NoEnoughReplicasException异常
此时有 2 个副本,acks=all 写入成功:
此时只有 1个副本,
acks=all 写入失败,但 acks=0 1 会写入成功: