从集群角度拆解RabbitMQ的架构设计与实现

298 阅读3分钟

集群构建

集群构建由节点发现和元数据存储两部分组成。

  • 固定配置发现:是指通过在 RabbitMQ 的配置文件中配置集群中所有节点的信息,从而发现集群所有节点的方式。和 ZooKeeper 的节点发现机制是一个思路。
  • 类广播机制发现:是指通过 DNS 本身的机制解析出所有可用 IP 列表,从而发现集群中的所有节点。和 Elasticsearch 通过多播来动态发现集群节点是类似的思路。
  • 第三方组件发现:是指通过多种第三方组件发现集群中的所有节点信息,比如 AWS(EC2)、Kubernetes、Consul、etcd 等。和 Kafka、Pulsar 依赖 ZooKeeper,RocketMQ 依赖 NameServer 是一个思路。
  • 手动管理:是 RabbitMQ 比较特殊的实现方式,是指通过命令 rabbitmqctlctl 工具往集群中手动添加或移除节点。即依赖人工来管理集群,这种方式使用起来不太方便,其他消息队列很少采用这个方案。

RabbitMQ 的元数据是通过内置数据库 Mnesia 来存储的。

数据可靠性

RabbitMQ 集群维度数据可靠性的核心是副本和数据一致性协议,RabbitMQ 的数据可靠性是由镜像队列和仲裁队列来保证的。

镜像队列

在 RabbitMQ 中,镜像队列是一个独立的功能。它通过为 Queue 创建副本、完成主从副本之间数据同步、维护主从副本之间数据的一致性等 3 个手段来保证数据的可靠性。

RabbitMQ 的镜像队列是通过内核中的 GM 模块将数据分发到从副本,从而完成主从副本之间的数据同步。GM 模块能保证组播数据的原子性,即保证数据要么能发送到所有模块上,要么不能。

从性能上来看,这个强一致的策略也是影响性能的一个重要原因。所以,3.8.0 以后,RabbitMQ 用仲裁队列替代了镜像队列来解决这些问题。

仲裁队列

仲裁队列是基于 Raft 算法来设计的,依赖 Raft 共识协议来确保数据的一致性和可靠性。

仲裁队列是主从模型,至少得有三个副本。通过主副本和多个从副本之间的数据同步,来实现数据的高可靠。队列会选举出主副本来实现数据的读写,当主副本不可用,会根据算法从副本中选举出新的主副本。

和镜像队列不同的是:当副本挂掉重新启动时,只需要从主节点同步增量数据,并且不会影响主副本的可用性,从而避免了镜像队列的缺点。

安全控制

RabbitMQ 内置了对 TLS 的支持,通过 TLS 来实现数据的加密传输。

当客户端连接到 RabbitMQ Broker 时,必须先进行身份认证,才能进行后续的操作。

RabbitMQ 的鉴权分为管理页面和数据流两个方面。


此文章为11月Day23学习笔记,内容来源于极客时间《深入拆解消息队列 47 讲》