要保证整个系统在运行过程中,其中的任何一个环节宕机都不能影响整个系统
集群模式下各节点组件的高可用
Apache Pulsar:broker,bookkeeper,zkRabbitMQ:rabbitmq-serverRocketMQ:NameServer,BrokerRabbitMQ有两种集群模式:普通集群模式和镜像集群模式,根本区别在于
普通集群模式中,每个RabbitMQ节点都保存有队列相同的元数据,但是只有一个节点保存队列实际的消息数据镜像集群模式中,依赖「镜像队列」功能实现效果:每个RabbitMQ节点既保存有队列相同的元数据,又保存有队列实际的消息数据具体对比见表格
普通集群模式镜像集群模式普通队列镜像队列仲裁队列(3.8版本加入)注册队列当用户向服务注册一个队列,该队列会随机保存到某一个服务节点上,然后将对应的元数据同步到各个不同的服务节点上,每个RabbitMQ都保存有相同的元数据生产者向任一服务节点注册队列,该队列相关信息会同步到其他节点上生产者向任一服务节点注册队列,该队列相关信息会同步到其他节点上消费消息RabbitMQ服务节点C发现自己本服务节点并没有对应的实际数据后,因为每个服务节点上都会保存相同的元数据,所以服务节点C会根据元数据,向服务节点B(该服务节点上有实际数据可供消费)请求实际数据,然后提供给用户进行消费任一消费者向任一节点请求消费,可以直接获取到消费的消息,因为每个节点上都有相同的实际数据任一消费者向任一节点请求消费,可以直接获取到消费的消息,因为每个节点上都有相同的实际数据优点提高消费的吞吐量任一节点宕机,不影响消息在其他节点上进行消费1.仲裁队列使用了Raft协议的一种变体,该协议已成为业界事实上的分布式共识算法。与镜像队列相比,它既安全又实现了更高的吞吐量。2.仲裁队列旨在解决镜像队列的性能和同步失败。3.镜像队列的同步问题已不复存在。当broker重新联机时,它们不会丢弃其数据。所有消息都保留在磁盘上,并且leader仅从上次停止的地方复制消息。4.将消息复制到恢复的follower是非阻塞的。因此,队列不会受到新follower或重新加入follower的影响。唯一的影响可能是网络利用率。5.Raft比镜像队列算法更有效,并且应提供更好的吞吐量。缺点1、为了请求RabbitMQ的实际数据以提供给用户,可能会在RabbitMQ内部服务节点之间进行频繁的进行数据交互,这样的交互比较耗费资源2、当其中一个RabbitMQ的服务节点宕机了,那么该节点上的实际数据就会丢失,用户再次请求时,就会请求不到数据,系统的功能就会出现异常1、性能开销非常大,因为要同步消息到对应的节点,这个会造成网络之间的数据量的频繁交互,对于网络带宽的消耗和压力都是比较重的2、扩展性差,rabbitMQ是集群,但不是分布式的,所以当某个Queue负载过重,并不能通过新增节点来缓解压力,因为所有节点上的数据都是相同的,这样就没办法进行扩展了3.镜像队列不是负载均衡,因为每个操作在所有节点都要做一遍。镜像队列无法提升消息的传输效率,或者更进一步说,由于镜像队列会在不同节点之间进行同步,会消耗消息的传输效率。目前功能不够完善,缺少一些队列特性的支持,比如:非持久化消息;独占型队列;队列/消息生存时间TTL等等备注如果master 由于某种原因失效,那么"资历最老"的slave 会被提升为新的master 。根据slave 加入的时间排序,时间最长的slave 即为"资历最老"。发送到镜像队列的所有消息会被同时发往master 和所有的slave 上,如果此时master 挂掉了,消息还会在slave 上,这样slave提升为master 的时候消息也不会丢失。这种方式风险较大,一旦Broker重启或者宕机时,会导致整个服务不可用。不建议线上环境使用,可以用于本地测试。
一个集群无Slave,全是Master,例如2个Master或者3个Master,这种模式的优缺点如下:
优点:配置简单,单个Master宕机或重启维护对应用无影响,在磁盘配置为RAID10时,即使机器宕机不可恢复情况下,由于RAID10磁盘非常可靠,消息也不会丢(异步刷盘丢失少量消息,同步刷盘一条不丢),性能最高; 缺点:单台机器宕机期间,这台机器上未被消费的消息在机器恢复之前不可订阅,消息实时性会受到影响。
每个Master配置一个Slave,有多对Master-Slave,HA采用异步复制方式,主备有短暂消息延迟(毫秒级),这种模式的优缺点如下:
优点:即使磁盘损坏,消息丢失的非常少,且消息实时性不会受影响,同时Master宕机后,消费者仍然可以从Slave消费,而且此过程对应用透明,不需要人工干预,性能同多Master模式几乎一样; 缺点:Master宕机,磁盘损坏情况下会丢失少量消息。
每个Master配置一个Slave,有多对Master-Slave,HA采用同步双写方式,即只有主备都写成功,才向应用返回成功,这种模式的优缺点如下:
优点:数据与服务都无单点故障,Master宕机情况下,消息无延迟,服务可用性与数据可用性都非常高; 缺点:性能比异步复制模式略低(大约低10%左右),发送单个消息的RT会略高,且目前版本在主节点宕机后,备机不能自动切换为主机。
每台NameServer 机器都拥有所有的路由信息,包括所有的 Broker 节点信息、数据信息等 ,这样只要有一台 NameServer 存活就不会影响系统的稳定性。
Pulsar 集群包含 3 个组件:ZooKeeper 集群、BookKeeper 集群和 Broker 集群。
其中BookKeeper做消息的存储,broker做消息的处理计算,pulsar依靠BookKeeper,实现了「存储计算分离」的架构,这是有别于其他MQ最大的一点。还有一个ZooKeeper主要是存储broker和BookKeeper的元数据,以及pulsar clusar的集群配置协调工作。
在 Apache Pulsar 的分层架构中,服务层 Broker 和存储层 BookKeeper 的每个节点都是对等的。Broker 仅仅负责消息的服务支持,不存储数据。这为服务层和存储层提供了瞬时的节点扩展和无缝的失效恢复。
一个 ZooKeeper 集群通常由一组机器组成,一般 3 台以上就可以组成一个可用的 ZooKeeper 集群。
组成 ZooKeeper 集群的每台机器都会在内存中维护当前的服务器状态,并且每台机器之间都会互相保持通信。
只要集群中存在超过一半的机器能够正常工作,那么整个集群就能够正常对外服务。
基于这个特性,如果想搭建一个能够允许 N 台机器 down 掉的集群,那么就要部署一个由 2*N+1 台服务器构成的 ZooKeeper 集群。因此,一个由 3 台机器构成的 ZooKeeper 集群,能够在挂掉 1 台机器后依然正常工作,而对于一个由 5 台服务器构成的 ZooKeeper 集群,能够对 2 台机器挂掉的情况进行容灾。
如果一个 Broker 失败,Pulsar 会自动将其拥有的主题分区移动到集群中剩余的某一个可用 Broker 中。需要注意的是:由于 Broker 是无状态的,当发生 Topic 的迁移时,Pulsar 只是将所有权从一个 Broker 转移到另一个 Broker,在这个过程中,不会有任何数据复制发生。
当client 开始使用未分配给任何Broker的Topic时,将触发一个机制:根据负载条件选择最合适的Broker来获取这些Topic的所有权。
如果是分区主题的情况(partitioned topics),则将不同的分区分配给不同的Broker。此处的“topic”是指未分区的主题或该Topic的一个分区。
分配是“动态的”,因为分配变化很快。例如,如果拥有该Topic的Broker崩溃,则将该Topic立即重新分配给另一个Broker。另一种情况是拥有Topic的Broker变得超载。在这种情况下,将Topic重新分配给负载较小的Broker。需要注意的是:由于 Broker 是无状态的,当发生 Topic 的迁移时,Pulsar 只是将所有权从一个 Broker 转移到另一个 Broker,在这个过程中,不会有任何数据复制发生。
Broker 的无状态性质使动态分配成为可能,因此可以根据使用情况快速扩展或收缩集群。
一个 BookKeeper 集群包括:
Bookies:一组独立的存储服务器元数据存储系统:用于服务发现和元数据管理关键点:
BookKeeper将数据存储至集群中的节点上,每个BookKeeper节点称为Bookie。
一个Topic由多个Ledger构成,一个Ledger由一个或多个Fragment组成,每个Fragment有多个条目Entry组成,每个Entry上包含的就是多条消息Message。
Fragment是BookKeeper集群中最小的分布单元,Ledger是最小的删除单元。
Topic是Pulsar中的概念。Ledger和Fragment是BookKeeper中的概念。
每个Pulsar Broker都需要跟踪每个Topic所包含的Ledgers和Fragments。这个元数据存储在Zookeeper中。
Fragments分布在Bookie集群中,跨多个Bookies带状分布。存储可以单独扩展。如果存储是瓶颈,那么只需要添加更多的Bookies,他们会自动承担负载,不需要Rebalance。
当Bookie不可用时,自动恢复模式将自动进行数据重新复制到其他的Bookies。
BookKeeper 通过 Quorum Vote 的方式来实现数据的一致性,跟 Master/Slave 模式不同,BookKeeper 中每个节点也是对等的,对一份数据会并发地同时写入指定数目的存储节点。对等的存储节点,保证了多个备份可以被并发访问;也保证了存储中即使只有一份数据可用,也可以对外提供服务。