本文从高可用的角度观察一下RabbitMQ、Kafka、RocketMQ,看看它们各自的实现思路。
1.RabbitMQ
RabbitMQ有3种部署模式:
单机模式普通集群模式镜像集群模式单机模式与高可用完全没关系,咱就不说了,直接看看这2种集群模式。
1.1普通集群模式
某一个Queue是在集群中的某一个Broker上,各个Broker会同步元数据,但不会同步Queue的消息数据。
如果某一个Broker故障了,其中的Queue便无法使用。如果消息没有配置消息持久化,则消息丢失。
可以看到,这种方式并没有实现高可用,只是扩展性比较好,扩充Broker可以容纳更多的Queue,提高吞吐量。
1.2镜像集群模式
一个Broker中Queue的元数据和消息数据都会同步到其他Broker上,就是做了全量备份,所以称为“镜像模式”。
实现了高可用,如果一个Broker故障了,没关系,可以使用其他Broker继续工作,消息数据不会丢失。
可用性上去了,但扩展性没有了。
一个Queue的数据是全量存在Broker中的,所以Queue的消息容量、消息处理能力,都受限于Broker。
普通集群模式没有达到高可用,扩展性较好。
镜像集群模式实现了高可用,但扩展性差。
2.Kafka
Kafka把Topic(主题/队列)分为了多个Partition(分区),Topic只是逻辑概念,Partition才是实际的消息存储单元。
一个Topic的多个Partition分散在多个Broker中,每个Partition存放Topic的一部分数据。
有了Partition之后,Topic就具有了极强的扩展性,可以指定N个Partition。
可以为Partition指定多个“副本”,分散在不同的Broker,从而实现其高可用。
当某个Broker故障的时候,其中存放的Partition不可用,但没有关系,可以使用其他Broker上的副本。
Partition的多个副本分为两种角色,Leader和Follower。
Leader是由Kafka选举出来的,负责处理消息的读写。Leader收到新消息后,会同步给Follower。
Follower的作用是候选人,当Leader出事儿之后,Kafka会从Follower中选举出新的Leader。
可以配置消息写入完成的标准:
写入Leader既可--速度快,但可能会有消息丢失,例如在同步到Follower之前Broker故障了,则消息丢失。Follower同步完成之后才算写入成功--消息可靠性极高,但影响写入速度。3.RocketMQ
这是RocketMQ的官方结构图,左右是Producer和Consumer,中间是RocketMQ,分为两个部分:
NameServer集群--存放元数据Broker集群--存放队列数据这两部分都需要保证高可用。
NameServer是独立运行的,保存着集群完整的集群元数据,例如路由信息、Broker信息、数据信息。
为了保证其高可用,可以运行多个NameServer,之间完整的同步数据即可。
这样只要有一个NameServer是可用的,就不会影响集群的正常工作。
Broker集群的部署方式可以分为3种。
多Master
部署多个Broker,角色都是Master,Topic的数据会分散存储在这些Broker中。
单个Master故障会导致其中数据无法使用,需要等待修复。
如果想保障数据的可靠性,可以使用机制。
多Master多Slave
为Master配置了Slave,Master会把数据同步到Slave。
当Master故障之后,可以用Slave顶上去,数据和服务都不影响,但会有短暂的停顿,需要修改配置并重启才能完成切换动作。
数据同步的方式分为:
1)异步--Master写入完成即可,异步同步给Slave。写入速度快,但同步会有延迟,可能会丢数据。
2)同步--Master与Slave都写入之后才算成功。不会丢消息,但写入速度降低。
DledgerGroup
Dledger模式要求为Master配置2个Slave,3者组成一个DledgerGroup。
Dledger也是Master-Slave同步的方式,好处在于可以实现自动选举Master,自动切换。
当Master故障的时候,RocketMQ可以从组内选出一个新的Master,完成自动切换,这样更进一步提高了集群的可用性。
最后小结一下。
最后说一句,作者整理了最新完整面试题及答案,有很多干货,包含mysql,netty,spring,线程,springcloud、JVM、源码、算法等详细讲解,详细的学习规划图等学习资料,需要的私信我:Java
(求