为什么Kafka不支持读写分离

在Kafka中,生产者写入消息、消费者读取消息的操作,都是通过和分区的leader副本进行交互的,这是一种主写主读的生产消费模型,并不支持主写从读。原因如下:

  • 数据一致性问题:数据从主节点转到从节点会有一个延时的时间窗口,导致主从节点的数据不一致。
  • 延时问题:类似Redis这种组件的数据存在内存,而Kafka的数据存在磁盘,主从同步会更加耗时,对于延时敏感的应用不适用。
  • 主写从读对于写很少而读很多的情况,可以均摊负载压力。但对于Kafka,每个broker上的读写负载都是一样的,数据写压力很大,主写从读只能分摊很少的负载压力。

Kafka的可靠性

Kafka有如下几个方面配置决定了可靠性:

复制系数

分区的多副本数可以保证数据可靠性,可以在创建主题时配置,也可以在后期修改。越多的副本数可靠性越高,但是副本数太多会引起磁盘、网络带宽的浪费,造成性能下降。一般而言副本数为2能够满足绝大多数场景对可靠性的要求,部分银行会设置为5。同时分配分区副本时引入基架信息(broker.rack参数),也能防止机架整体宕机的风险。

生产者客户端参数acks

acks = -1( 等同于all)时,leader副本在写入本地日志,并且等待所有ISR集合的副本成功写入日志后,才会告知生产者成功提交,最大程度提高消息的可靠性,但性能最差。

acks = 1时,leader副本在写入本地日志之后就会告知生产者已成功提交,若ISR集合的副本没来得及拉取新写入的消息leader副本宕机,此次发送的消息就会丢失。

ack = 0时,生产者把消息发送出去后就认为消息已经成功写入Kafka,性能最好但可靠性最差。

刷盘策略

broker端可以通过设置刷盘策略为同步刷盘,增强数据可靠性,但会对性能造成很大影响。应当使用默认配置,将刷盘策略交由操作系统本身来处理。

发生重复消费的场景

  1. 分区再均衡。消费者在消费消息的时候,还未处理完,这时候如果发生了分区再均衡,消费组将不可用,消费者偏移量未提交,完成再均衡后重新消费消息。
  2. 消费者消费完消息再提交偏移量,若中间宕机,则重启后再次拉取已消费未提交的消息。
  3. 消费者设置了自动提交,在关闭时可能会有部分偏移量未提交,重启后重复消费。
  4. 生产者宕机,重启后可能重发数据。

发生消息丢失的场景

  1. 消费者拉取数据后,先提交偏移量再消费,若中间宕机,则重启后从新的偏移量开始拉取,前面有部分消息没来得及处理。
  2. 生产者acks不是-1,可能有发送不成功或只发给leader副本但该副本宕机的风险,造成消息未实际保存至日志。