特点
- 可靠性特征:
- 分区消息顺序。同一个分区中先写入的消息会被消费者先读到。
- 消息被写入分区所有同步副本,才被认为已提交。
- 只要有一个副本活跃,已提交消息就不会丢失。
- 消费者只能读取已提交的消息。
- 核心:复制+分区多副本。
- kafka配置需要在两点之间权衡:
- 消息存储的可靠性、一致性。
- 可用性、高吞吐、低延时、硬件成本
- 保证消息至少被消费一次。生产者、消费者均有可能使消息重复。
broker
复制系数
- 分区副本数两个级别:
- 主题级别:replication.factor
- broker级别:default.replication.factor。
- 可丢消息设为1,要求可用性设为>=3。
首领选举
- CA权衡。是否允许不同步的副本成为首领。
- 3个副本,两个不可用或不同步,首领也不可用。
- 不完全的首领选举:unclean.leader.election,默认true。
最少同步副本
- CA权衡。至少存在n个同步副本才能向分区中写数据。
- min.insync.replicas。
生产者
发送确认
- acks模式:
- 0。生产者发出之后,无需broker响应。
- 追求吞吐量。
- 1。首领副本broker将消息写到操作系统page cache,响应客户端。之后异步刷到磁盘。
- 可能丢数据。
- kafka不支持同步刷盘,可减小异步刷盘间隔降低丢数据风险。
- -1(all)。所有同步副本复制消息之后,首领副本响应客户端。
- 追求一致性。
- 0。生产者发出之后,无需broker响应。
- acks时间消耗。
- acks=0,总耗时 f(t)=f(1)。
- acks=1,总耗时 f(t)=f(1)+f(2)。
- acks=-1,总耗时 f(t)=f(1)+max( f(A) , f(B) )+f(2)。
发送重试
- 效果:每条消息至少被保存一次。如果需要只一次,需要消费方根据唯一键幂等性。
额外错误处理
- 可自定义错误处理器。
消费者
初始位移
- auto.offset.reset。无可提交偏移量(第一次启动)或偏移量不存在时消费者的操作。
- earliest。从分区开始读数据,大量重复消息,保证最少丢失。
- latest。从分区末尾开读数据,减少重复,错过更多消息。
提交时机
- enable.auto.commit。是否自动提交poll到的消息,默认5s一次。
- 自动提交前宕机,处理较多重复消息。
- 对于后台线程处理的消息,可能提交未完成消息。
- auto.commit.interval.ms。自动提交间隔,每隔n ms提交poll到的最大位移。
- 较大。重复消息概率大。
- 较小。增加提交开销
手动提交注意点
- 处理完之后提交,保证至少一次消费,否则丢消息。
- 可通过分区再平衡监听器再平衡前提交偏移量。
- 消费者重试时的两种做法。
- 可用pause暂停拉取消息,resume恢复。
- 放入独立的重试topic。
- poll间隔时间过久,但是心跳正常,消费者会被提出消费组。
- 手动提交参考。
心跳
- 0.10.1之前:poll方法发出。相关参数:
- fetch.max.wait.ms:消费者等待broker的最长时间,默认500ms。超过该时间或者一定数据量,poll方法则返回
- session.timeout.ms:认为消费者挂掉的时间,默认3s。超过该时间没有心跳,触发再平衡。
老版本kafka处理消息的耗时尽可能要短,否则会持续rebalance导致消息堆积
- 0.10.1之后:单独的心跳线程发出。