kafka和rabbit区别

118 阅读6分钟

rabbitmq

基础概念
Exchange:交换机,接收消息,根据路由键转发消息到绑定的队列。它指定消息按什么规则,路由到哪个队列。

Binding:Exchange和Queue之间的虚拟连接,binding中可以包含routing key。用于消息队列和交换器之间的关联。一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则,所以可以将交换器理解成一个由绑定构成的路由表。它的作用就是把exchange和queue按照路由规则绑定起来。

Routing key:一个路由规则,虚拟机可用它来确定如何路由一个特定消息。exchange根据这个关键字进行消息投递。

Queue:也称为Message Queue,消息队列,用来保存消息直到发送给消费者。它是消息的容器,也是消息的终点。一个消息可投入一个或多个队列。消息一直在队列里面,等待消费者连接到这个队列将其取走。

简单

img

img

工作

交换机

img

img

路由

主题

img

6.工作模式总结

​ 这五种工作模式,可以归为三类:

  1. 生产者,消息队列,一个消费者;
  2. 生产者,消息队列,多个消费者;
  3. 生产者,交换机,多个消息队列,多个消费者;
7、四种交换器

  1、direct 如果路由键完全匹配的话,消息才会被投放到相应的队列。  

  2、fanout 当发送一条消息到fanout交换器上时,它会把消息投放到所有附加在此交换器上的队列。

  3、topic 设置模糊的绑定方式,“*”操作符将“.”视为分隔符,匹配单个字符;“#”操作符没有分块的概念,它将任意“.”均视为关键字的匹配部分,能够匹配多个字符。

4、header 交换器允许匹配 AMQP 消息的 header 而非路由键,除此之外,header 交换器和 direct 交换器完全一致,但是性能却差很多,因此基本上不会用到该交换器

如何保证消息不被重复消费?

保证消息不被重复消费的关键是保证消息队列的幂等性,这个问题针对业务场景来答分以下几点:

1.比如,你拿到这个消息做数据库的insert操作。那就容易了,给这个消息做一个唯一主键,那么就算出现重复消费的情况,就会导致主键冲突,避免数据库出现脏数据。

2.再比如,你拿到这个消息做redis的set的操作,那就容易了,不用解决,因为你无论set几次结果都是一样的,set操作本来就算幂等操作。

3.如果上面两种情况还不行,上大招。准备一个第三方介质,来做消费记录。以redis为例,给消息分配一个全局id,只要消费过该消息,将<id,message>以K-V形式写入redis。那消费者开始消费前,先去redis中查询有没消费记录即可

1生产者丢数据

生产者的消息没有投递到MQ中怎么办?从生产者弄丢数据这个角度来看,RabbitMQ提供transaction和confirm模式来确保生产者不丢消息。

2.消息队列丢数据

处理消息队列丢数据的情况,一般是开启持久化磁盘的配置。这个持久化配置可以和confirm机制配合使用,你可以在消息持久化磁盘后,再给生产者发送一个Ack信号。这样,如果消息持久化磁盘之前,rabbitMQ阵亡了,那么生产者收不到Ack信号,生产者会自动重发。

3.消费者丢数据

启用手动确认模式可以解决这个问题

所以一般来说,如果你要确保说写 RabbitMQ 的消息别丢,可以开启 confirm 模式,在生产者那里设置开启 confirm 模式之后,你每次写的消息都会分配一个唯一的 id,然后如果写入了 RabbitMQ 中,RabbitMQ 会给你回传一个 ack 消息,告诉你说这个消息 ok 了。如果 RabbitMQ 没能处理这个消息,会回调你的一个 nack 接口,告诉你这个消息接收失败,你可以重试。而且你可以结合这个机制自己在内存里维护每个消息 id 的状态,如果超过一定时间还没接收到这个消息的回调,那么你可以重发。

或者生产端与消费端开启定时任务去比对

Kafka

图片.png broker

顾名思义,集群中的一台机器,节点

zk

节点需要注册进去zk管理node,portition

consumer-group

消费组,多个消费者

consumer

消费者,当然也有生产者,组

topic

生产者发送到topic,消费者再去消费

partition

分区,各种中间件都有分区,这里就不解释,由topic决定保留在哪个分区,portition之间无法保证消费顺序

leader

分区的领导者

flowwer

副本,用于冗余数据,保证高可用

生产者消息丢失

Kafka消息发送有两种方式:同步(sync)和异步(async),默认是同步方式,可通过producer.type属性进行配置

0—不进行确认

1—表示当Leader接收成功时确认,其实还用最低水位的用于同步,这个时候会有数据丢失,(应用层处理)

-1—表示Leader和Follower都接收成功时确认(最稳妥)

消费者消息丢失

消息丢失:

同步模式下,确认机制设置为-1,即让消息写入Leader和Follower之后再确认消息发送成功

消费者:(offset手动提交,业务逻辑成功处理后,提交offset)

异步模式下,为防止缓冲区满,可以在配置文件设置不限制阻塞超时时间,当缓冲区满时让生产者一直处于阻塞状态

消息重复:将消息的唯一标识保存到外部介质中,每次消费时判断是否处理过即可。

应用场景

rabbitMQ支持对消息的可靠的传递,支持事务,不支持批量的操作;基于存储的可靠性的要求存储可以采用内存或者硬盘。金融场景中经常使用

kafka具有高的吞吐量,内部采用消息的批量处理,zero-copy机制,数据的存储和获取是本地磁盘顺序批量操作,具有O(1)的复杂度(与分区上的存储大小无关),消息处理的效率很高。(大数据)