Docker Compose 搭建 Redis Cluster 集羣環境

  在前文《Docker 搭建 Redis Cluster 集羣環境》中我已經教過你們如何搭建了,本文使用 Docker Compose 再帶你們搭建一遍,其目的主要是爲了讓你們感覺 Docker Compose 所帶來的便捷之處。node

  按照 Redis 官網:https://redis.io/topics/cluster-tutorial 的提示,爲了使 Docker 與 Redis Cluster 兼容,您須要使用 Docker 的 host 網絡模式。redis

  host 網絡模式須要在建立容器時經過參數 --net host 或者 --network host 指定,host 網絡模式可讓容器共享宿主機網絡棧,容器將不會虛擬出本身的網卡,配置本身的 IP 等,而是使用宿主機的 IP 和端口。docker

  關於 Docker 網絡模式更多的內容請閱讀《Docker 網絡模式詳解及容器間網絡通訊》。shell

  

環境

  

  爲了讓環境更加真實,本文使用多機環境:bash

  • 192.168.10.10
  • 192.168.10.11

  

  每臺機器所使用的基礎設施環境以下:網絡

  • CentOS 7.8.2003
  • Docker version 19.03.12

  

搭建

  

  總體搭建步驟主要分爲如下幾步:app

  • 下載 Redis 鏡像(其實這步能夠省略,由於建立容器時,若是本地鏡像不存在,就會去遠程拉取);
  • 編寫 Redis 配置文件;
  • 編寫 Docker Compose 模板文件;
  • 建立並啓動全部服務容器;
  • 建立 Redis Cluster 集羣。

  

編寫 Redis 配置文件

  

建立目錄及文件

  

  分別在 192.168.10.10192.168.10.11 兩臺機器上執行如下操做。函數

# 建立目錄
mkdir -p /usr/local/docker-redis/redis-cluster
# 切換至指定目錄
cd /usr/local/docker-redis/redis-cluster/
# 編寫 redis-cluster.tmpl 文件
vi redis-cluster.tmpl

  

編寫配置文件

  

  192.168.10.10 機器的 redis-cluster.tmpl 文件內容以下:學習

port ${PORT}
requirepass 1234
masterauth 1234
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
cluster-announce-ip 192.168.10.10
cluster-announce-port ${PORT}
cluster-announce-bus-port 1${PORT}

  192.168.10.11 機器的 redis-cluster.tmpl 文件內容以下:ui

port ${PORT}
requirepass 1234
masterauth 1234
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
cluster-announce-ip 192.168.10.11
cluster-announce-port ${PORT}
cluster-announce-bus-port 1${PORT}
  • port:節點端口;
  • requirepass:添加訪問認證;
  • masterauth:若是主節點開啓了訪問認證,從節點訪問主節點須要認證;
  • protected-mode:保護模式,默認值 yes,即開啓。開啓保護模式之後,需配置 bind ip 或者設置訪問密碼;關閉保護模式,外部網絡能夠直接訪問;
  • daemonize:是否以守護線程的方式啓動(後臺啓動),默認 no;
  • appendonly:是否開啓 AOF 持久化模式,默認 no;
  • cluster-enabled:是否開啓集羣模式,默認 no;
  • cluster-config-file:集羣節點信息文件;
  • cluster-node-timeout:集羣節點鏈接超時時間;
  • cluster-announce-ip:集羣節點 IP,填寫宿主機的 IP;
  • cluster-announce-port:集羣節點映射端口;
  • cluster-announce-bus-port:集羣節點總線端口。

  每一個 Redis 集羣節點都須要打開兩個 TCP 鏈接。一個用於爲客戶端提供服務的正常 Redis TCP 端口,例如 6379。還有一個基於 6379 端口加 10000 的端口,好比 16379。

  第二個端口用於集羣總線,這是一個使用二進制協議的節點到節點通訊通道。節點使用集羣總線進行故障檢測、配置更新、故障轉移受權等等。客戶端永遠不要嘗試與集羣總線端口通訊,與正常的 Redis 命令端口通訊便可,可是請確保防火牆中的這兩個端口都已經打開,不然 Redis 集羣節點將沒法通訊。

  

  在 192.168.10.10 機器的 redis-cluster 目錄下執行如下命令:

for port in `seq 6371 6373`; do \
  mkdir -p ${port}/conf \
  && PORT=${port} envsubst < redis-cluster.tmpl > ${port}/conf/redis.conf \
  && mkdir -p ${port}/data;\
done

  在 192.168.10.11 機器的 redis-cluster 目錄下執行如下命令:

for port in `seq 6374 6376`; do \
  mkdir -p ${port}/conf \
  && PORT=${port} envsubst < redis-cluster.tmpl > ${port}/conf/redis.conf \
  && mkdir -p ${port}/data;\
done

上面兩段 shell for 語句,意思就是循環建立 6371 ~ 6376 相關的目錄及文件。

  

  在 192.168.10.10 機器執行查看命令結果以下,若是沒有 tree 命令先安裝 yum install -y tree

  在 192.168.10.11 機器執行查看命令結果以下。

  

  如下內容爲每一個節點的配置文件詳細信息。

============================== 192.168.10.10 ==============================
[root@localhost redis-cluster]# cat /usr/local/docker-redis/redis-cluster/637{1..3}/conf/redis.conf
port 6371
requirepass 1234
masterauth 1234
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
cluster-announce-ip 192.168.10.10
cluster-announce-port 6371
cluster-announce-bus-port 16371

port 6372
requirepass 1234
masterauth 1234
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
cluster-announce-ip 192.168.10.10
cluster-announce-port 6372
cluster-announce-bus-port 16372

port 6373
requirepass 1234
masterauth 1234
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
cluster-announce-ip 192.168.10.10
cluster-announce-port 6373
cluster-announce-bus-port 16373
============================== 192.168.10.10 ==============================

============================== 192.168.10.11 ==============================
[root@localhost redis-cluster]# cat /usr/local/docker-redis/redis-cluster/637{4..6}/conf/redis.conf
port 6374
requirepass 1234
masterauth 1234
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
cluster-announce-ip 192.168.10.11
cluster-announce-port 6374
cluster-announce-bus-port 16374

port 6375
requirepass 1234
masterauth 1234
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
cluster-announce-ip 192.168.10.11
cluster-announce-port 6375
cluster-announce-bus-port 16375

port 6376
requirepass 1234
masterauth 1234
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
cluster-announce-ip 192.168.10.11
cluster-announce-port 6376
cluster-announce-bus-port 16376
============================== 192.168.10.11 ==============================

  

編寫 Docker Compose 模板文件

  

  在 192.168.10.10 機器的 /usr/local/docker-redis 目錄下建立 docker-compose.yml 文件並編輯。

# 描述 Compose 文件的版本信息
version: "3.8"

# 定義服務,能夠多個
services:
  redis-6371: # 服務名稱
    image: redis # 建立容器時所需的鏡像
    container_name: redis-6371 # 容器名稱
    restart: always # 容器老是從新啓動
    network_mode: "host" # host 網絡模式
    volumes: # 數據卷,目錄掛載
      - /usr/local/docker-redis/redis-cluster/6371/conf/redis.conf:/usr/local/etc/redis/redis.conf
      - /usr/local/docker-redis/redis-cluster/6371/data:/data
    command: redis-server /usr/local/etc/redis/redis.conf # 覆蓋容器啓動後默認執行的命令

  redis-6372:
    image: redis
    container_name: redis-6372
    network_mode: "host"
    volumes:
      - /usr/local/docker-redis/redis-cluster/6372/conf/redis.conf:/usr/local/etc/redis/redis.conf
      - /usr/local/docker-redis/redis-cluster/6372/data:/data
    command: redis-server /usr/local/etc/redis/redis.conf

  redis-6373:
    image: redis
    container_name: redis-6373
    network_mode: "host"
    volumes:
      - /usr/local/docker-redis/redis-cluster/6373/conf/redis.conf:/usr/local/etc/redis/redis.conf
      - /usr/local/docker-redis/redis-cluster/6373/data:/data
    command: redis-server /usr/local/etc/redis/redis.conf

  

  在 192.168.10.11 機器的 /usr/local/docker-redis 目錄下建立 docker-compose.yml 文件並編輯。

# 描述 Compose 文件的版本信息
version: "3.8"

# 定義服務,能夠多個
services:
  redis-6374: # 服務名稱
    image: redis # 建立容器時所需的鏡像
    container_name: redis-6374 # 容器名稱
    restart: always # 容器老是從新啓動
    network_mode: "host" # host 網絡模式
    volumes: # 數據卷,目錄掛載
      - /usr/local/docker-redis/redis-cluster/6374/conf/redis.conf:/usr/local/etc/redis/redis.conf
      - /usr/local/docker-redis/redis-cluster/6374/data:/data
    command: redis-server /usr/local/etc/redis/redis.conf # 覆蓋容器啓動後默認執行的命令

  redis-6375:
    image: redis
    container_name: redis-6375
    network_mode: "host"
    volumes:
      - /usr/local/docker-redis/redis-cluster/6375/conf/redis.conf:/usr/local/etc/redis/redis.conf
      - /usr/local/docker-redis/redis-cluster/6375/data:/data
    command: redis-server /usr/local/etc/redis/redis.conf

  redis-6376:
    image: redis
    container_name: redis-6376
    network_mode: "host"
    volumes:
      - /usr/local/docker-redis/redis-cluster/6376/conf/redis.conf:/usr/local/etc/redis/redis.conf
      - /usr/local/docker-redis/redis-cluster/6376/data:/data
    command: redis-server /usr/local/etc/redis/redis.conf

  

建立並啓動全部服務容器

  

  分別在 192.168.10.10192.168.10.11 機器的 /usr/local/docker-redis 目錄下執行如下命令:

docker-compose up -d

  

建立 Redis Cluster 集羣

  

  請先確保你的兩臺機器能夠互相通訊,而後隨便進入一個容器節點,並進入 /usr/local/bin/ 目錄:

# 進入容器
docker exec -it redis-6371 bash
# 切換至指定目錄
cd /usr/local/bin/

  

  接下來咱們就能夠經過如下命令實現 Redis Cluster 集羣的建立。

redis-cli -a 1234 --cluster create 192.168.10.10:6371 192.168.10.10:6372 192.168.10.10:6373 192.168.10.11:6374 192.168.10.11:6375 192.168.10.11:6376 --cluster-replicas 1

  

  出現選擇提示信息,輸入 yes,結果以下所示:

  集羣建立成功以下:

  

  如下內容是建立集羣時返回的詳細信息,也就是上兩幅圖中的全部內容。

root@localhost:/usr/local/bin# redis-cli -a 1234 --cluster create 192.168.10.10:6371 192.168.10.10:6372 192.168.10.10:6373 192.168.10.11:6374 192.168.10.11:6375 192.168.10.11:6376 --cluster-replicas 1
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.10.11:6376 to 192.168.10.10:6371
Adding replica 192.168.10.10:6373 to 192.168.10.11:6374
Adding replica 192.168.10.11:6375 to 192.168.10.10:6372
M: 04444afa3ca66de6af4a182984c79d4d140293d7 192.168.10.10:6371
   slots:[0-5460] (5461 slots) master
M: fb76ada83a70ea8d367f22f8a6436d427f12022c 192.168.10.10:6372
   slots:[10923-16383] (5461 slots) master
S: 20f6913a4b08afe3b4092a4f6c70fddd9506f2fa 192.168.10.10:6373
   replicates c130120ffbd7c4e442ac9fc9870e977dc801cb54
M: c130120ffbd7c4e442ac9fc9870e977dc801cb54 192.168.10.11:6374
   slots:[5461-10922] (5462 slots) master
S: d4d5f7fd94fcd2239e82e481f0529380b288ff51 192.168.10.11:6375
   replicates fb76ada83a70ea8d367f22f8a6436d427f12022c
S: e08b8f629e2dfa474a836910634052d83c77d06a 192.168.10.11:6376
   replicates 04444afa3ca66de6af4a182984c79d4d140293d7
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.
>>> Performing Cluster Check (using node 192.168.10.10:6371)
M: 04444afa3ca66de6af4a182984c79d4d140293d7 192.168.10.10:6371
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: 20f6913a4b08afe3b4092a4f6c70fddd9506f2fa 192.168.10.10:6373
   slots: (0 slots) slave
   replicates c130120ffbd7c4e442ac9fc9870e977dc801cb54
S: d4d5f7fd94fcd2239e82e481f0529380b288ff51 192.168.10.11:6375
   slots: (0 slots) slave
   replicates fb76ada83a70ea8d367f22f8a6436d427f12022c
M: fb76ada83a70ea8d367f22f8a6436d427f12022c 192.168.10.10:6372
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: c130120ffbd7c4e442ac9fc9870e977dc801cb54 192.168.10.11:6374
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: e08b8f629e2dfa474a836910634052d83c77d06a 192.168.10.11:6376
   slots: (0 slots) slave
   replicates 04444afa3ca66de6af4a182984c79d4d140293d7
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

  

  至此一個高可用的 Redis Cluster 集羣搭建完成,以下圖所示,該集羣中包含 6 個 Redis 節點,3 主 3 從。三個主節點會分配槽,處理客戶端的命令請求,而從節點可用在主節點故障後,頂替主節點。

  

查看集羣狀態

  

  咱們先進入容器,而後經過一些集羣經常使用的命令查看一下集羣的狀態。

# 進入容器
docker exec -it redis-6371 bash
# 切換至指定目錄
cd /usr/local/bin/

  

檢查集羣狀態

  

redis-cli -a 1234 --cluster check 192.168.10.11:6375

  

查看集羣信息和節點信息

  

# 鏈接至集羣某個節點
redis-cli -c -a 1234 -h 192.168.10.11 -p 6376
# 查看集羣信息
cluster info
# 查看集羣結點信息
cluster nodes

  

SET/GET

  

  在 6371 節點中執行寫入和讀取,命令以下:

# 進入容器並鏈接至集羣某個節點
docker exec -it redis-6371 /usr/local/bin/redis-cli -c -a 1234 -h 192.168.10.10 -p 6371
# 寫入數據
set name mrhelloworld
set aaa 111
set bbb 222
# 讀取數據
get name
get aaa
get bbb

  彆着急,讓我來解釋一下上圖中的操做過程:

  • 首先進入容器並鏈接至集羣某個節點;
  • 而後執行第一個 set 命令 set name mrhelloworldname 鍵根據哈希函數運算之後獲得的值爲 [5798]。當前集羣環境的槽分配狀況爲:[0-5460] 6371節點[5461-10922] 6374節點[10923-16383] 6372節點,因此該鍵的存儲就被分配到了 6374 節點上;
  • 再來看第二個 set 命令 set aaa,這裏你們可能會有一些疑問,爲何看不到 aaa 鍵根據哈希函數運算之後獲得的值?由於剛纔重定向至 6374 節點插入了數據,此時若是還有數據插入,正好鍵根據哈希函數運算之後獲得的值也還在該節點的範圍內,那麼直接插入數據便可;
  • 接着是第三個 set 命令 set bbbbbb 鍵根據哈希函數運算之後獲得的值爲 [5287],因此該鍵的存儲就被分配到了 6371 節點上;
  • 而後是讀取操做,第四個命令 get namename 鍵根據哈希函數運算之後獲得的值爲 [5798],被重定向至 6374 節點讀取;
  • 第五個命令 get aaaaaa 鍵根據哈希函數運算之後獲得的值也在 6374 節點,直接讀取;
  • 第六個命令 get bbbbbb 鍵根據哈希函數運算之後獲得的值爲 [5287],被重定向至 6371 節點讀取。

  

  經過以上操做咱們得知 name 鍵的存儲被分配到了 6374 節點,若是直接鏈接 6374 節點並獲取該值會怎麼樣?沒錯,不須要重定向節點,由於數據就在該節點,因此直接讀取返回。

  

客戶端鏈接

  

  最後來一波客戶端鏈接操做,隨便哪一個節點,看看能否經過外部訪問 Redis Cluster 集羣。

  至此使用多機環境基於 Docker Compose 搭建 Redis Cluster 就到這裏。雖然總體搭建過程感受比起以前並無簡化太多。可是,若是咱們想要中止並刪除 Redis Cluster 集羣環境,以前的方式就須要一個個去操做,而 Docker Compose 只須要一個 docker-compose down 命令的操做便可。Docker Compose 的學習及使用就到這裏,下文開始咱們學習 Docker Swarm 的相關內容。

本文采用 知識共享「署名-非商業性使用-禁止演繹 4.0 國際」許可協議

你們能夠經過 分類 查看更多關於 Docker 的文章。

  

🤗 您的點贊轉發是對我最大的支持。

📢 掃碼關注 哈嘍沃德先生「文檔 + 視頻」每篇文章都配有專門視頻講解,學習更輕鬆噢 ~

相關文章
相關標籤/搜索