简介
kafka提供了多副本机制,实现了容灾能力,提升可用性和可靠性。副本分为两类,一类是leader副本,另一类是follower副本,每个分区创建时都需要选举一个leader副本,没有选上leader副本的都是follower副本。
follower副本不对外提供服务,它唯一的任务就是异步的从leader副本拉取消息,写入自己的日志,保持和leader副本的同步。
当leader故障时,可以从符合条件的follower副本中重新选举leader副本。
既然follower副本是异步拉取消息进行同步的,那就可能存在和leader副本不能实时同步的风险。所以,kafka就引入了ISR概念,ISR中的副本就认为是和leader副本保持同步的副本,重新选举leader副本时,默认需要从ISR中选举。
ISR
那如何判断一个follower副本是否处于ISR集合中呢?kafka根据follower副本落后leader副本最长时间间隔来判定的,这个对应broker端的replica.lag.time.max.ms参数,默认是10秒。只要是follower副本落后leader副本的时间在10秒内,则就认为该follower副本和leader副本是同步的。
当follower副本落后时间达到10秒后,kafka会收缩ISR集合,把该follower副本移除。当该follower副本追上leader进度后,也可以被重新加回ISR。
其实之前kafka还有一个replica.lag.max.messages参数来判定ISR,当follower副本滞后的消息数超过这个值的设定时,就认为该副本处于失效状态。不过这个参数很难设定,因为实际使用过程中,有的topic消息量很少,有的topic消息量很多,而且参数是broker级别的,对所有的topic都生效,很难设置一个通用的值。所以kafka后来就把这个参数废弃了。
副本还分为本地副本和远程副本。本地副本是指对应的Log分配在当前的broker节点上,远程副本是指对应的Log分配在其他的broker节点上。
acks
生产者客户端有个acks参数,用来指定分区中必须要有多少个副本收到这条消息,才会认为该消息写入成功。acks有三个取值,1,0,-1。
acks默认值为1,表示只要leader副本写入成功,就认为是成功。这个也是kafka默认的设置。