Kafka如何保证消息不丢失
Kafka如何保证消息不丢失
在生产者到Kafka再到消费者这个过程中,每个环节都有可能造成数据丢失,需要针对这些情况分别处理。
生产者
生产者向Kafka发送消息的时候,出现网络波动就会造成消息无法打到Kafka。
acks参数
我们可以调整生产者的acks配置,该参数指定了必须要有多少个分区收到消息,生产者才会认为写入是成功的。
-
acks=0生产者写入消息之前不会等待Kafka的响应,出了问题生产者无法知道,但是吞吐量最大。
-
acks=1只要集群的首节点收到消息,Kafka即响应成功。
-
acks=all只有当所有参与复制的节点全部收到消息,Kafka才会进行响应,这种方式最安全,但是延迟最高。
要避免消息丢失,最好此参数设置为all。
retries参数
生产者发送失败有时候可能是临时性的错误,例如分区找不到首领,可以通过设置参数retries,表示生产端的重试次数,所以在代码逻辑中,没必要再写重试逻辑。
retry.backoff.ms参数
生产者获取通知可以采用get()同步阻塞的方法,也可以采用增加回调的方法进行持久化到本地等处理。
服务端
服务器也会造成消息丢失,例如某个分区的节点挂掉,那么针对这种情况,我们就需要设置备份:
replication.factor参数
复制系数,即每个分区会被复制几次,默认的复制系数为3(建议)。
min.insync.replicas参数
最小同步副本,尽管一个主题配置了3个副本,开启了acks=all参数,还是会出现只有一个同步副本的情况,例如当两个副本挂了的时候,这个时候,就只有一个副本,它复制成功了,也满足了acks=all,那么这个副本如果变成不可用时,数据就会丢失,所以在三个副本的情况下,min.insync.replicas可以设置为2,至少要存在两个同步副本才能向分区写入数据。
unclean.leader.election.enable参数
有时候由于网络问题,导致两个副本复制消息滞后,这个时候如果首领变成不可用的,那么两个副本就是不同步的,unclean.leader.election.enable=true,即允许这两个不同步的副本参与选举,那么就会出现消息丢失的情况(滞后的偏移量被重写了),如果该参数设置为false,则要接受较低的可用性。
如果消息较为重要(例如银行),那么该参数需要设置为false,即时不可用,也不能出现数据丢失的情况。
消费者
group.id参数
多个消费者group.id不要重复,不然每个消费者只会读到部分消息。
enable.auto.reset参数
该参数指定了请求的偏移量在服务端不存在的时候,消费者行为,该参数有两种配置:
-
earliest消费者从最开始的位置开始消费,导致大量的重复数据,但是数据不会丢失。
-
latest从分区的末尾开始读取,可以减少重复,但是会导致错过一些消息。
enable.auto.commit参数
自动提交可能会在消费者没有处理完毕就提交偏移量(默认5秒提交一次,可以通过auto.commit.interval.ms设置),导致消息没有消费,所以设置为false,改为手动提交的方式,在处理完事件后再提交偏移量。
这样也会导致重复消费问题,例如,消费者处理完成后就挂了,那么下次再消费的时候,就会带来重复消费问题。
重复消费问题
Kafka在0.11.0版本后,每条消息都有唯一的message id, MQ服务采用空间换时间方式,自动对重复消息过滤处理,保证接口的幂等性,即使这样依然无法解决上面提到的消费者挂了等问题。
所以需要消费者自己做幂等处理,每次拉到消息后,在Redis中存储数据标识,下次拉到消息后,进行校验。
还可以使用事务,把消息的处理和偏移量的提交放在一个事务中。
References
评论 (0)
登录后即可发表评论
