RabbitMQ和Kafka到底怎么选(二)?

前言

前一篇文章《RabbitMQ和Kafka到底怎么选?》,咱们在吞吐量方面比较了Kafka和RabbitMQ,知道了Kafka的吞吐量要高于RabbitMQ。本文从可靠性方面继续探讨两个队列的差别。html

RabbitMQ可靠性

咱们经过前文知道,RabbitMQ的队列分为master queue和mirror queue,mirror queue 在master queue宕机以后,会被提高为master queue,以下图所示。 队列A的consumer在消费的时候,机器宕机,此时客户端和服务端分别作以下动做:安全

  • 服务端:把mirror queue提高为master queue
  • 客户端:链接到新的master queue 所在的节点进行消费或者生产

当master queue 所在节点宕机后,其正在被消费的消息的相关信息所有丢失,即服务端不知道消费者对那一瞬间消费的消息是否进行了ACK,因此在mirror queue被提高为master queue时,会把宕机前正在进行消费的的消息所有从新发送一遍,即客户端重连后,消息可能被重复消费,这个时候就必须依靠应用层逻辑来判断来避免重复消费。分布式

在持久化方面,RabbitMQ的master queue每次收到新消息后,都会马上写入磁盘,并把消息同步给mirror queue。假设在master queue 收到消息后,消息未同步到mirror queue 以前master queue 宕机,则此时mirror queue中就没有刚刚master queue收到的那条消息,当这个mirror queue被提高为master queue时,消费者链接到新的master queue上进行消费时就丢了一条消息。因此,RabbitMQ也会丢消息,只不过这个丢消息的几率很是低。性能

Kafka可靠性

咱们知道Kafka中的每一个队列叫作Topic,一个Topic有多个主分片和副分片,当主分片所在机器宕机后,服务端会把一个副分片提高为主分片,以下图所示。 spa

服务端和客户端会有以下动做:操作系统

  • 服务端:把副分片提高为主分片
  • 客户端:链接到新的主分片

Kafka一样有主从同步,因此也一定存在与RabbitMQ一样丢消息的问题。可是Kafka的每一个客户端保存了读取消息的偏移信息,故当一个主分片宕机后,Kafka客户端能够从副分片相应位移后继续消费,不会有重复消费的状况。日志

持久化方面,Kafka默认把消息直接写文件,可是因为操做系统的cache缘由,消息可能不会立马写到磁盘上,这个时候就须要刷新文件到磁盘。因为刷新文件到磁盘是一个比较耗时的操做,故Kafka提供了两种不一样的刷新配置:code

#每接收多少条消息刷一下磁盘
log.flush.interval.messages=10000
#每隔多少ms刷一下磁盘
log.flush.interval.ms=1000

咱们彻底能够把log.flush.interval.messages设置为1,这样Kafka就能在持久化方面达到和RabbitMQ一样的安全级别。htm

可是Kafka集群依赖ZK,如上图所示,因此对于Kafka稳定性的评估必须考虑ZK集群的稳定性,而通常咱们认为任何分布式集群的稳定性都小于1,故两个集群的串联稳定性会降低一些,维护更复杂一些,这点没有RabbitMQ有优点。blog

总结

其实好多开源组件随着时间推移,每每都进行了各类改进。就好比Kafka虽然是为了日志而生,给人第一印象是容易丢消息,可是通过这么多年的改进,其可靠性可能并不逊色RabbitMQ了,只须要你根据不一样的业务场景配置不一样的配置参数,便可达到适合本身的安全级别。

  • 从吞吐量上看,在不要求消息顺序状况下,Kafka完胜;在要求消息前后顺序的场景,性能应该稍逊RabbitMQ(此时Kafka的分片数只能为1)。
  • 从稳定性来看,RabbitMQ胜出,可是Kafka也并不逊色多少。

好了,以上就是个人我的分析,多有不足,但愿能和小伙伴进行探讨。

相关文章
相关标签/搜索