kafka如何保证数据不重不漏,无乱序

消息丢失和消息重复,从生产端和消费端来考虑

如何保证消息有序

  • 消费端重复消费:建立去重表
  • 消费端丢失数据:关闭自动提交offset,处理完后再手动提交移位
由于在使用kafka的高级API时,消费者会自动每隔一段时间将offset保存到zookeeper上,此时如果刚好将偏移量提交到zookeeper上后,但这条数据还没消费完,机器发生宕机,此时数据就丢失了。
解决方法:关闭自动提交,改成手动提交,每次数据处理完后,再提交。
auto.commit.enable=true
  • 生产端重复发送:这个没关系,消费端去重处理就行
  • 生产端丢失消息:

1.异步方式缓冲区满了,就阻塞到那,等到缓冲区可用,不能情况缓存区
2.发送消息后回调函数,发送成功一条就发下一条,发送失败就记录到日志,等着定时脚本来扫描。

  • 保证信息有序:

1.同步发送模式:发出消息后,必须阻塞等待收到通知后,才发送下一条消息
2.异步发送模式:一直往缓冲区写,然后一把写到队列中去

ack:
ack确认机制设置为0,表示不等待响应,不等待borker的确认信息,最小延迟,producer无法知道消息是否发生成功,消息可能丢失,但具有最大吞吐量。

ack确认机制设置为-1,也就是让消息写入leader和所有的副本,ISR列表中的所有replica都返回确认消息。

ack确认机制设置为1,leader已经接收了数据的确认信息,replica异步拉取消息,比较折中。

ack确认机制设置为2,表示producer写partition leader和其他一个follower成功的时候,broker就返回成功,无论其他的partition follower是否写成功。

ack确认机制设置为 "all" 即所有副本都同步到数据时send方法才返回, 以此来完全判断数据是否发送成功, 理论上来讲数据不会丢失。

min.insync.replicas=1  意思是至少有1个replica返回成功,否则product异常

如果想要高吞吐量就得容忍偶尔的消息发送失败(比如重发漏发无顺序)

block.on.buffer.full = true
acks = all
retries = MAX_VALUE
max.in.flight.requests.per.connection = 1
使用KafkaProducer.send(record, callback)
callback逻辑中显式关闭producer:close(0) 
unclean.leader.election.enable=false
replication.factor = 3 
min.insync.replicas = 2
replication.factor > min.insync.replicas
enable.auto.commit=false

消息处理完成之后再提交位移

顺序写磁盘,性能高,不丢数据

  • ACK机制

kafka采用的至少一次(AT Least Once),消息不会丢失,但是会重复传输

  • 复制机制
  • 消息删除机制

默认会删除大于7天的数据,这个参数可以设置

  • 发送消息
    发送消息

为了更好的性能,kafka支持在生产者一侧进行本地buffer,也就是累计到一定消息条数才发送,这样会造成丢失消息。生产者端设置
producer.type=async 默认是sync
设置成async会最大程度的提高性能,原理:生产者会在本地缓存消息,适时批量发送。
如果对可靠性要求高,可以设置为sync 同步发送。

  • 消息可靠

如果更注重消息可靠性,就要手动提交offset,也就是当前业务都处理完成的时候,再提交offset,这样会导致重复消费,需要提供幂等性接口。
所谓幂等性,指的是系统A对系统B的接口进行多次调用所产生的结果和调用一次所产生的结果是一致的。

你可能感兴趣的:(大数据/架构)