博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何保证Kafka的可靠性、幂等性和有序性
阅读量:3762 次
发布时间:2019-05-22

本文共 1888 字,大约阅读时间需要 6 分钟。

之前的项目中由于用到了Kafka,所以在前一阵的实习面试中被问到了如何保证Kafka消息的有序性,所以本文对于Kafka这三个常被问到的问题进行总结归纳。

可靠性

对于消息队列而言,如果不能保证消息的可靠性可能会引起重大的生产事故。如果我们在超市里买完东西用手机进行支付,这条支付的消息存进了Kafka,但是因为某些原因导致消息丢失,商家没有收到钱,而我们却已经显示扣费,这是绝对不能容忍的,所以消息队列的可靠性至关重要。

对于可靠性的保障,主要需要从生产者、Broker和消费者三个角度来进行实现,我们先简单介绍一下。

Kafka是基于发布订阅模型的消息队列,主要包括生产者、Broker和消费者三个部分。生产者在Kakfa模型中负责生产消息,并将生产的消息发送到Broker中进行存储,消费者从Broker中拉取订阅的消息进行消费。如下图所示:

从上图我们可以得知Kafka可能出现消息丢失的三个地方就是生产者、Broker和消费者。下面我们分别介绍三种情况。

保证生产者的消息可靠性

从本质上来说,生产者与Broker之间是通过网络进行通讯的,因此保障生产者的消息可靠性就必须要保证网络可靠性,这里Kafka使用acks=all可以设置Broker收到消息并同步到所有从节点后给生产者一个确认消息。如果生产者没有收到确认消息就会多次重复向Broker发送消息,保证在生产者与Broker之间的消息可靠性。

保证Broker的消息可靠性

在Broker收到了生产者的消息后,也有可能会丢失消息,最常见的情况是消息到达某个Broker后服务器就宕机了。这里需要补充说明一下Kafka的高可用性,直观的看,Kafka一般可被分成多个Broker节点,而为了增加Kafka的吞吐量,一个topic通常被分为多个partition,每个partition分布在不同的Broker上。如果一个partition丢失就会导致topic内容的部分丢失,因此partition往往需要多个副本,以此来保证高可用。

如上图所示,一个topic被分成三个partition,每个partition又进行复制,假如此时Broker1挂了,在Broker2和Broker3上依然有完整的三个partition。此时只需要重新选举出partition的leader即可。这里还是需要强调一下,一定要将leader上的数据同步到follower上才能给生产者返回消息,否则可能造成消息丢失。

保证消费者的消息可靠性

这里比较容易发生消息丢失的情况是,消费者从Broker把消息拉过来,如果这个时候还没有消费完,消费者就挂了并且消费者自动提交了offset,那么此时就丢失了一条消息。所以解决办法就是关闭自动提交offset,等真正消费成功之后再手动提交offset。

幂等性

保证消息的幂等性,其实就是保证消息不会被重复消费。幂等性的保证需要根据具体业务具体分析,比如向MySQL插入一条订单信息,可以根据订单id查询数据库中是否已经存在该信息进行去重。如果是类似于Redis的设置key值,Redis天然支持消息的幂等性,所以这种情况下是不需要关心消息的幂等性的。总之,对于幂等性的保证完全可以根据业务需求进行具体分析。

有序性

消息队列在某些场景下需要严格保证消息被消费的顺序,想象一个场景,你看到你的男朋友在朋友圈晒别的女生的照片,于是你在下面评论了一句:“渣男”,然后把他的微信删了。这时候如果这两条消息的消费顺序是反过来的,也就是先删除微信,然后进行评论,那么是无法评论的。

前面说到可靠性的时候我们提到了Kafka的topic是由多个partition组成的,那么我们可以用一种最极端的方式保证消息有序性,一个topic只设置一个partition。这里的问题就是如果一个topic只对应一个partition,那么这个吞吐量肯定就大幅下降了,这就违背了Kafka的设计初衷。

还有一种方法是比较推荐的,由于不同partition之间是不能保证有序性的,因此保证消息在同一个partition中是保证消息有序性的关键,除了前面说的那种极端解决方案,其实还可以在发送消息时,指定一个partition,或者指定一个key,因为同一个key的消息可以保证只发送到同一个partition,这里的key一般可以用类似userid的属性来表示。在上面的场景来看就是妹子的userid先是进行了评论操作,又进行了删除好友的操作,这两个操作由于是同一个key值,因此被发往同一个partition中。

转载地址:http://jicpn.baihongyu.com/

你可能感兴趣的文章
计组期末复习题(3)
查看>>
计组期末复习题(4)
查看>>
计组期末复习题(5)
查看>>
计组期末开卷资料
查看>>
计组期末复习题获取
查看>>
c++(STL中一些常用操作)
查看>>
php(环境搭建)
查看>>
php(变量)
查看>>
php(单双引号的区别)
查看>>
php(数据类型)
查看>>
php(运算符及流程控制)
查看>>
php(自定义函数与系统自带函数)
查看>>
php(从一个文件中调用另一个文件的变量)
查看>>
php(数组及相关操作)
查看>>
php(about error and time)
查看>>
利用php对数据库进行操作
查看>>
二叉树及其(前中后)序遍历
查看>>
2020.8.29 ssdh
查看>>
javascript--DOM事件流
查看>>
安卓实训项目报告:基于存储卡音乐播放器V0.3
查看>>