消息队列MQ如何保证高可用性?

保证MQ的高可用性,主要是解决MQ的缺点--系统复杂性变高--带来的问题

主要说一下  rabbitMQ  和  kafka  的高可用性

 

一、rabbitMQ的高可用性

rabbitMQ是基于主从做高可用性的,主要有三种模式:单机模式(不推荐)、普通集群模式(不推荐)、镜像集群模式(推荐)

1、单机模式:demo级别,本地启动,个人练习使用的,生产环境一般不用

2、普通集群模式:

      

    多台机器上启动多个rabbitMQ实例,但是你创建的queue元数据+实际数据)只会放在一个rabbitMQ实例 A 上,其他实例都会同步queue的元数据(元数据可以理解为queue的位置、信息,便于其他实例拉取数据的)。如果消费者消费信息的时候,实际连接的是另一个实例 B ,那个B会根据元数据去到A上拉取数据过来。

  缺点是:没做到所谓的分布式,就是个普通集群。

      消费者每次随机连接一个实例拉取数据(增加了拉取数据的开销),

      要么就是消费者固定连接到那个queue所在的实例消费数据(导致单实例性能瓶颈)。

      若A宕机了(丢失数据),则其他实例无法拉取数据。即使开启了消息持久化,让rabbitMQ落地存储消息,消息不一定会丢,得等A恢复了才能继续拉取数据。

总结:并没有高可用性可言。该方案主要是提高吞吐量,让集群中多个节点来服务某个queue的读写操作

3、镜像集群模式:rabbitMQ的高可用实现

      

  创建一个queue(元数据+实际数据),无论是queue的元数据还是消息,都存在于多个实例上。每次写消息到queue时,都会自动把消息同步到多个实例的queue里。

  好处是不担心宕机,因为所有实例的数据都是一样的。

  坏处是(1)性能开销大,消息同步所有机器导致网络带宽压力和消耗很重

   (2)无扩展性可言,若某queue负载很重,你再加机器,新增的机器也包含了这个queue的所有数据,并没有办法线性拓展你的queue(非分布式的

另:如何开启镜像集群模式?rabbitMQ管理控制台上新增一个镜像集群模式的策略,指定的时候可以要求数据同步到所有节点,也可以要求同步到指定数量的节点,然后在创建queue时应用这个策略,就会自动将数据同步到其他节点上。

 

二、kafka 的高可用性

分布式消息队列

架构认识: 由多个broker组成,每个broker是一个节点。你创建一个topic,这个topic可以划分成多个partition,每个partition可以存在于不同的broker上,每个partition就放一部分数据。也就是说一个topic的数据,是分散放在多个机器上的,每个机器就放一部分数据。

  kafka0.8之前是没有HA模式的(high access),就是replica副本机制

  每个partition的数据都会同步到其他机器上,形成自己的多个replica副本,所有replica会选举出一个leader出来,那么生产者和消费者都是跟这个leader打交道,其他replica就是follower。

  写的时候,leader会负责把数据同步到所有follower上去,读的时候直接读leader上数据即可。

  高可用性在于:kafka会均匀的将一个partition的所有replica分布在不同的机器上,提高容错性。若某个broker宕机了,刚好其上有某个partition的leader,那么此时kafka会自动重新选举出一个新leader,继续读写那个新leader即可。

  如何保证所有follower数据跟leader一样?写数据的时候,生产者就是leader,将数据落地写入本地磁盘,接着其他follower主动从leader来拉数据。一旦所有follower同步好数据,会发送ack给leader,leader收到所有follower的ack后,会返回写成功的消息给生产者。

  消费的时候,只会从leader读,但是只有一个消息已经被所有follower都同步成功返回ack的时候,这个消息才会被读到,即leader和所有follower上都有了这个消息。

posted on 2020-02-25 22:09  黑子菜园  阅读(1326)  评论(0编辑  收藏  举报

导航