rabbitmq 集群数据存储与单点故障


声明:本文转载自https://my.oschina.net/zcjlq/blog/1574455,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

rabbitmq每个节点记录四类信息:交换机、队列、绑定、vhost元数据。

集群中的信息存储

在rabbitmq2.6.0之前没有镜像队列,数据存储情况为:

队列所属节点保存队列全部信息(元数据、状态、内容),其他节点拥有队列元数据;所有节点保存exchange、bundling信息。好处有两点:

    1.节约存储空间,每个节点都有相同信息的拷贝,意味着磁盘空间成倍占用;

    2.提升性能,数据在节点间同步占用网络资源,如果是持久化状态,又会有大量I/O;

正常情况的工作原理:

集群中有三个节点:rabbit、hare、hare1,队列声明在hare节点,向rabbit节点发消息,消息会转发到hare节点,消费者连接hare1节点,则从hare节点读取数据。

异常情况1(发送过程中故障):

向rabbit节点发送5条消息,第一条发送成功后,关掉hare节点

2017-11-16 12:05:07,015 [http-bio-8080-exec-1]  [org.springframework.amqp.rabbit.core.RabbitTemplate]-[DEBUG] Publishing message (Body:'< publish  message 内容为:[ Thu Nov 16 12:05:07 CST 2017 ]>' MessageProperties [headers={},  contentType=text/plain, contentEncoding=UTF-8, contentLength=62, deliveryMode=PERSISTENT, priority=0, deliveryTag=0])on exchange [AMC_TMP_EXCHANGE], routingKey = [cluster.send]

控制台显示正常发送,实际上后面4条消息已经丢失

localhost:sbin zcjlq$ ./rabbitmqctl -n hare stop_app Stopping rabbit application on node hare@localhost localhost:sbin zcjlq$ ./rabbitmqctl -n rabbit -p zcjlq list_queues Listing queues AMC_TMP_QUEUE

hare节点重启,只有第一条消息

localhost:sbin zcjlq$ ./rabbitmqctl -n hare start_app Starting node hare@localhost localhost:sbin zcjlq$ ./rabbitmqctl -n rabbit -p zcjlq list_queues Listing queues AMC_TMP_QUEUE	1

拓展:

如果使用publisher confirm机制,在回调函数RabbitTemplate.ConfirmCallback,你将拿到5个ack,RabbitTemplate.ReturnCallback不会被回调。


异常情况2(发送完毕故障):

假如我们连上任意节点,发送4条消息,先不消费,各个节点都能查到消息。

下面停掉队列所属节点hare

localhost:sbin zcjlq$ ./rabbitmqctl -n rabbit -p zcjlq list_queues Listing queues AMC_TMP_QUEUE	4 localhost:sbin zcjlq$ ./rabbitmqctl -n hare1 -p zcjlq list_queues Listing queues AMC_TMP_QUEUE	4 localhost:sbin zcjlq$ ./rabbitmqctl -n hare stop_app Stopping rabbit application on node hare@localhost localhost:sbin zcjlq$ ./rabbitmqctl -n hare1 -p zcjlq list_queues Listing queues AMC_TMP_QUEUE localhost:sbin zcjlq$ ./rabbitmqctl -n rabbit -p zcjlq list_queues Listing queues AMC_TMP_QUEUE localhost:sbin zcjlq$ ./rabbitmqctl -n hare start_app Starting node hare@localhost localhost:sbin zcjlq$ ./rabbitmqctl -n rabbit -p zcjlq list_queues Listing queues AMC_TMP_QUEUE	4 localhost:sbin zcjlq$ ./rabbitmqctl -n hare1 -p zcjlq list_queues Listing queues AMC_TMP_QUEUE	4

我们发现:停用hare节点后,在另外两个节点查不到消息,hare节点重启后,三个节点都能查到消息。

说明:本测试在单机上启动三个节点(单机集群搭建见后续文章)

rabbitmqctl -n参数指定节点名称,-p指定vhost名称,start_app启动节点,stop_app关闭节点,

list_queues查看队列列表和待消费消息。

异常情况3(故障期间重新声明队列):

在恢复hare节点前,我们尝试通过其他节点重新创建队列。出现以下错误

Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method:  #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - home node 'hare@localhost'  of durable queue 'AMC_TMP_QUEUE' in vhost 'zcjlq' is down or inaccessible, class-id=50, method-id=10)

 

节点类型

集群中的节点有两个类型:磁盘节点、内存节点。内存节点(ram)将所有的队列、交换器、绑定、用户、权限、vhost的元数据定义都仅存储于内存中。磁盘节点(disc)将元数据存储在磁盘中。

是磁盘节点还是内存节点?

在集群中声明队列、交换器、绑定的时候,其他节点会得到元数据的同步,如果集群中全都是磁盘节点,那么你需要等到所有的节点都磁盘I/O后才完成工作,内存节点将会更快。

rabbitmq要求集群中至少有一个磁盘节点。磁盘节点离开集群时,集群还可以进行部分工作,创建队列、创建交换机、创建绑定、添加用户、更改权限、添加或删除集群节点将不能使用。原理的磁盘节点重启后,集群可以正常工作。我们想要更安全一点:原磁盘节点重启前,为让集群正常工作,这时候可以考虑设置两个集群节点,当其中一个磁盘节点离开时,它会将该变更通知到至少一个磁盘节点。

 

本文发表于2017年11月16日 14:33
(c)注:本文转载自https://my.oschina.net/zcjlq/blog/1574455,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2377 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1