消息队列RabbitMQ和Kafka

RabbitMQ和Kafka

转自通九大神的博客

起因

最近公司RabbitMQ的集群出了点问题,然后有些亲就说RabbitMQ慢且不好用,是一个瓶颈,不如换成Kafka。而我本人,使用RabbitMQ有一点久了,认为这个事情应当辩证的去看。所以就在没事的时候简单的看了看RabbitMQ的代码。但是我并没有看太多Kafka的代码,我只简单提下。 
关于Kafka

根据Kafka官方的文档,Kafka可以被认为一个高大上的集群消息中间件,但是读了下以前一个朋友给的部署文档和Kafka的官方的文档。发现Kafka确实不错,真的可以说是集群消息中间件。

用topic来进行消息管理,每个topic包含多个part,每个part对应一个逻辑log,有多个segment组成。

segment中的消息id由其逻辑位置决定,可以用消息id直接定位到消息的存储位置,避免id到位置的额外映射。

生产者发到某个topic的消息会被均匀的分布到多个part上,broker收到消息会写入最后的segment文件中,当某个segment上的消息条数达到配置值或消息发布时间超过阈值时,segment上的消息会被flush到磁盘,只有flush到磁盘上的消息消费者才能收到。并且通过rolling的机制,保证segment的文件不至于过大。

消费者可以rewind back到任意位置重新进行消费,当消费者故障时,可以选择最小的offset进行重新读取消费消息。

是不是看起来很爽,但是深入往下看,发现了一些深坑(下面是单机来说的)

Kafka对消息的重复、丢失、错误以及顺序型没有严格的要求。但是part只会被consumer group内的一个consumer消费,故kafka保证每个parti内的消息会被顺序的消费。

broker没有副本机制,一旦broker宕机,该broker的消息将都不可用。同时broker是无状态的,broker不保存消费者的状态,由消费者自己保存。无状态导也致消息的删除成为难题,所以Kafka选择消息保存一定时间后会被删除。

大量的依赖Zookeeper,需要Zookeeper来管理broker与consumer的动态加入与离开。以及消费关系及每个partion的消费信息。

看到这里,你如果还明白我说这些深坑是什么意思,那就请带入运维场景和特定故障场景思考下。我稍后会说一下这些坑会带来什么问题。 
关于RabbitMQ

RabbitMQ是使用Erlang开发的一个消息队列,可以构建成集群,也可以单独使用。

根据测试,RabbitMQ在不使用ACK机制的,Msg大小为1K的情况下,QPS可达6W+。再双方ACK机制,Msg大小为1K的情况下,QPS瞬间降到了1W+。从某种意义上RabbitMQ还真是慢,但是我们需要思考下。

我们真的每个消息都能到1K吗?

我们真的需要双方都对消息ACK的系统吗?

好了,如果两个回答都是YES,那么RabbitMQ就是慢的。如果是No,那么RabbitMQ还是一个非常快的队列。

RabbitMQ慢有几个原因:

RabbitMQ做为一个Broker,不单单做到了简单的数据转发功能,还保证了单个队列上的数据有序,即便是有多个消费者和多个生产者。

RabbitMQ的策略是实时转发,而不像Kafka那样等待刷盘之后才让消费者来消费。

如果消费者和生产者不对等,会产生大量的磁盘IO操作,进行消息换出。

RabbitMQ为什么不好用:

扫描二维码关注公众号,回复: 2336521 查看本文章
AMQP协议本身比较复杂,参数比较多。

Erlang写的,很多人不熟悉,并且Mnesia出现问题好多人解决不了。

RabbitMQ和Kafka相比没价值了吗?

很多亲们读到这里,就会想RabbitMQ好像也不怎么样呀。和Kafka相比没什么价值可言了,但是我前面说了一些Kafka的坑,我就在这里面揭示一下。

Kafka大量依赖Zookeeper,它的broker并不保存任何状态,如果Zookeeper集群不幸悲剧了,那么整个Kafka集群的消息就全完蛋了。

上面问题有人会说这概率好小,我也同样认为这个概率很小,那么一个broker当机呢?当一个broker当机了整个消息队列由于负载均衡的算法,在一瞬间消费者和生产者之间的消息就全乱掉了。很多需要保证消息顺序的系统一下子就完蛋了。

这就是RabbitMQ存在的价值和意义,同时RabbitMQ使用了MirrorQueue的机制,也可以做到多个机器进行热备。 
RabbitMQ该怎么用

RabbitMQ的消息应当尽可能的小,并且只用来处理实时且要高可靠性的消息。

消费者和生产者的能力尽量对等,否则消息堆积会严重影响RabbitMQ的性能。

集群部署,使用热备,保证消息的可靠性。

Kafka该怎么用

应当有一个非常好的运维监控系统,不单单要监控Kafka本身,还要监控Zookeeper。

对消息顺序不依赖,且不是那么实时的系统。

对消息丢失并不那么敏感的系统。

1、在应用场景上:

RabbitMQ,遵循AMQP协议,由内在高并发的erlanng语言开发,用在实时的对可靠性要求比较高的消息传递上。

kafka是jms的订阅者模式,它主要用于处理活跃的流式数据,大数据量的数据处理上。(高的吞吐量,高效率)

1)在架构模型方面,

RabbitMQ遵循AMQP协议,RabbitMQ的broker由Exchange,Binding,queue组成,其中exchange和binding组成了消息的路由键;客户端Producer通过连接channel和server进行通信,Consumer从queue获取消息进行消费(长连接,queue有消息会推送到consumer端,consumer循环从输入流读取数据)。rabbitMQ以broker为中心;有消息的确认机制。

kafka遵从一般的MQ结构,producer,broker,consumer,以consumer为中心,消息的消费信息保存的客户端consumer上,consumer根据消费的点,从broker上批量pull数据;无消息确认机制。

2)在吞吐量

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

rabbitMQ在吞吐量方面稍逊于kafka,他们的出发点不一样,rabbitMQ支持对消息的可靠的传递,支持事务,不支持批量的操作;基于存储的可靠性的要求存储可以采用内存或者硬盘。

3)在可用性方面

rabbitMQ支持miror的queue,主queue失效,miror queue接管。

kafka的broker支持主备模式。

4)在集群负载均衡方面

kafka采用zookeeper对集群中的broker、consumer进行管理,可以注册topic到zookeeper上;通过zookeeper的协调机制,producer保存对应topic的broker信息,可以随机或者轮询发送到broker上;并且producer可以基于语义指定分片,消息发送到broker的某分片上。

rabbitMQ的负载均衡需要单独的loadbalancer进行支持。

猜你喜欢

转载自blog.csdn.net/wojiao228925661/article/details/81165249