Docker 部署 RocketMQ 雙主雙從模式( 版本v4.7.0)
文章轉載自:http://www.mydlq.club/article/96/
系統環境:
- 系統版本:CentOS 7.8
- RocketMQ 版本:4.7.0
- Docker 版本:19.03.13
一、RocketMQ 簡介
RocketMQ是一個純 Java、分散式、佇列模型的開源訊息中介軟體,前身是 MetaQ,是阿里參考 Kafka 特點研發的一個佇列模型的訊息中介軟體,後開源給 Apache 基金會成為了 Apache 的頂級開源專案,具有高效能、高可靠、高實時、分散式特點。
二、RocketMQ 需部署的元件
這裡介紹下 RocketMQ 相關的元件:
- 名字服務(Name Server): 是一個幾乎無狀態節點,可叢集部署,叢集節點間相互獨立沒有資訊交換。其功能主要為更新和發現 Broker 服務,生產者或消費者能夠通過其查詢到各主題相應的 Broker IP 列表。
- 代理服務(Broker Server): 訊息中轉角色,負責儲存訊息,轉發訊息。分為 Master Broker 和 Slave Broker,一個 Master Broker 可以對應多個 Slave Broker,但是一個 Slave Broker 只能對應一個 Master Broker。Broker 啟動後需要完成一次將自己註冊至 Name Server 的操作,隨後每隔 30s 定期 向Name Server 上報 Topic 路由資訊。
- 生產者: 與 Name Server 叢集中的其中一個節點(隨機)建立長連結(Keep-alive),定期從 Name Server 讀取 Topic 路由資訊,並向提供 Topic 服務的 Master Broker 建立長連結,且定時向 Master Broker 傳送心跳。
- 消費者: 與 Name Server 叢集中的其中一個節點(隨機)建立長連線,定期從 Name Server 拉取 Topic 路由資訊,並向提供 Topic 服務的 Master Broker、Slave Broker建立長連線,且定時向 Master Broker、Slave Broker 傳送心跳。Consumer 既可以從 Master Broker 訂閱訊息,也可以從 Slave Broker 訂閱訊息,訂閱規則由 Broker 配置決定。
- 控制檯(console): RocketMQ 的 Web 視覺化控制檯,包含 RocketMQ 常用操作,可以用於簡單管理 RocketMQ 平臺。
三、RocketMQ 常用部署模式
RocketMQ 常用部署方案有以下幾種:
- 單機模式
- 多主模式
- 雙主雙從/多主多從模式(非同步複製)
- 雙主雙從/多主多從模式(同步雙寫)
- Dledger 叢集模式
(1)、單機模式
這種模式就如該名單機模式一樣,就是部署單個 RocketMQ Broker 來使用,一般使用這種方式在生產中風險較大,一旦 Broker 重啟或者宕機時,會導致整個服務不可用,所以常常在學習、開發過程中才會使用這種模式。
優缺點分析:
優點: 本地開發測試,配置簡單,同步刷盤訊息不會丟失。
缺點: 不可靠,如果宕機會導致服務不可用。
(2)、多主模式
全部由 Broker Master 節點組成(即可能部署兩個或者更多 Broker),生產者傳送的資料會分別存入不同的 Broker 中,這樣能夠避免某個 Broker 一直接收處理資料從而負載過高。
優缺點分析:
優點: 效能高,配置簡單,單個 Master 宕機或重啟維護對應用無影響,在磁碟配置為 RAID10 時,即使機器宕機不可恢復,由於 RAID10 磁碟非常可靠,訊息也不會丟(非同步刷盤可能會丟失少量訊息,同步刷盤能保證訊息不丟)。
缺點: 單臺伺服器宕機期間,不可訂閱該伺服器上未被消費者消費的訊息,只有機器恢復後才可恢復訂閱,所以可能會影響訊息的實時性。
(3)、雙主雙從/多主多從模式(非同步複製)
一般會部署多個 Broker Master,同時也會為各個 Broker Master 部署一個或者多個 Broker Slave,且 Master 和 Slave 之間採用"非同步複製資料"方式進行資料同步(主從同步訊息會有延遲,毫秒級),這樣在生產者將訊息傳送到 Broker Master 後不必等待資料同步到 Slave 節點,就返回成功。
優缺點分析:
優點: 效能高,且磁碟損壞也不會丟失大量訊息,訊息實時性不會受影響,Master 宕機後,消費者仍然可以從 Slave 消費。
缺點: 主備有短暫訊息延遲,毫秒級,如果Master宕機,磁碟損壞情況,會丟失少量訊息。
(4)、雙主雙從/多主多從模式(同步雙寫)
一般會部署多個 Broker Master,同時也會為各個 Broker Master 部署一個或者多個 Broker Slave,且 Master 和 Slave 之間採用"同步複製資料"方式進行資料同步,這樣在生產者將訊息傳送到 Broker Master 後需要等待資料同步到 Slave 節點成功後,才返回成功。
優缺點分析:
優點: 資料與服務都無單點故障,Master 宕機情況下,訊息無延遲,服務可用性與資料可用性都非常高;
缺點: 效能比非同步複製模式略低(大約低10%左右),傳送單個訊息的 RT 會略高,且目前版本在主節點宕機後,備機不能自動切換為主機。
(5)、Dledger 叢集模式
RocketMQ-on-DLedger Group 是指一組相同名稱的 Broker,至少需要 3 個節點,通過 Raft 自動選舉出一個 Leader,其餘節點 作為 Follower,並在 Leader 和 Follower 之間複製資料以保證高可用。當 Master 節點出現問題宕機後也能自動容災切換,並保證資料一致性。該模式也支援 Broker 水平擴充套件,即可以部署任意多個 RocketMQ-on-DLedger Group 同時對外提供服務。
優缺點分析:
優點: 多節點(至少三個)組成叢集,其中一個為 Leader 節點,其餘為 Follower 節點組成高可用,能夠自動容災切換。
缺點: 需要 RocketMQ 4.5 及以後版本才支援。
四、RocketMQ 常見概念介紹
1、非同步複製與同步複製
在使用 RocketMQ 中,生產者叢集將資料傳入到 Broker Master 節點後,Master 節點會將資料同步到 Slave 節點,其有兩種同步方式:
- 非同步複製(SYNC_MASTER): 生產者將資料傳送到 Broker Master 節點後,Master 會直接使用非同步方式將資料同步到 Slave 節點,然後不等待 Slave 節點響應接收成功就直接告知生產者訊息接收成。
- 同步雙寫(SYNC_MASTER): 生產者將資料傳送到 Broker Master 節點後,Master 會使用同步方式將資料同步到 Slave 節點,然後等待 Slave 節點響應接收資料成功,然後再告知生產者訊息接收成。
2、同步刷盤與非同步刷盤
在使用 RocketMQ 中,生產者叢集將資料傳入到 Broker 後,Broker 會將資料進行持久化操作,其因效能與資料安全性等原因,所以提供兩種方式將資料持久化到硬碟,兩種刷盤方式分別是:
- 同步刷盤(SYNC_FLUSH): 生產者傳送的每一條訊息都在儲存到磁碟成功後才返回告訴生產者訊息傳送成功。這種方式不會存在訊息丟失的問題,但是有很大的磁碟 IO 開銷,對效能產生一些影響。
- 非同步刷盤(ASYNC_FLUSH): 生產者傳送的每一條訊息並不是立即儲存到磁碟,而是暫時快取到記憶體,然後就立即返回生產者,告知其訊息傳送成功。隨後再非同步的將快取資料儲存到磁碟,這裡分兩種情況:(1)、定期將快取中更新的資料進行刷盤。(2)、當快取中更新的資料條數達到某一設定值後進行刷盤。需要注意的是,這種方式都存在訊息可能丟失情況(在還未來得及同步到磁碟的時候宕機),不過由於其效能比"同步刷盤"要好,所以大多情況下都會選擇這種刷盤方式,且該方式也是 RocketMQ 的預設刷盤方式。
3、雙主雙從/多主多從模式
一般會部署多個 Broker Master,同時也會為各個 Broker Master 部署一個或者多個 Broker Slave,不過需要注意的是,當 Broker Master 宕機後,Broker Slave 並不能轉換為 Master 節點,這裡的 Slave 只會起到資料備份以及 Broker Master 宕機時間內消費者能夠繼續消費宕機前生產者傳送到 Broker Master 的資料。
多主多從模式下的 Broker 之間會進行資料同步,其中同步方式可以是"非同步複製",也可以是"同步複製"。這其中也會涉及資料持久化刷盤方式,刷盤方式也是分為"同步刷盤"與"非同步刷盤"兩種,資料複製與刷盤方式上面都有介紹,這裡就不再陳述。這裡主要要說的是其不同的"資料複製"與"刷盤方式"對效能的影響。例如,生產者將資料傳送到 Broker 後,如果為"同步刷盤"那麼只有將資料寫入磁碟成功後才能響應成功。如果為"非同步刷盤"那麼將資料寫入記憶體中即可返回成功。其中"同步刷盤"對效能影響較大。
使用多主多從模式部署 RocketMQ 的 Broker,一般我們大部分都會選擇"同步複製","非同步刷盤"方式的組合進行部署,當然,如果對資料安全性要求不是很高,可以選擇"非同步複製"與"非同步刷盤"方式來部署 Broker。
4、Broker 常用配置引數簡介
引數名 | 預設值 | 描述 |
---|---|---|
listenPort | 10911 | 監聽埠 |
namesrvAddr | Namesrv 地址 | |
brokerIP1 | 用於網路介面的 InetAddress | 指定 Broker 的 IP 地址,向 Namesrv 註冊時候會註冊此地址 |
brokerName | Broker 名稱 | |
brokerClusterName | 指定 Broker 歸屬的叢集的名稱 | |
brokerId | 0 | Broker ID, 0 表示 Master,大於 0 表示 Slave |
storePathCommitLog | $HOME/store/commitlog/ | commitlog 的檔案儲存路徑 |
storePathConsumerQueue | $HOME/store/consumequeue/ | comsumer queue 的檔案儲存路徑 |
mapedFileSizeCommitLog | 1024 * 1024 * 1024(1G) | commitlog 對映檔案大小 |
deleteWhen | 04 | 磁碟檔案空間充足情況下,預設每天什麼時候執行刪除過期檔案,預設 04 表示凌晨 4 點 |
fileReserverdTime | 72 | 設定 commitlog 日誌保留時間 |
brokerRole | ASYNC_MASTER | broker角色,分為 ASYNC_MASTER SYNC_MASTER, SLAVE |
flushDiskType | ASYNC_FLUSH | 刷盤方式,預設為 ASYNC_FLUSH(非同步刷盤),可選值SYNC_FLUSH(同步刷盤) |
五、部署 RcoketMQ 雙主雙從模式(同步雙寫)
部署伺服器安排
伺服器 | 部署的應用 | 物理資源 | 儲存目錄 |
---|---|---|---|
192.168.2.21 | Namesrv Server、Broker、Console | 4C && 8G | /usr/local/rocketmq |
192.168.2.22 | Namesrv Server、Broker | 4C && 8G | /usr/local/rocketmq |
192.168.2.23 | Namesrv Server、Broker | 4C && 8G | /usr/local/rocketmq |
部署的內容如下圖所示:
1、建立儲存資料的目錄
分別在 192.168.2.21、192.168.2.22 伺服器上執行下面命令建立目錄:
## 建立 Broker-Master 持久化目錄
$ mkdir -p /usr/local/rocketmq/broker-master/conf && \
mkdir -p /usr/local/rocketmq/broker-master/logs && \
mkdir -p /usr/local/rocketmq/broker-master/store
## 建立 Broker-Slave 持久化目錄
$ mkdir -p /usr/local/rocketmq/broker-slave/conf && \
mkdir -p /usr/local/rocketmq/broker-slave/logs && \
mkdir -p /usr/local/rocketmq/broker-slave/store
## 建立 NameServer 持久化目錄
$ mkdir -p /usr/local/rocketmq/server/logs
2、建立 Broker 配置檔案
在各個伺服器上分別建立如下檔案:
- 伺服器 192.168.2.21: 建立 master-a、slave-b 配置檔案
- 伺服器 192.168.2.22: 建立 master-b、slave-a 配置檔案
第一臺伺服器建立 master-a 配置:
$ cat > /usr/local/rocketmq/broker-master/conf/broker.conf << EOF
listenPort=10911
brokerIP1=192.168.2.21
brokerClusterName=DefaultCluster
brokerName=broker-a
brokerRole=SYNC_MASTER
brokerId=0
deleteWhen=04
fileReservedTime=48
flushDiskType=ASYNC_FLUSH
namesrvAddr=192.168.2.21:9876;192.168.2.22:9876
EOF
第一臺伺服器建立 slave-b 配置:
$ cat > /usr/local/rocketmq/broker-slave/conf/broker.conf << EOF
listenPort=11911
brokerIP1=192.168.2.21
brokerClusterName=DefaultCluster
brokerName=broker-b
brokerRole=SLAVE
brokerId=1
deleteWhen=04
fileReservedTime=48
flushDiskType=ASYNC_FLUSH
namesrvAddr=192.168.2.21:9876;192.168.2.22:9876
EOF
第二臺伺服器建立 master-b 配置:
$ cat > /usr/local/rocketmq/broker-master/conf/broker.conf << EOF
listenPort=10911
brokerIP1=192.168.2.22
brokerClusterName=DefaultCluster
brokerName=broker-b
brokerRole=SYNC_MASTER
brokerId=0
deleteWhen=04
fileReservedTime=48
flushDiskType=ASYNC_FLUSH
namesrvAddr=192.168.2.21:9876;192.168.2.22:9876
EOF
第二臺伺服器建立 slave-a 配置:
$ cat > /usr/local/rocketmq/broker-slave/conf/broker.conf << EOF
listenPort=11911
brokerIP1=192.168.2.22
brokerClusterName=DefaultCluster
brokerName=broker-a
brokerRole=SLAVE
brokerId=1
deleteWhen=04
fileReservedTime=48
flushDiskType=ASYNC_FLUSH
namesrvAddr=192.168.2.21:9876;192.168.2.22:9876
EOF
3、下載相關映象
在兩臺伺服器上,分別建立拉取對應的映象:
- 伺服器一 192.168.2.21: 拉取 rocketmq 與 rocketmq-console 映象。
- 伺服器二 192.168.2.22: 拉取 rocketmq 映象。
兩臺伺服器分別拉取 RocketMQ 映象:
## 下載 RocketMQ 映象
$ docker pull foxiswho/rocketmq:4.7.0
第一臺伺服器拉取 RocketMQ Console 映象:
## 下載 RocketMQ 控制檯
$ docker pull apacherocketmq/rocketmq-console:2.0.0
4、檢視映象設定的使用者與組的配置
任意一臺伺服器上檢視映象 rocketmq 的組成,分析其中使用者與組的資訊:
$ docker history foxiswho/rocketmq:4.7.0
IMAGE CREATED CREATED BY SIZE
1cf46e8f03d0 7 months ago /bin/sh -c #(nop) WORKDIR /home/rocketmq/roc… 0B
<missing> 7 months ago /bin/sh -c #(nop) USER rocketmq 0B
<missing> 7 months ago |5 gid=3000 group=rocketmq uid=3000 user=roc… 1.92kB
<missing> 7 months ago |5 gid=3000 group=rocketmq uid=3000 user=roc… 0B
<missing> 7 months ago |5 gid=3000 group=rocketmq uid=3000 user=roc… 11.3kB
<missing> 7 months ago /bin/sh -c #(nop) EXPOSE 10909 10911 10912 0B
<missing> 7 months ago |5 gid=3000 group=rocketmq uid=3000 user=roc… 10.1kB
<missing> 7 months ago /bin/sh -c #(nop) EXPOSE 9876 0B
<missing> 7 months ago |5 gid=3000 group=rocketmq uid=3000 user=roc… 15.1MB
<missing> 7 months ago /bin/sh -c #(nop) COPY dir:bdc4a8518539da6ce… 11.4kB
<missing> 7 months ago |5 gid=3000 group=rocketmq uid=3000 user=roc… 15.1MB
<missing> 7 months ago /bin/sh -c #(nop) WORKDIR /home/rocketmq/roc… 0B
<missing> 7 months ago /bin/sh -c #(nop) ENV ROCKETMQ_HOME=/home/r… 0B
<missing> 7 months ago /bin/sh -c #(nop) ENV ROCKETMQ_VERSION=4.7.0 0B
<missing> 7 months ago /bin/sh -c #(nop) ARG version=4.7.0 0B
<missing> 7 months ago |4 gid=3000 group=rocketmq uid=3000 user=roc… 1.07MB
<missing> 7 months ago /bin/sh -c #(nop) ARG gid=3000 0B
<missing> 7 months ago /bin/sh -c #(nop) ARG uid=3000 0B
<missing> 7 months ago /bin/sh -c #(nop) ARG group=rocketmq 0B
<missing> 7 months ago /bin/sh -c #(nop) ARG user=rocketmq 0B
<missing> 7 months ago /bin/sh -c yum install -y java-1.8.0-openjdk… 264MB
<missing> 11 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 11 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
<missing> 11 months ago /bin/sh -c #(nop) ADD file:45a381049c52b5664… 203MB
可以觀察到:
- 組名:rocketmq,組ID:3000
- 使用者名稱:rocketmq,使用者ID:3000
5、更改目錄歸屬組與使用者與容器的配置一致
兩臺伺服器上分別建立組與使用者:
## 建立組
$ groupadd rocketmq
## 增加使用者並加入組
$ useradd -g rocketmq rocketmq
## 設定使用者密碼
$ passwd rocketmq
## 更改組的 gid
$ groupmod -g 3000 rocketmq
## 更改使用者的 uid
$ usermod -u 3000 rocketmq
## 檢視是否更改成功
$ id rocketmq
兩臺伺服器上分別更改上面建立的目錄的許可權為上面建立的組與使用者:
$ chown -R rocketmq:rocketmq /usr/local/rocketmq
6、安裝 RocketMQ NameServer
兩臺伺服器上分別部署 NameServer:
$ docker run -d --name rmqnamesr --net host \
--restart=always \
-v /usr/local/rocketmq/server/logs:/home/rocketmq/logs \
-e "JAVA_OPT_EXT=-Xms512M -Xmx512M -Xmn128m" \
-p 9876:9876 \
foxiswho/rocketmq:4.7.0 \
sh mqnamesrv
7、安裝 RocketMQ Broker
分別在兩臺伺服器上執行下面命令,操作 Docker 啟動 Broker Master 與 Broker Slave 節點:
- 伺服器 192.168.2.21: Broker master-a、Broker slave-b
- 伺服器 192.168.2.22: Broker master-b、Broker slave-a
slave 的配置已經配置在 RocketMQ 配置檔案中
伺服器一部署 Broker master-a,伺服器二部署 Broker master-b 的 Docker 命令:
$ docker run -d --name rmqbroker-master \
--restart=always \
--net host \
-v /usr/local/rocketmq/broker-master/logs:/home/rocketmq/logs \
-v /usr/local/rocketmq/broker-master/store:/home/rocketmq/store \
-v /usr/local/rocketmq/broker-master/conf:/home/rocketmq/conf \
-p 10909:10909 -p 10911:10911 -p 10912:10912 \
-e "JAVA_OPT_EXT=-Xms512M -Xmx512M -Xmn128m" \
foxiswho/rocketmq:4.7.0 \
sh mqbroker -c /home/rocketmq/conf/broker.conf
伺服器一部署 Broker slave-b,伺服器二部署 Broker slave-a 的 Docker 命令:
$ docker run -d --name rmqbroker-slave \
--restart=always \
--net host \
-v /usr/local/rocketmq/broker-slave/logs:/home/rocketmq/logs \
-v /usr/local/rocketmq/broker-slave/store:/home/rocketmq/store \
-v /usr/local/rocketmq/broker-slave/conf:/home/rocketmq/conf \
-p 11909:11909 -p 11911:11911 -p 11912:11912 \
-e "JAVA_OPT_EXT=-Xms512M -Xmx512M -Xmn128m" \
foxiswho/rocketmq:4.7.0 \
sh mqbroker -c /home/rocketmq/conf/broker.conf
8、部署控制檯
伺服器一部署 RocketMQ 控制檯:
$ docker run -d --name rmqconsole \
--restart=always \
-p 8080:8080 \
-e "JAVA_OPTS=-Drocketmq.namesrv.addr=192.168.2.21:9876;192.168.2.22:9876 \
-Dcom.rocketmq.sendMessageWithVIPChannel=false" \
apacherocketmq/rocketmq-console:2.0.0
9、訪問控制檯
輸入 http://192.168.2.21:8080 訪問在伺服器一部署的 RocketMQ 控制檯:
然後我們可以通過該控制檯進行傳送訊息來驗證 RocketMQ 是否正常,這裡就交由大家自行驗證了,文件到此結束。