kafka可靠传输、不重复消费、高可用
一. 如何保证消息的可靠传输
数据丢失分两种:mq自身丢失数据;消费环节丢失数据
1、kafka自身丢失数据
问题场景:kafka某个broker宕机,然后重新选举partiton的leader时
解决方案:
① 给这个topic设置replication.factor参数:这个值必须大于1,要求每个partition必须有至少2个副本
② 在kafka服务端设置min.insync.replicas参数:这个值必须大于1,这个是要求一个leader至少感知到有至少一个follower还跟自己保持联系,没掉队,这样才能确保leader挂了还有一个follower吧
③ 在producer端设置acks=all:这个是要求每条数据,必须是写入所有replica之后,才能认为是写成功了
④ 在producer端设置retries=MAX(很大很大很大的一个值,无限次重试的意思):这个是要求一旦写入失败,就无限重试,卡在这里了
综上:在生产环节发生故障,可以保证数据不丢失
2、消费环节丢失
问题场景:已经拉取到消息,在未处理完毕之前提交了offset到kafka服务,但是消费者在处理的时候出现异常,导致数据丢失
解决方案:
① 更改关闭offset自动提交方案,待数据处理完毕后再行提交offset
② 获取消息后,做简单的消息查重,然后放入到业务队列中,在另一个队列中消费
关于acks参数
此参数是在生产者端设置,包含0、1、all三种状态
① acks=0:生产者客户端,只要把消息发送出去,无论是否在kafkakakfa服务磁盘,都默认为发送成功
可能出现问题:topic所在partition leader并未接收成功,或,leader-follower同步失败
② acks=1:topic所在partition leader接收到消息,并成功写入磁盘,就人为成功,而不用关心follower是否同步成功
③ acks=all:Partition Leader接收到消息之后,还必须要求ISR列表里跟Leader保持同步的那些Follower都要把消息同步过去,才能认为这条消息是写入成功了
acks=all可以保证数据不丢失吗?
不,如果只有一个Partition副本,即Leader=partition,此时的acks=all是无用的,因为ISR里就一个Leader,他接收完消息后宕机,也会导致数据丢失。
所以说,这个acks=all,必须跟ISR列表里至少有2个以上的副本配合使用,起码是有一个Leader和一个Follower才可以。这样才能保证说写一条数据过去,一定是2个以上的副本都收到了才算是成功,此时任何一个副本宕机,不会导致数据丢失
二. Kafka保证消息不会被重复消费
1、Kafka本身幂等机制
kafka有个offset的概念,就是每个消息写进去,都有一个offset,代表他的序号,然后consumer消费了数据之后,每隔一段时间,会把自己消费过的消息的offset提交一下,代表我已经消费过了,下次我要是重启啥的,你就让我继续从上次消费到的offset来继续消费吧
2、业务方保证幂等
① 比如你拿个数据要写库,你先根据主键查一下,如果这数据都有了,你就别插入了,update一下好吧
② 在消息里面添加一个全局唯一id,在消费环节,对id进行校验,如果已经消费过,就直接过滤
③ 基于数据库的唯一键来保证重复数据不会重复插入多条,在功能上线环节,重启系统就可能会产生重复,因为kafka消费者还没来得及提交offset,重复数据拿到了以后我们插入的时候,因为有唯一键约束了,所以重复数据只会插入报错,不会导致数据库中出现脏数据
三. Kafka实现高可用
kafka具有天然的分布式队列特征,是有多个broker组成的集群,每个broker是一个节点,消息的传递是以topic为标识,创建一个topic,这个topic可以划分为多个partition,每个partition可以存在于不同的broker上,每个partition就放一部分数据。可以理解为一个topic的数据,是分散放在多个机器上的,每个机器就放一部分数据
kafka 0.8以后,提供了HA机制,就是replica副本机制。每个partition的数据都会同步到吉他机器上,形成自己的多个replica副本。然后所有replica会选举一个leader出来,那么生产和消费都跟这个leader打交道,然后其他replica就是follower。写的时候,leader会负责把数据同步到所有follower上去,读的时候就直接读leader上数据即可
Kafka的读写都会有一个leader,如果可以随意读写每个follower,那么就要care数据一致性的问题,系统复杂度太高,很容易出问题。kafka会均匀的将一个partition的所有replica分布在不同的机器上,这样才可以提高容错性
Kafka的集群制,partition分片,leader选举机制,确保了当某个broker宕机,不会出现数据丢失服务不可用的情况。达到高可用的目标