持续创作,加速成长!这是我参与「掘金日新计划 · 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
会写入成功: