不可靠的KAFKA
这里的不可靠是指代KAFKA其设计之初就为高性能而设计,其是允许消息丢失的,但经过多个版本的升级之后,通过KAFKA的相关配置,我们可以将其作为可靠的队列(不丢消息的队列)。
在本文里,不会具体列出要改哪个参数,需要改的参数请大家自行翻文档找出来,这样理解会更为深刻。
发送消息到KAFKA时产生的消息丢失
在一些比较旧的版本,KAFKA客户端发送消息到KAFKA服务器时,由于客户端不等待服务器回应,直接返回,等待发送异步进行。因此其在发送环节就可能存在消息丢失。
为了避免消息丢失,我们需要用新版客户端,并配置客户端发送消息时同步等待返回结果
KAFKA服务器宕机导致的消息丢失(磁盘缓存丢失)
KAFKA自身不管理LOG写入磁盘的缓存,将其交由操作系统处理。因此在默认配置下,如果KAFKA宕机,则会因为数据没有FLUSH到磁盘而丢失数据。
为了保证数据不丢失,KAFKA提供的现成方法有两个,
-
每条消息都Flush一次; 每条都Flush一遍,必然不可行,因为其速度会变得很慢。官方也不建议这么做。(如果其有类似Group Commit的优化机制的话,我觉得可以使用,但是貌似曾经有人提过这个PR,没有被采纳,其认为用集群就可解决这个可靠性问题)
-
构建集群,以提高可用性。 官方推荐的方法。只要挂的机器不要超过强制写入的机器,那么就可以保证数据不丢失。但需要注意的是,KAFKA组成的集群必须在不同机房。不然机房一断电,集群内的KAFKA就会出现消息丢失。
KAFKA复制模式导致的丢失
KAFKA的副本模式为主备复制模式,这个模式下有两种形式 同步复制模式 以及 异步复制模式。
异步复制模式: 客户端将信息发送到主副本,主副本收到信息写到本地缓存后即返回ACK给客户端。然后异步地将数据发送给备份。本配置为默认配置,其高效,但主挂掉,则消息丢失。 同步复制模式: 客户端将信息发送到主副本,主副本收到信息,写到本地缓存,并发送给所有从机,从机都写到缓存后给主机反馈,主机都收到反馈后再反馈给客户端
需要修改复制模式为同步复制
KAFKA选举导致的消息丢失
KAFKA有一个配置,是否允许在不得已的情况下,允许在非同步状态下的副本成为主副本。其默认是打开的,结果就导致存在丢失消息的可能性。需要将其关闭
未被确认的消息不会被消费
KAFKA使用主从同步复制的时候,没有被完全复制(完全复制的消息会在HW(High water Mark之下))的信息不会被消费。 一个Broker若需要从非ISR状态进入到ISR状态前,会将其在HW之前的消息记录给truncate掉,并尝试跟上Master里的记录。跟上后,将会恢复ISR状态。
KAFKA的主节点选举通过ZK中登记的序号决定,更细节可查看KAFKA同步复制模式选举过程,以上为默认实现,不需修改,也无法修改
已确认的消息如果存在ISR状态的副本的话,就不会丢失记录
原Master挂掉后,新选出的Master不会丢弃HW之后的消息,新Master会将这些HW之后的副本再次发送给其余的副本。因此即使高水位信息没有传递给新的Master副本也没有问题。
ISR分区过少导致失去容灾特性
默认配置下,ISR分区个数可以为1时依然可以写数据。但当出现这种情况的时候,就失去了容灾性。只要主分区挂掉,那么数据就丢失。
KAFKA有配置可以指定写入时最少的ISR数量,少于特定值,就不再ACK。如一共三台BROKER,我们可以指定ISR最少数量为2,那么只有1台处于ISR状态的话,COMMIT将无法执行。
是否设置该值,视具体情况而定,若无法容忍丢失,则设置该值为2,NAME 。追求可用性,则不设置。
个人建议设置为2,无论副本数量有多少
KAFKA如何处理网络分区情况?
如果MASTER与其他的副本与ZK是联通的,但是MASTER与其他副本之间出现了网络分区,那么ISR就只能为1。
消息保存的策略的设置
建议保留消息的策略基于时间。如保留21天
客户端宕机导致的消费位置丢失
KAFKA在分区中的消费位置由客户端管控,其有可能没有及时保存到KAFKA中,导致消费位置丢失。 若消费位置丢失,则消费可能从上一个保存的消费位置重新进行消费。所以在不能接受重复消息的系统需要自行定制对于消息的幂等处理
(死信是否会丢失?)
At Least Once
实际上我们对可靠消息系统的要求通常是At least Once,经过上述配置已经基本达到了At Least Once的要求
消息消费失败的重试设置
需要设计一个死信队列,消费失败的消息需放入里面,以免影响后续其他消息消费
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于