一、现状分析

传统方法经过物理机或虚拟机布置一套高可用的 RocketMQ 集群,假定 2 Master 2 Slave,再加 2 个 nameserver,总共需求 6 台机器。如果把 nameserver 跟 broker 布置在一起,那也需求 4 台机器。这种方法硬件本钱很高,另外保护本钱也相当高。

Kubernetes 布置

基于 Kubernetes 布置运用可以大幅度下降硬件本钱和运维本钱。RocketMQ 官方供给了 operator 布置,我们公司已经用这种方法布置了好几套集群,运用进程中发现了一些问题:

  • nameserver 从头调度后 pod ip 会改动,此刻 operator 会逐一修正 broker statefulset 装备,这意味着所有 broker 都需求重启,会形成事务中止。
  • 装备不够灵活,比如不方便增加节点亲和性;副节点跟主节点运用同样的资源配额,不方便单独装备。
  • 布置操作不够简练,operator 比 helm 的复杂度高许多。

RocketMQ 官方没有供给 helm,谷歌搜一下 rocketmq helm 也没有找到可用的资源。bitnami 供给了超级丰厚的 helm 资源,其间覆盖了 Kafka 和 RabbitMQ,但是没有 RocketMQ.

因此,有必要自己开发 helm 来布置高可用集群。

二、helm 开发

难点分析

因为 k8s pod ip 都是动态的,这给一些有状态的运用带来了麻烦。

broker 必须静态增加每个 nameserver 地址 (ip或域名),它不能依托服务发现。这儿运用 pod ip 必定不合理,需求把每个 nameserver 的 pod 域名装备到 broker. <pod域名> = <pod名>.<statefulSet服务名>.<namespace>.svc.cluster.local,同命名空间下可以去掉后缀: <pod名>.<statefulSet服务名>

以下截取了部分关于 nameserver 高可用的装备:

apiVersion: v1
kind: Service
metadata:
  name: rocketmq-nameserver
---

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: rocketmq-nameserver
spec:
  replicas: 3
  serviceName: rocketmq-nameserver
---

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: rocketmq-broker-0-master
spec:
  template:
    spec:
      containers:
      - env:
        - name: NAMESRV_ADDR
          # NAMESRV_ADDR 错误装备:value: rocketmq-nameserver:9876 
          # 正确操作是把所有 nameserver 节点加入 NAMESRV_ADDR,如下:
          value: rocketmq-nameserver-0.rocketmq-nameserver:9876;rocketmq-nameserver-1.rocketmq-nameserver:9876;rocketmq-nameserver-2.rocketmq-nameserver:9876

Kubernetes 部署高可用 RocketMQ 集群

完成细节

把每个 nameserver 的 pod 域名装备到 broker,以下截取了完成这个需求的部分模板装备:

nameserver statefulset.yaml 模板:

{{- $fullName := include "rocketmq.nameserver.fullname" . -}}
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: {{ $fullName | quote }}
spec:
  replicas: {{ .Values.nameserver.replicaCount }}
  serviceName: {{ $fullName | quote }}

broker statefulset.yaml 模板:

{{- $nameserverFullName := include "rocketmq.nameserver.fullname" . -}}
{{- $nameserverReplicaCount:= int .Values.nameserver.replicaCount }}
env:
- name: NAMESRV_ADDR
  value: {{ range $i := until $nameserverReplicaCount }}{{ if gt $i 0 }}{{ printf ";" }}{{ end }}{{ printf "%s-%d.%s:9876" $nameserverFullName $i $nameserverFullName }}{{ end }}

三、布置

参阅 GitHub 文档: github.com/itboon/rock…

git clone https://github.com/itboon/rocketmq-helm.git
cd rocketmq-helm
kubectl create namespace rocketmq

# 布置测验集群, 单 Master
helm -n rocketmq install rocketmq -f examples/test.yml ./

# 布置出产集群, 多 Master 多 Slave
helm -n rocketmq install rocketmq -f examples/production.yaml ./

Broker 集群架构

单 Master 形式

broker:
  size:
    master: 1
    replica: 0

多 Master 形式

一个集群无Slave,全是Master,例如2个Master或许3个Master,这种形式的优缺陷如下:

  • 长处:装备简略,单个Master宕机或重启保护对运用无影响,性能最高;
  • 缺陷:单台机器宕机期间,这台机器上未被消费的音讯在机器恢复之前不可订阅,音讯实时性会受到影响。
broker:
  size:
    master: 3
    replica: 0

多 Master 多 Slave 形式

每个Master装备一个Slave,有多对Master-Slave,HA选用异步复制方法,主备有时间短音讯推迟(毫秒级),这种形式的优缺陷如下:

  • 长处:Master宕机后,消费者依然可以从Slave消费,并且此进程对运用通明,不需求人工干预,性能同多Master形式几乎一样;
  • 缺陷:Master宕机,磁盘损坏情况下会丢失少数音讯 (已经同步到 Slave 的数据不受影响)
broker:
  size:
    master: 3
    replica: 1
# 3个 master 节点,每个 master 具有1个副节点,共6个 broker 节点

作者简介

八戒,来自杭州晓宇科技,技能中台运维工程师。

| 本文系晓宇科技技能团队出品,著作权归属晓宇科技技能团队。欢迎出于分享和交流等非商业目的转载或运用本文内容,敬请注明“内容转载自晓宇科技技能团队”。本文未经许可,不得进行商业性转载或许运用。