[Erlang 0088] RabbitMQ 集群 Disc Node 一点实现细节

简介:

    刚开始使用rabbitmqctl 创建集群的时候会有一个问题,怎么控制节点是disk node还是ram node?翻看了rabbitmq2.8.7的代码看了一下才知道原委,记录一下:

 

 

先看下面的实验

   这个实验其实之前已经做过了,这里抽出来做对比:

复制代码
[root@localhost scripts]#
[root@localhost scripts]# RABBITMQ_NODE_PORT=9991 RABBITMQ_NODENAME=z_91@zen.com ./rabbitmq-server -detached
Activating RabbitMQ plugins ...
0 plugins activated:

[root@localhost scripts]# RABBITMQ_NODE_PORT=9992 RABBITMQ_NODENAME=z_92@zen.com ./rabbitmq-server -detached
Activating RabbitMQ plugins ...
0 plugins activated:

[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com stop_app
Stopping node 'z_91@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com reset
Resetting node 'z_91@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com cluster z_92@zen.com
Clustering node 'z_91@zen.com' with ['z_92@zen.com'] ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com start_app
Starting node 'z_91@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com cluster_status
Cluster status of node 'z_91@zen.com' ...
[{nodes,[{disc,['z_92@zen.com']},{ram,['z_91@zen.com']}]},
{running_nodes,['z_92@zen.com','z_91@zen.com']}]
...done.
复制代码

 

   细心的你一定发现了,这里的结果有点奇怪,91节点将92节点拉入组成集群,但是disc节点是92,91节点是ram节点!这是怎么回事?下面换一种方式组建集群,目的是观察rabbitmq在构建集群是如何选择Disc node的.和第一种组建方式的差异在于这行命令: ./rabbitmq-util -n z_91@zen.com cluster z_92@zen.com z_91@zen.com    这样完成组建之后,查看一下集群状态,注意disk node的已经变成了:   [{nodes,[{disc,['z_91@zen.com','z_92@zen.com']}]},{running_nodes,['z_92@zen.com','z_91@zen.com']}]

复制代码
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com stop_app     
Stopping node 'z_91@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com reset
Resetting node 'z_91@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com cluster z_92@zen.com z_91@zen.com
Clustering node 'z_91@zen.com' with ['z_92@zen.com','z_91@zen.com'] ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com start_app
Starting node 'z_91@zen.com' ...
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_91@zen.com cluster_status
Cluster status of node 'z_91@zen.com' ...
[{nodes,[{disc,['z_91@zen.com','z_92@zen.com']}]},
{running_nodes,['z_92@zen.com','z_91@zen.com']}]
...done.
[root@localhost scripts]#  ./rabbitmq-util -n z_92@zen.com cluster_status
Cluster status of node 'z_92@zen.com' ...
[{nodes,[{disc,['z_91@zen.com','z_92@zen.com']}]},
{running_nodes,['z_91@zen.com','z_92@zen.com']}]
...done.
[root@localhost scripts]# 
复制代码

 

WHY?

 

   我们先把答案说了,这是因为方法should_be_disc_node

 

should_be_disc_node(ClusterNodes) ->
    ClusterNodes == [] orelse lists:member(node(), ClusterNodes).

 

   当集群初建的时候,没有节点是disk node,ClusterNodes为[]所以会把加入集群的第一个新节点设置为disk node;当ClusterNodes不为空的时候,只要ClusterNodes包含当前节点,就会把当前节点设置为disk node;ClusterNodes就是来自于rabbitmqctl cluster命令后跟的参数.

 

 下面是详细的代码跟进过程,不再赘述,代码里面对一些关键的地方加了补充说明,比较容易理解.

 

  rabbitmqctl的实现逻辑实际上是在rabbitcontrol模块,我们关注的是action(cluster...)分支:

复制代码
..\rabbitmq-server-2.8.7\src\rabbit_control.erl

action(cluster, Node, ClusterNodeSs, _Opts, Inform) ->
    ClusterNodes = lists:map(fun list_to_atom/1, ClusterNodeSs),
    Inform("Clustering node ~p with ~p",
           [Node, ClusterNodes]),
    rpc_call(Node, rabbit_mnesia, cluster, [ClusterNodes]);
复制代码

 

 rabbitcontrol 调用的是rabbit_mnesia的cluster方法,跟进去看:

 

rabbit_mnesia.erl

 

  代码太长了,展开看吧 : ) 

 

 最后,小图一张 我有一个一样的台灯

 

相关实践学习
RocketMQ一站式入门使用
从源码编译、部署broker、部署namesrv,使用java客户端首发消息等一站式入门RocketMQ。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
目录
相关文章
|
23天前
|
存储 Kubernetes 容器
【CKA模拟题】查找集群中使用内存最高的node节点
【CKA模拟题】查找集群中使用内存最高的node节点
16 1
|
3月前
|
消息中间件 负载均衡 监控
【面试问题】RabbitMQ 的集群
【1月更文挑战第27天】【面试问题】RabbitMQ 的集群
|
6月前
|
消息中间件 存储 Kubernetes
k8s1.20版本部署RabbitMQ集群(持久化)——2023.05
k8s1.20版本部署RabbitMQ集群(持久化)——2023.05
259 1
|
21天前
|
数据库 存储 监控
什么是 SAP HANA 内存数据库 的 Delta Storage
什么是 SAP HANA 内存数据库 的 Delta Storage
16 0
什么是 SAP HANA 内存数据库 的 Delta Storage
|
6月前
|
Kubernetes 容器
k8s集群—node节点的删除与添加
k8s集群—node节点的删除与添加
273 0
|
6月前
|
Kubernetes 网络协议 API
node节点加入k8s集群时报错:no such host
node节点加入k8s集群时报错:no such host
133 0
|
6月前
|
消息中间件 存储 监控
消息中间件第八讲:消息队列 RocketMQ 版实战、集群及原理
消息中间件第八讲:消息队列 RocketMQ 版实战、集群及原理
|
2月前
|
消息中间件 运维 应用服务中间件
容器化运维:构建高可用RabbitMQ集群的Docker Compose指南
容器化运维:构建高可用RabbitMQ集群的Docker Compose指南
171 0
|
3月前
|
消息中间件 存储 缓存
RabbitMQ 集群和镜像队列
【1月更文挑战第11天】 一、clustering(集群) 1、使用集群的原因 2、搭建步骤 2.1、拉取镜像 2.2、创建三个RabbitMQ容器节点 2.3、集群搭建 二、镜像队列 1、使用镜像的原因 2、搭建步骤
241 6
|
5月前
|
消息中间件 测试技术