[Erlang 0085] RabbitMQ 集群: data and metadata

简介:

 我们希望 RabbitMQ的集群能够解决单点故障,一旦节点异常自动重连到正常的节点;希望RabbitMQ 集群可以完成负载均衡,可以保证消息不丢失,希望可以快速增加节点到集群,单个节点当掉不会给集群带来灾难影响..... 哦,停下来,我们似乎把构建健壮地可扩展系统的所有梦想都寄托在RabbitMQ之上了.事实又是怎样呢?我们不能臆测软件对一个功能的实现,最好的办法就是用一下;我们近距离看一下.

 

RabbitMQ Cluster设计目标

 

   RabbitMQ in Action 里面提到RabbitMQ两个设计目标,需要自己琢磨一下:

 

  •  allowing consumers and producers to keep running in the event one Rabbit node dies

  •  linearly scaling messaging throughput by adding more nodes. 

  即:在集群中的一个Rabbit节点当掉的时候允许Consumer和producer继续运行;以及通过增加节点的线性扩展方式增加消息吞吐能力.

 

 

   RabbitMQ会提供一些机制比如把exchange queue设置为durable,persistent mode设置为2,等等来尽可能保证消息不丢失,但是这种保证是有限的.即使你该做的都做了,RabbitMQ节点当掉还是有可能出现消息丢失的情况.这是因为RabbitMQ并没有在节点之间做数据复制(Data Replicate).没有特殊的配置(后面会提到Mirrored Queue),一个队列的数据只会出现在Queue所属的节点.

 

Message Data & Metadata

 

   如果我们把RabbitMQ看作一个处理消息的机器,那么RabbitMQ内部拥有若干基础的零件(Queue Exchange Binding Vhost),它是如何将这些概念组合起来构成一个消息组件的呢?这种问题的思考有两种方式:从软件构成的基础设施入手,看基础设施之间的配合方式;另外一种方式就是从被处理的对象入手,看对象如何被处理的;这样都可以了解软件的内部机制.对于RabbitMQ它处理的对象就是消息数据(Message)和消息路由必须的规则数据.

 

  对于RabbitMq集群我们可以从数据的视角切入,集群需要解决两种类型数据的存储:Message Data和Metadata;我们传递的消息就是 Message Data,而和消息路由相关的配置和规则型的数据被称为meta data.

 

Message Data

  

  之前提到过Message在RabbitMQ实际存储位置是Queue, 所以当我们谈Message data的时候,实际上更多的时候我们在谈Queue.这一节的题目也可以是:"How Queues behave in a cluster". 并不是所有的节点都拥有集群内某个Queue的完整副本.在单节点环境中,所有的数据元数据都会在节点内维护,all-in-one. 如果是在集群中创建一个Queue,RabbitMQ集群只会在一个节点维护该Queue的完整信息,Client连接到哪个节点就会在哪个节点上.其它节点仅仅拥有Queue的元数据和一个Queue实际数据所在节点的指针.

  所以,集群中的节点当掉,该节点的queues和相关的bingdings都会消失,连接到这个Queue的Consumer失去了订阅,任何模式匹配发送到该Queue的新消息都会被扔进黑洞.不要担心,有一些额外的消息确认策略来防止这种情况带来的消息丢失.

 

  如果Queue所在的节点当掉了,怎么办?

 

  我们可能会想:让consumer重新连接到集群重建队列不就可以了? 这样做是有条件限制的,只有当queue没有标记为durable的时候可以.如果一个Queue被声明为durable的,那么在新的节点重建这个queue会得到一个404 NOT_FOUND错误(见下图).这种集群处理策略是为了保证这个Queue中的消息在加入集群后不消失:如果一个队列之前在node1,如果允许在节点node2重建那么后续RabbitMQ就会认为这个队列在所在的位置是在node2,之前node1未被处理的消息就不会被处理了.把这个queue加入集群的唯一方法就是等待它所在的节点恢复正常加入集群.

 

 

   如果要重建的不是durable的,重新声明会成功.

 
   为什么RabbitMQ不在各节点复制所有的队列的消息内容和状态?
 
   这个首先很容易想到两个原因: [1] 额外的存储成本  [2] 性能 集群中的某个node只负责特定队列的消息,如果消息冗余就要将消息分发到所有节点,这里会有性能消耗;如果消息需要持久化仅仅是一个节点所在的机器有磁盘IO消耗,如果是多个节点都要复制所有的消息,这个消耗将出现在所有的节点上而且每增加一个节点都会加剧这个负担.

 

 

相比具体message data,meta data更像是一种"组织概念",对于这种概念首先要明确的就是其包含哪些东西:

 

metadata

  

  RabbitMQ在内部维护基础零件(Queue Exchange Binding Vhost)的元数据(metadata),在构成RabbitMQ集群之后还有集群的元数据.

 

  • Queue metadata—Queue names and their properties (are they durable or auto-delete?)

  • Exchange metadata—The exchange’s name, the type of exchange it is, and what the properties are (durable and so on)

  • Binding metadata—A simple table showing how to route messages to queues

  • Vhost metadata—Namespacing and security attributes for the queues, exchanges,and bindings within a vhost 

  • Rabbit node location 

 

   单节点的情况,RabbitMQ会在内存中维护一份元数据信息,并把标记为Durable的Queue和Exchange(以及相关bingding)持久化到磁盘.

 

   引入了集群之后,会新增几种元数据信息:集群节点位置信息(Erlang节点名包含这部分信息),以及节点之间的关系信息.集群环境中你还会面临一个选择是存储元数据到RAM Only还是Disk 磁盘,在单节点情况由于没有额外的数据冗余存在所以这个选择默认是持久化到磁盘.

 

 

 

最后小图一张,Gal Gadot 2004年度以色列小姐 速度与激情4,5惊艳全场,我们俩都是金牛座的 : )

 

 

相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
目录
相关文章
|
3月前
|
消息中间件 存储 负载均衡
|
3月前
|
消息中间件 存储 负载均衡
"RabbitMQ集群大揭秘!让你的消息传递系统秒变超级英雄,轻松应对亿级并发挑战!"
【8月更文挑战第24天】RabbitMQ是一款基于AMQP的开源消息中间件,以其高可靠性、扩展性和易用性闻名。面对高并发和大数据挑战时,可通过构建集群提升性能。本文深入探讨RabbitMQ集群配置、工作原理,并提供示例代码。集群由多个通过网络连接的节点组成,共享消息队列,确保高可用性和负载均衡。搭建集群需准备多台服务器,安装Erlang和RabbitMQ,并确保节点间通信顺畅。核心步骤包括配置.erlang.cookie文件、使用rabbitmqctl命令加入集群。消息发布至任一节点时,通过集群机制同步至其他节点;消费者可从任一节点获取消息。
45 2
|
3月前
|
存储 C# 关系型数据库
“云端融合:WPF应用无缝对接Azure与AWS——从Blob存储到RDS数据库,全面解析跨平台云服务集成的最佳实践”
【8月更文挑战第31天】本文探讨了如何将Windows Presentation Foundation(WPF)应用与Microsoft Azure和Amazon Web Services(AWS)两大主流云平台无缝集成。通过具体示例代码展示了如何利用Azure Blob Storage存储非结构化数据、Azure Cosmos DB进行分布式数据库操作;同时介绍了如何借助Amazon S3实现大规模数据存储及通过Amazon RDS简化数据库管理。这不仅提升了WPF应用的可扩展性和可用性,还降低了基础设施成本。
77 0
|
4月前
|
消息中间件 Prometheus 监控
消息队列 MQ使用问题之如何将旧集群的store目录迁移到新集群
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
4月前
|
消息中间件 RocketMQ
MetaQ/RocketMQ 原理问题之当消费集群规模较大时,处理分配不到队列的Consumer的问题如何解决
MetaQ/RocketMQ 原理问题之当消费集群规模较大时,处理分配不到队列的Consumer的问题如何解决
|
3月前
|
消息中间件 API 数据安全/隐私保护
就软件研发问题之RocketMQ ACL 2.0加强集群组件间访问控制的问题如何解决
就软件研发问题之RocketMQ ACL 2.0加强集群组件间访问控制的问题如何解决
|
4月前
|
消息中间件 负载均衡 算法
【RocketMQ系列十二】RocketMQ集群核心概念之主从复制&生产者负载均衡策略&消费者负载均衡策略
【RocketMQ系列十二】RocketMQ集群核心概念之主从复制&生产者负载均衡策略&消费者负载均衡策略
114 2
|
4月前
|
消息中间件 存储 Java
【RocketMQ 系列三】RocketMQ集群搭建(2m-2s-sync)
【RocketMQ 系列三】RocketMQ集群搭建(2m-2s-sync)
344 1
|
4月前
|
消息中间件 NoSQL 关系型数据库
【RocketMQ系列十三】RocketMQ的集群核心概念之消费重试&死信队列&幂等消息的出现以及处理
【RocketMQ系列十三】RocketMQ的集群核心概念之消费重试&死信队列&幂等消息的出现以及处理
124 1
|
4月前
|
消息中间件 存储 Java
消息队列 MQ使用问题之如何将RocketMQ中某个集群的topic迁移到另一个集群
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。