1.kafka 保证消息不丢失
保证最少一次 ,消息不丢失,可能会重复发送
- producer
- 代码
要使用带回调方法的发送api,消息重试后仍然发送失败先放入磁盘或者远程缓存,后续重发 - 配置
acks=all
retries =3
retry.backoff.ms=300 //重试间隔
2.broker
副本数大于1
min.insync.replicas>1 //isr中的副本大于1,即ISR中最少2个副本,如果小于2个此分区不可用
unclean.leader.election.enable=false //不允许非ISR中的副本选举为leader,防止数据丢失 0.11.0.0之后默认为false
3.消费端
enable.auto.commit=false //收到提交offset ,处理业务逻辑再提交offset, 但是可能出现重复消费
即使这样配置了,Kafka 在极端环境下也并非确保绝对不丢数据: 根据 Kafka 官方文档说明,Producer 发送消息持久化到 Kafka 得到 ack 的回馈这段过程中,基于性能的考虑,Kafka 并没有及时把数据落盘的,而是将数据放到内存(FS cache)中,并周期性的落盘(从磁盘监控也可以看的出来),如果数据未及时落盘,如遇到服务器断电宕机,则数据丢失;
2.kafka 保证消息不重复
kafka 生产的精准一次性(不丢消息也不重复) Exactly Once = At Least Once + 幂等性 PID 只对单个producer有效,如果全局有效需要使用全局ID
Kafka的幂等性实现其实就是将原来下游需要做的去重放在了数据上游。开启幂等性的Producer在初始化的时候会被分配一个PID,发往同一Partition的消息会附带Sequence Number。而Broker端会对<PID, Partition, SeqNumber>做缓存,当具有相同主键的消息提交时,Broker只会持久化一条。 但是PID重启就会变化,同时不同的Partition也具有不同主键,所以幂等性无法保证跨分区跨会话的Exactly Once。
enable.idempotence=true //默认为false 先提交,后处理逻辑,但可能丢失消息。
|