研磨消息中间件Kafka之保证消息不丢失
本文是“研磨Kafka”系列较为重要的一篇,我将在本文中重点讲解Kafka是通过何种手段达到消息不丢失的目的。
Kafka通过ISR机制保证了消息发送的可靠性。
首先介绍下什么是ISR。
ISR
ISR,即:in-sync replica,中文含义为:与leader 副本保持同步的副本集合。
我们在之前的文章中已经介绍过Kafka的副本机制,如:单个分区可配置多个副本。
在Kafka中,分区下维护了一个replica集合,集合中所有副本保存的日志都和leader 副本保持着同步状态。
只有该集合中的replica才能被选举为leader,当该集合中所有的副本都收到了同一条消息,Kafka才会将该消息状态设置为“已提交”状态,对客户端而言就是消息发送成功了。
Kafka保证,在分区下的replica集合中,只要存在至少一个replica,则状态为 “已提交” 的消息就不会丢失。
这里我们要记住两个要点:
- ISR 中存在至少一个可用的replica
- 消息状态为– 已提交
我们常常会听到一种论调,“Kafka会丢消息”。
这种言论其实是没有理解Kafka对消息可靠性保证的范围,Kafka并非对任意消息都保证可靠提交,它只保证在ISR存活的条件下,对“已提交”消息是不会丢失的,而对于未提交成功的消息,Kafka不做可靠性保证。
通常情况下,分区内所有的replica(也包括leader replica),都与leader replica保持着同步,如果出现一部分replica开始落后于leader replica的进度,当落后进度达到一定阈值,则Kafka会将
这些replica “踢出” ISR。反之,当这些落后的replica重新追上了leader的进度,则Kafka会将他们重新加入到ISR中。这个过程完全是自动的,不需要人工干预。既保证了消息交付可靠性语义,同时还
减少了用户的操作成本。
那么Kafka具体是如何配置ISR从而达到消息可靠存储的目的呢?
我们主要关注新版的Kafka,在0.9.0.0版本之后,Kafka不再通过replica.lag.max.messages参数,而是改成了唯一参数—replica.lag.time.max.ms 来进行检测,它的含义是:follower副本落后
leader副本的时间间隔,参数的默认值为10s。
对于“请求速度追不上”的情况,Kafka采用了新的检测机制–如果一个follower副本落后leader副本的时间超过了该参数,则认为该follower副本是不同步的,这样做的目的是:避免由于短时间内出现瞬时峰值,而导致follower反应进出ISR,从而保证了集群的稳定性和吞吐量。
参考资料:
《Apache Kafka实战》