本文作者:蔡高扬,Apache RocketMQ Committer, 阿里云智能技术专家。
背景
上图左侧为 RocketMQ 4.x版本集群,属于非切换架构。NameServer 作为无状态节点可以部署多份,broker 集群可以部署多组 broker ,每一组有一个 Broker Master 和多个 Broker Slave 。运行过程中如果某一组 master 故障,消息发送会路由到正常的 master 上,普通消息可以从原 Broker Slave 继续消费。
但非切换架构存在若干问题,比如定时消息或事务消息需要由 Master 进行二次投递,如果 Master 故障,则需要人工介入将 Master 重新恢复。因此, RocketMQ 5.0 提出了自主切换架构。
自主切换架构新增了一个 Controller 模块,负责选主。当某个 Broker Master 故障,会选择合适的 Broker Slave 提升为 Master,无需人工介入。
如果要在生产环境中部署一套集群,需要规划整个集群的机器资源(比如哪些模块部署在哪些机器、哪些机器需要什么样的资源规格等),然后安装 JDK 等依赖软件。每个组件还需要准备有其配置文件、启动脚本,再启动各个组件。整个过程十分耗费人力,而且存在误操作可能。
而在云基础设施上部署 RocketMQ 面临更多挑战:
首先,在云基础设施上创建不同规格的虚拟机更为方便,因此在云基础设施上部署时,一个虚拟机上往往只会部署一个模块,以实现资源隔离。然而,多节点部署也带了更高的操作成本。而系统内部组件的宕机、恢复、迁移等行为也需要进行支持。
从社区角度看,因为社区面向不同用户,不同用户往往会在不同云基础服务提供商上进行部署。但是从 IaaS 层设施看,不同云厂商提供的接口并不统一。
为了解决上述问题,社区借鉴了面向接口编程的思路:不直接操作基础设施,而是通过标准接口。而 Kubernetes 正是这样一个容器编排的“标准接口”。于是,社区在解决 RocketMQ 在云基础设施的部署问题时,选择基于 Kubernetes 进行部署,不同云厂商负责从 Kubernetes 到具体云 IaaS 层的调度:将有状态 RocketMQ 集群托管到 Kubernetes 集群,充分利用 Kubernetes 提供的部署、升级、自愈相关能力,同时也能享受到 Kubernetes 社区的生态红利。
Kubernetes 将 Pod、Deployment、Service、Ingress 等都封装成抽象资源。在部署 RocketMQ 集群时,只需将相关的 Kubernetes 资源编排好,而资源最终如何在云基础设施上进行编排则交由云服务提供商来完成。
然而,直接基于 Kubernetes 原生资源进行部署也存在一些不足。
比如用 Kubernetes 部署时