如何配置 KAFKA 使其消息不会丢失

本贴最后更新于 2702 天前,其中的信息可能已经渤澥桑田

不可靠的KAFKA

这里的不可靠是指代KAFKA其设计之初就为高性能而设计,其是允许消息丢失的,但经过多个版本的升级之后,通过KAFKA的相关配置,我们可以将其作为可靠的队列(不丢消息的队列)。

在本文里,不会具体列出要改哪个参数,需要改的参数请大家自行翻文档找出来,这样理解会更为深刻。

发送消息到KAFKA时产生的消息丢失

在一些比较旧的版本,KAFKA客户端发送消息到KAFKA服务器时,由于客户端不等待服务器回应,直接返回,等待发送异步进行。因此其在发送环节就可能存在消息丢失。

为了避免消息丢失,我们需要用新版客户端,并配置客户端发送消息时同步等待返回结果

KAFKA服务器宕机导致的消息丢失(磁盘缓存丢失)

KAFKA自身不管理LOG写入磁盘的缓存,将其交由操作系统处理。因此在默认配置下,如果KAFKA宕机,则会因为数据没有FLUSH到磁盘而丢失数据。

为了保证数据不丢失,KAFKA提供的现成方法有两个,

  1. 每条消息都Flush一次; 每条都Flush一遍,必然不可行,因为其速度会变得很慢。官方也不建议这么做。(如果其有类似Group Commit的优化机制的话,我觉得可以使用,但是貌似曾经有人提过这个PR,没有被采纳,其认为用集群就可解决这个可靠性问题)

  2. 构建集群,以提高可用性。 官方推荐的方法。只要挂的机器不要超过强制写入的机器,那么就可以保证数据不丢失。但需要注意的是,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的要求

消息消费失败的重试设置

需要设计一个死信队列,消费失败的消息需放入里面,以免影响后续其他消息消费

参考

https://kafka.apache.org/documentation/#replication

  • Kafka

    Kafka 是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是现代系统中许多功能的基础。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。

    36 引用 • 35 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...