MQ----保证MQ的可用性

保证MQ的可用性

文章引用地址:
感谢前辈分享
https://github.com/doocs/advanced-java/blob/master/docs/high-concurrency/how-to-ensure-high-availability-of-message-queues.md
https://blog.csdn.net/Box_clf/article/details/84076012

在"MQ-----为什么要使用MQ,优点和缺点呢"文中提到,在系统中加入MQ会存在很多风险:
系统复杂性提高
MQ挂掉了怎么保证可用性
MQ怎么保障消息不重复的消费,怎么保证消息不丢失,怎么保证消息的顺序性,
怎么保证MQ中的消息被其他系统全部完成的一致性问题

RabbitMMQ的可用性
RabbitMQ是基于主从做高可用的,RabbitMQ有三种模式。单机模式,普通集群模式,镜像集群模式
单机模式就不说了,单机模式就是玩玩demo的,没有人生产的时候使用单机
普通集群模式
普通集群模式就是说在多个机器上面启动多个RabbitMQ实例,每个机器上面启动一个,而我们创建的queue,只会存放在一个机器的RabbitMQ实例上,其他的实例会同步我们创建的queue的元数据,这里的元数据就是queue的一些配置信息,通过元数据我们能够找到queue所在的RabbitMQ实例,我们消费的时候如果链接到了另外的一个实例,那么那个实例会从queue所在的实例上拉去数据过来
MQ----保证MQ的可用性_第1张图片
在这个时候MQ集群内部可能存在大量的数据传输,如果queue所在的Rabbit实例挂掉了,那么数据就全部丢失了,没有可用性的保证,并且拉去数据带来了很多开销,影响性能。这种方案主要是提高吞吐量的,让集群的多个节点来服务某个queue的读写操作

镜像集群模式
镜像集群模式,我们创建的queue,不光是queue的元数据还有queue的数据都会保存在每一个RabbitMQ实例上,每个RabbitMQ都是一个完整的镜像,包含queue的全部数据。每次写消息到queue上的时候,都会自动把消息同步到多个RabbitMQ实例的queue上
MQ----保证MQ的可用性_第2张图片
镜像集群模式保证了RabbitMQ的可用性,怎么开启镜像集群模式,RabbitMQ有很好的管理控制台,在后台新增一个策略,这个错略就是集群模式的策略,指定的时候可以要求数据同步到所有的节点上,也可以要求同步到指定的节点上,再此创建queue的时候就会应用这个策略,按照后台新增的策略将数据进行同步,镜像集群方式的好处是任何一个机器挂了之后其他机器还有queue的完整数据。但是,再MQ集群内部需要将消息queue的全部信息同步到所有的机器上,导致网络带宽压力和消耗很大。如果queue中的负载很重,我们加机器进行扩展的话,新增的机器中将会包含这个queue中的全部信息,没有办法线性扩展我们的queue,,如果这个 queue 的数据量很大,大到这个机器上的容量无法容纳了,此时该怎么办呢?(可以设置时间,如果超过了这个时间没有被消费就将这个消息删除,或者是将消息持久话在本地)

Kafka的可用性
kafka的结构是,由多个broker组成,每一个broker是一个节点,创建一个topic之后,这个topic被划分成多个partition,每一个partition可以保存在不同的broker上
这就是分布式消息队列,一个topic数据被分散在多个机器上,每台机器上面保存一部分数据。是没有 可用性机制的,就是说任何一个 broker 宕机了,那个 broker 上的partition 就废了,没法写也没法读,没有什么高可用性可言。比如说,我们假设创建了一个 topic,指定其 partition 数量是 3 个,分别在三台机器上。但是,如果第二台机器宕机了,会导致这个 topic 的 1/3 的数据就丢了,因此这个是做不到高可用的,后来kafka提供了可用性机制,就是复制品副本机制,每个 partition 的数据都会同步到其它机器上,形成自己的多个 replica 副本,注意是自己的partition的多个副本。所有 replica 会选举一个 leader 出来,那么生产和消费都跟这个 leader 打交道,然后其他 replica 就是 follower。写的时候,leader 会负责把数据同步到所有 follower 上去,读的时候就直接读 leader 上的数据即可。为什么只能读写 leader,因为如果我们可以随意读写每个 follower,那么就要关心数据的一致性问题,系统复杂度太高,容易出问题。Kafka 会均匀地将一个 partition 的所有 replica 分布在不同的机器上,这样才可以提高容错性。

这样,就有所谓的高可用性了,因为如果某个 broker 宕机了这个 broker上面的 partition 在其他机器上都有副本的,如果宕机的这个broker上面有某个 partition 的 leader,就会会从 follower 中重新选举一个新的 leader 出来,大家继续读写那个新的 leader 即可。写数据的时候,生产者就写 leader,然后 leader 将数据落地写本地磁盘,接着其他 follower 自己主动从 leader 来 pull 数据。一旦所有 follower 同步好数据了,就会发送 ack 给 leader,leader 收到所有 follower 的 ack 之后,就会返回写成功的消息给生产者。(当然,这只是其中一种模式,我们还可以调整这种模式)
消费的时候,只会从 leader 去读,但是只有当一个消息已经被所有 follower 都同步成功返回 ack 的时候,这个消息才会被消费者读到。

你可能感兴趣的:(MQ----保证MQ的可用性)