第十二章:集群部署

深入了解 RocketMQ 的集群部署架构,包括主从集群和 DLedger 集群。

最后更新: 2024-01-15
页面目录

RocketMQ 集群部署

本章介绍 RocketMQ 的各种集群部署方案和配置方法。

集群架构

架构类型

┌─────────────────────────────────────────────────────────────────┐
│                      RocketMQ 集群类型                            │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│   1. 单机部署                                                   │
│      ┌─────────┐                                                │
│      │NameServer│                                                │
│      │  Broker  │                                                │
│      └─────────┘                                                │
│                                                                  │
│   2. 主从集群                                                   │
│      ┌─────────┐                                                │
│      │NameServer│◄─── 多个 NameServer                           │
│      └─────────┘                                                │
│           │                                                      │
│      ┌────┴────┐                                                 │
│      │         │                                                 │
│   ┌──┴──┐   ┌──┴──┐                                              │
│   │Master│───│Slave │                                              │
│   └─────┘   └─────┘                                              │
│                                                                  │
│   3. DLedger 集群                                               │
│      ┌─────────┐                                                │
│      │NameServer│◄─── 多个 NameServer                           │
│      └─────────┘                                                │
│           │                                                      │
│      ┌────┴────┐                                                 │
│      │         │                                                 │
│   ┌──┴──┬──┴──┐                                              │
│   │Leader│   │Follower │                                      │
│   └─────┘   └─────┘                                              │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

NameServer 集群

多 NameServer 部署

# 启动多个 NameServer
# NameServer 1
nohup sh mqnamesrv -n 192.168.1.101:9876 &

# NameServer 2
nohup sh mqnamesrv -n 192.168.1.102:9876 &

# NameServer 3
nohup sh mqnamesrv -n 192.168.1.103:9876 &

Producer/Consumer 配置

# Producer 配置
rocketmq:
  producer:
    namesrvAddr: 192.168.1.101:9876;192.168.1.102:9876;192.168.1.103:9876

# Consumer 配置
rocketmq:
  consumer:
    namesrvAddr: 192.168.1.101:9876;192.168.1.102:9876;192.168.1.103:9876

主从集群

双主双从同步集群

┌─────────────────────────────────────────────────────────────────┐
│                      双主双从同步集群                             │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│   NameServer1 ┐                                                │
│   NameServer2 ┼──► Broker Cluster                              │
│   NameServer3 ┘                                                │
│                    │                                            │
│   ┌───────────────┼───────────────┐                           │
│   │                               │                           │
│   ┌───────┐                  ┌───────┐                       │
│   │Master-A│◄─── SYNC ────►│Slave-A │                   │
│   │  10911 │                  │  10912 │                   │
│   └───────┘                  └───────┘                       │
│        │                           │                       │
│        │                           │                       │
│   ┌───────┐                  ┌───────┐                       │
│   │Master-B│◄─── SYNC ────►│Slave-B │                   │
│   │  10921 │                  │  10922 │                   │
│   └───────┘                  └───────┘                       │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Broker 配置

Master-A 配置

# broker-a.properties
brokerClusterName=DefaultCluster
brokerName=broker-a
brokerId=0
listenPort=10911
namesrvAddr=192.168.1.101:9876;192.168.1.102:9876;192.168.1.103:9876
defaultTopicQueueNums=4
storePathRootDir=/home/rocketmq/store-a
storePathCommitLog=/home/rocketmq/store-a/commitlog
# 同步复制
brokerRole=SYNC_MASTER
# 异步刷盘
flushDiskType=ASYNC_FLUSH
# 读写队列
readQueueNums=4
writeQueueNums=4

Slave-A 配置

# broker-a-s.properties
brokerClusterName=DefaultCluster
brokerName=broker-a
brokerId=1
listenPort=10912
namesrvAddr=192.168.1.101:9876;192.168.1.102:9876;192.168.1.103:9876
storePathRootDir=/home/rocketmq/store-a-s
storePathCommitLog=/home/rocketmq/store-a-s/commitlog
# 从节点角色
brokerRole=SLAVE
flushDiskType=ASYNC_FLUSH

启动集群

#!/bin/bash
# start-cluster.sh

# 启动 NameServer
ssh 192.168.1.101 "cd /rocketmq && nohup sh bin/mqnamesrv &"
ssh 192.168.1.102 "cd /rocketmq && nohup sh bin/mqnamesrv &"
ssh 192.168.1.103 "cd /rocketmq && nohup sh bin/mqnamesrv &"

sleep 5

# 启动 Master
ssh 192.168.1.101 "cd /rocketmq && nohup sh bin/mqbroker -c conf/2m-2s-sync/broker-a.properties &"
ssh 192.168.1.102 "cd /rocketmq && nohup sh bin/mqbroker -c conf/2m-2s-sync/broker-b.properties &"

# 启动 Slave
ssh 192.168.1.103 "cd /rocketmq && nohup sh bin/mqbroker -c conf/2m-2s-sync/broker-a-s.properties &"
ssh 192.168.1.104 "cd /rocketmq && nohup sh bin/mqbroker -c conf/2m-2s-sync/broker-b-s.properties &"

echo "集群启动完成"

DLedger 集群

DLedger 简介

DLedger 是一个基于 Raft 协议的日志存储库,支持自动故障转移。

┌─────────────────────────────────────────────────────────────────┐
│                      DLedger 架构                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│   DLedger Group                                                 │
│   ┌─────────────────────────────────────────────────────────┐   │
│   │                                                         │   │
│   │     ┌─────────┐                                        │   │
│   │     │  Node 0 │ ◄─── Leader                           │   │
│   │     │ (Self)  │                                        │   │
│   │     └────┬────┘                                        │   │
│   │          │                                               │   │
│   │    ┌─────┼─────┐                                       │   │
│   │    │     │     │                                       │   │
│   │    ▼     ▼     ▼                                       │   │
│   │ ┌────┐ ┌────┐ ┌────┐                                   │   │
│   │ │ N0 │ │ N1 │ │ N2 │  ────► Raft 复制                   │   │
│   │ └────┘ └────┘ └────┘                                   │   │
│   │                                                         │   │
│   └─────────────────────────────────────────────────────────┘   │
│                                                                  │
│   特点:                                                         │
│   ✅ 自动故障转移                                                │
│   ✅ 数据一致性                                                  │
│   ✅ 选举协议                                                    │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

DLedger 配置

# broker-dledger.conf
brokerClusterName = DefaultCluster
brokerName = broker-d
listenPort = 10911
namesrvAddr = 192.168.1.101:9876;192.168.1.102:9876;192.168.1.103:9876

# DLedger 配置
enableDLegerCommitLog = true
dLegerGroup = broker-d
# Raft 节点配置
dLegerPeers = n0=192.168.1.101:40911;n1=192.168.1.102:40911;n2=192.168.1.103:40911
# 当前节点 ID
dLegerSelfId = n0

# 存储路径
storePathRootDir = /home/rocketmq/store-d

# 性能配置
sendMessageThreadPoolNums = 16

启动 DLedger 集群

#!/bin/bash
# start-dledger.sh

# 在三个节点上分别执行以下命令

# 节点 1
nohup sh mqbroker -c conf/dledger/broker-dledger.conf &

# 节点 2 (dLegerSelfId = n1)
nohup sh mqbroker -c conf/dledger/broker-dledger.conf &

# 节点 3 (dLegerSelfId = n2)
nohup sh mqbroker -c conf/dledger/broker-dledger.conf &

DLedger vs 主从集群

特性 主从集群 DLedger 集群
数据一致性 最终一致 强一致
自动故障转移 需要配置 自动
配置复杂度 中等 简单
性能 中等
适用场景 一般生产环境 高可用场景

Docker Compose 部署

version: '3.8'
services:
  namesrv1:
    image: apache/rocketmq:5.1.0
    container_name: rmqnamesrv1
    ports:
      - "9876:9876"
    command: sh mqnamesrv
    networks:
      - rocketmq-net

  namesrv2:
    image: apache/rocketmq:5.1.0
    container_name: rmqnamesrv2
    ports:
      - "9877:9876"
    command: sh mqnamesrv
    networks:
      - rocketmq-net

  broker1:
    image: apache/rocketmq:5.1.0
    container_name: rmqbroker1
    ports:
      - "10911:10911"
    - "10909:10909"
    depends_on:
      - namesrv1
      - namesrv2
    environment:
      - NAMESRV_ADDR=namesrv1:9876;namesrv2:9876
    volumes:
      - ./broker1.conf:/home/rocketmq/rocketmq-5.1.0/conf/broker.conf
    command: sh mqbroker -c /home/rocketmq/rocketmq-5.1.0/conf/broker.conf
    networks:
      - rocketmq-net

networks:
  rocketmq-net:
    driver: bridge

集群管理

查看集群状态

# 使用 mqadmin 查看集群
./mqadmin clusterList -n 192.168.1.101:9876

# 输出示例:
# Cluster Name     #Broker Name            #Status  #Port
# DefaultCluster    broker-a                OK      10911
# DefaultCluster    broker-b                OK      10921

Topic 管理

# 创建 Topic
./mqadmin updateTopic -n 192.168.1.101:9876 \
    -t ORDER_TOPIC \
    -c DefaultCluster \
    -r 8 \
    -w 8

# 查看 Topic 路由
./mqadmin topicRoute -n 192.168.1.101:9876 -t ORDER_TOPIC

# 列出所有 Topic
./mqadmin topicList -n 192.168.1.101:9876

Broker 管理

# 查看 Broker 状态
./mqadmin brokerStatus -n 192.168.1.101:9876 -b broker-a

# 关闭 Broker
./mqadmin shutdownBroker -n 192.168.1.101:9876 -b broker-a

# 切换 Master
./mqadmin wipeWritePerm -n 192.168.1.101:9876 -b broker-a

高可用配置

Producer 高可用

/**
 * 高可用 Producer 配置
 */
public class HAProducer {

    private DefaultMQProducer producer;

    public void init() {
        producer = new DefaultMQProducer("ha-producer-group");
        
        // 多个 NameServer
        producer.setNamesrvAddr("192.168.1.101:9876;192.168.1.102:9876;192.168.1.103:9876");
        
        // 发送失败重试次数
        producer.setRetryTimesWhenSendFailed(3);
        
        // 异步发送失败重试
        producer.setRetryTimesWhenSendAsyncFailed(3);
        
        // 发送超时
        producer.setSendMsgTimeout(3000);
    }
}

Consumer 高可用

/**
 * 高可用 Consumer 配置
 */
public class HAConsumer {

    private DefaultMQPushConsumer consumer;

    public void init() {
        consumer = new DefaultMQPushConsumer("ha-consumer-group");
        
        // 多个 NameServer
        consumer.setNamesrvAddr("192.168.1.101:9876;192.168.1.102:9876;192.168.1.103:9876");
        
        // 订阅 Topic
        consumer.subscribe("ORDER_TOPIC", "*");
        
        // 消费模式
        consumer.setMessageModel(MessageModel.CLUSTERING);
        
        // 启动时从最新位置开始消费
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
        
        // 失败重试次数
        consumer.setMaxReconsumeTimes(3);
    }
}

监控集群

RocketMQ Dashboard

# 启动 Dashboard
docker run -d \
  --name rocketmq-dashboard \
  -p 8080:8080 \
  -e "ROCKETMQ_NAMESRV_ADDR=192.168.1.101:9876;192.168.1.102:9876;192.168.1.103:9876" \
  apacherocketmq/rocketmq-dashboard:latest

Prometheus 监控

# prometheus.yml
scrape_configs:
  - job_name: 'rocketmq'
    static_configs:
      - targets: ['192.168.1.101:5557']

下一步

接下来让我们学习控制台与运维。

👉 控制台与运维