如何保证消息队列的高可用的?
RabbitMQ的高可用
RabbitMQ 是比较有代表性的,因为是基于主从(非分布式)做高可用性的,我们就以 RabbitMQ 为例子讲解第一种 MQ 的高可用性怎么实现。
RabbitMQ 有三种模式**:单机模式、普通集群模式、镜像集群模式。**
单机模式:
单机模式,就是Demo等级的,一般就是你本地启动了玩玩儿的????,没人生产用单机模式
普通集群模式:
普通模式,就是在多台机器上启动多个RabbitMQ实例,每个机器启动一个。我们创建的queue,只会放在一个RabbitMQ实例上,但是每个实例都会同步queue的元数据(元数据可以认为是queue的一些配置信息,通过元数据,找到queue所在的实例中)。假如系统消费的时候,实际上连到另外一个实例,那么这个实例会从queue所在实例上拉取数据过来。这方案主要是提高吞吐量的,就是让多个节点来服务某个queue的读写操作。
镜像集群模式:
镜像集群模式,跟普通的模式不一样的,在重叠模式下,我们创建的队列,无论元数据还是队列的消息都会存在与多个实例上,就是说,每个RabbitMQ队列都有这个队列的一个完整的副本,包含queue的全部数据。每次将消息写到queue的时候,都会自动把消息同步到多个实例的队列上。
如何开启这个它的镜像就是集群模式呢?
其实很简单,RabbitMQ的有很好的管理控制台,就是在后台新增一个策略,策略这个的英文它的镜像就是集群模式的策略,指定的时候是可以要求数据同步到所有节点的,也可以要求同步到指定数量的路由器,再次创建队列的时候,应用这个策略,就会自动将数据同步到其他的例程上去了。
好处在于:
你任何一个机器停机机了其他机器(计数器)还包含了这个队列的完整数据,别的consumer都可以到其他上游上去消费数据。
坏处在于:
不是分布的,就没有扩展性可言了,如果某个队列负载,性能增量也太大了吧,消息需要同步到所有机器上,导致网络带宽压力和消耗很重!很重,你加机器,补充的机器也包含了这个队列的所有数据,并没有办法线性扩展你的队列。你想,如果这个队列的数据量很大,大到这个机器上的容量无法容纳了。
Kafka的高可用
Kafka基本的架构:
kafka是由多个broker组成,每个broker是一个节点;创建 一个topic可以划分为 多个partition,每个partition可以存在于不同的broker上,每个partition就放一部分数据。天然的分布式消息队列,就是分散放在多个机器上的,每个机器就放一部分数据。
Kafka 0.8 以后,提供了机制,就是replica(复制品)副本机制。每个partition的数据都会同步到其他的机器上,形成自己的多个replica副本。**所有replica会选举一个leader出来,那么生产何消费都和这个leader打交道,然后其他的replica就是follower。**写的时候,leader回负责把数据同步到follower上去,读取的时候直接读取leader上的数据即可。如果某个broker宕机了,这个broker上面的partition在其他机器上都有副本的如果某个partition的leader,那么会从follower中重新选举一个新的leader出来,消费 者继续读取这个leader即可,这就是 所谓的高可用性。
写数据的时候,生产者将数据写入到leader中,然后leader将数据落到本地磁盘中,接着其他的follower自己主动从leader来pull数据。一旦所有的follwer同步好数据了,就会发送ack给leader,leader接收到所有follower的ack之后,就会返回写成功的消息给生产者。
消费的时候,只会从Leader去读,但是只有当一个消息已经被所有follower都同步成功返回ack的时候,这个消息才会被消费者读到。