如果讓你為開發、測試環境分別搭一套哨兵和叢集模式的redis,你最快需要多久,或許你需要一天?2小時?事實是可以更短。 是的,你已經猜到了,用docker部署,真的只需要十幾分鍾。

一.準備工作

拉取redis映象

執行如下命令:

docker pull redis

該命令拉取的映象是官方映象,當然你可以搜尋其他的映象,這裡不做深入

檢視映象情況:

二.部署redis哨兵主從模式

什麼是哨兵模式?--請自行百度

1、什麼是docker compose?

Docker Compose 可以理解為將多個容器執行的方式和配置固化下來!

就拿最簡單的例子來說吧,如果我們要為我們的應用容器準備一個 MySQL 容器和一個 Redis 容器,那麼在每次啟動時,我們先要將 MySQL 容器和 Redis 容器啟動起來,再將應用容器執行起來。這其中還不要忘了在建立應用容器時將容器網路連線到 MySQL 容器和 Redis 容器上,以便應用連線上它們並進行資料交換。

這還不夠,如果我們還對容器進行了各種配置,我們最好還得將容器建立和配置的命令儲存下來,以便下次可以直接使用。

針對這種情況,我們就不得不引出在我們開發中最常使用的多容器定義和執行軟體,也就是 Docker Compose 了。

2、編寫reids主從docker-compose.yml

version: '3.7'
services:
master:
image: redis
container_name: redis-master
restart: always
command: redis-server --requirepass redispwd --appendonly yes
ports:
- 6379:6379
volumes:
- ./data1:/data
slave1:
image: redis
container_name: redis-slave-1
restart: always
command: redis-server --slaveof redis-master 6379 --requirepass redispwd --masterauth redispwd --appendonly yes
ports:
- 6380:6379
volumes:
- ./data2:/data
slave2:
image: redis
container_name: redis-slave-2
restart: always
command: redis-server --slaveof redis-master 6379 --requirepass redispwd --masterauth redispwd --appendonly yes
ports:
- 6381:6379
volumes:
- ./data3:/data

名詞解釋:

3、啟動主從redis

進入redis對應的docker-compose.yml的目錄,執行命令:

docker-compose up -d

-d表示後臺執行

使用命令docker ps命令檢視啟動結果:



出現截圖所示,表示執行成功

4.編寫哨兵docker-compose.yml

version: '3.7'
services:
sentinel1:
image: redis
container_name: redis-sentinel-1
restart: always
ports:
- 26379:26379
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
volumes:
- ./sentinel1.conf:/usr/local/etc/redis/sentinel.conf
sentinel2:
image: redis
container_name: redis-sentinel-2
restart: always
ports:
- 26380:26379
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
volumes:
- ./sentinel2.conf:/usr/local/etc/redis/sentinel.conf
sentinel3:
image: redis
container_name: redis-sentinel-3
ports:
- 26381:26379
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
volumes:
- ./sentinel3.conf:/usr/local/etc/redis/sentinel.conf
networks:
default:
external:
name: redis_default

5.編寫哨兵sentinel.conf

# 自定義叢集名,其中172.19.0.3 為 redis-master 的 ip,6379 為 redis-master 的埠,2 為最小投票數(因為有 3 臺 Sentinel 所以可以設定成 2)
port 26379
dir /tmp
sentinel monitor mymaster 172.19.0.3 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel auth-pass mymaster redispwd
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes

將上述檔案分別拷貝3份分別命名為sentinel1.conf、sentinel2.conf、sentinel3.conf與docker-compose.yml中的配置檔案對應,然後放置和哨兵的docker-compose.yml在同一目錄

6.啟動哨兵

進入哨兵docker-compose.yml所在目錄,執行命令:

docker-compose up -d

檢視容器,可以看到哨兵和主從redis都起來了

6.1哨兵啟動日誌



上述日誌中可以看出,哨兵監聽master和slave節點

6.2關掉master節點

通過命令停止redis的master節點

docker stop redis-master



通過上述日誌,我們可以看到sdown,odown,他們是什麼意思呢?

sdown是主觀宕機,就一個哨兵如果自己覺得一個master宕機了,那麼就是主觀宕機

odown是客觀宕機,如果quorum數量的哨兵都覺得一個master宕機了,那麼就是客觀宕機

然後就是開始選舉,從日誌可以看出兩個哨兵選擇了同一個slave節點,這時候滿足了我們配置最小投票數,那麼這臺slave就被選為新的master。

6.3重開master節點



上述日誌表明哨兵檢測到原master重新啟動,將原master節點變成新master的從節點

三.部署redis叢集模式

1、建立目錄和檔案

├── docker-compose.yml
├── redis-6371
│ ├── conf
│ │ └── redis.conf
│ └── data
├── redis-6372
│ ├── conf
│ │ └── redis.conf
│ └── data
├── redis-6373
│ ├── conf
│ │ └── redis.conf
│ └── data
├── redis-6374
│ ├── conf
│ │ └── redis.conf
│ └── data
├── redis-6375
│ ├── conf
│ │ └── redis.conf
│ └── data
└── redis-6376
├── conf
│ └── redis.conf
└── data

2、redis.conf 配置檔案

port 6371
cluster-enabled yes
cluster-config-file nodes-6371.conf
cluster-node-timeout 5000
appendonly yes
protected-mode no
requirepass 1234
masterauth 1234
cluster-announce-ip 10.12.12.10 # 這裡是宿主機IP
cluster-announce-port 6371
cluster-announce-bus-port 16371

每個節點的配置只需改變埠。

3、docker-compose 配置檔案

version: "3"

# 定義服務,可以多個
services:
redis-6371: # 服務名稱
image: redis # 建立容器時所需的映象
container_name: redis-6371 # 容器名稱
restart: always # 容器總是重新啟動
volumes: # 資料卷,目錄掛載
- ./redis-6371/conf/redis.conf:/usr/local/etc/redis/redis.conf
- ./redis-6371/data:/data
ports:
- 6371:6371
- 16371:16371
command:
redis-server /usr/local/etc/redis/redis.conf redis-6372:
image: redis
container_name: redis-6372
volumes:
- ./redis-6372/conf/redis.conf:/usr/local/etc/redis/redis.conf
- ./redis-6372/data:/data
ports:
- 6372:6372
- 16372:16372
command:
redis-server /usr/local/etc/redis/redis.conf redis-6373:
image: redis
container_name: redis-6373
volumes:
- ./redis-6373/conf/redis.conf:/usr/local/etc/redis/redis.conf
- ./redis-6373/data:/data
ports:
- 6373:6373
- 16373:16373
command:
redis-server /usr/local/etc/redis/redis.conf redis-6374:
image: redis
container_name: redis-6374
restart: always
volumes:
- ./redis-6374/conf/redis.conf:/usr/local/etc/redis/redis.conf
- ./redis-6374/data:/data
ports:
- 6374:6374
- 16374:16374
command:
redis-server /usr/local/etc/redis/redis.conf redis-6375:
image: redis
container_name: redis-6375
volumes:
- ./redis-6375/conf/redis.conf:/usr/local/etc/redis/redis.conf
- ./redis-6375/data:/data
ports:
- 6375:6375
- 16375:16375
command:
redis-server /usr/local/etc/redis/redis.conf redis-6376:
image: redis
container_name: redis-6376
volumes:
- ./redis-6376/conf/redis.conf:/usr/local/etc/redis/redis.conf
- ./redis-6376/data:/data
ports:
- 6376:6376
- 16376:16376
command:
redis-server /usr/local/etc/redis/redis.conf

編寫完成後使用docker-compose up -d啟動容器 ,這裡沒有使用主機模式(host),而是使用 NAT 模式,因為主機模式可能導致外部客戶端無法連線。

4、進入容器,建立叢集

上面只是啟動了 6 個 Redis 例項,並沒有構建成 Cluster 叢集。

執行docker exec -it redis-6371 bash進入一個 Redis 節點容器,隨便哪個都行。

繼續執行以下命令建立叢集:

# 叢集建立命令
redis-cli -a 1234 --cluster create 10.35.30.39:6371 10.35.30.39:6372 10.35.30.39:6373 10.35.30.39:6374 10.35.30.39:6375 10.35.30.39: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 10.35.30.39:6375 to 10.35.30.39:6371
Adding replica 10.35.30.39:6376 to 10.35.30.39:6372
Adding replica 10.35.30.39:6374 to 10.35.30.39:6373
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: e9a35d6a9d203830556de89f06a3be2e2ab4eee1 10.35.30.39:6371
slots:[0-5460] (5461 slots) master
M: 0c8755144fe6a200a46716371495b04f8ab9d4c8 10.35.30.39:6372
slots:[5461-10922] (5462 slots) master
M: fcb83b0097d2a0a87a76c0d782de12147bc86291 10.35.30.39:6373
slots:[10923-16383] (5461 slots) master
S: b9819797e98fcd49f263cec1f77563537709bcb8 10.35.30.39:6374
replicates fcb83b0097d2a0a87a76c0d782de12147bc86291
S: f4660f264f12786d81bcf0b18bc7287947ec8a1b 10.35.30.39:6375
replicates e9a35d6a9d203830556de89f06a3be2e2ab4eee1
S: d2b9f265ef7dbb4a612275def57a9cc24eb2fd5d 10.35.30.39:6376
replicates 0c8755144fe6a200a46716371495b04f8ab9d4c8
Can I set the above configuration? (type 'yes' to accept): yes # 這裡輸入 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 10.35.30.39:6371)
M: e9a35d6a9d203830556de89f06a3be2e2ab4eee1 10.35.30.39:6371
slots:[0-5460] (5461 slots) master
1 additional replica(s)
M: 0c8755144fe6a200a46716371495b04f8ab9d4c8 10.35.30.39:6372
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: b9819797e98fcd49f263cec1f77563537709bcb8 10.35.30.39:6374
slots: (0 slots) slave
replicates fcb83b0097d2a0a87a76c0d782de12147bc86291
M: fcb83b0097d2a0a87a76c0d782de12147bc86291 10.35.30.39:6373
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: f4660f264f12786d81bcf0b18bc7287947ec8a1b 10.35.30.39:6375
slots: (0 slots) slave
replicates e9a35d6a9d203830556de89f06a3be2e2ab4eee1
S: d2b9f265ef7dbb4a612275def57a9cc24eb2fd5d 10.35.30.39:6376
slots: (0 slots) slave
replicates 0c8755144fe6a200a46716371495b04f8ab9d4c8
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

看到上面的輸出即為 Cluster 叢集配置完成。且為 3 主 3 從。

總結:

以上就是通過docker compose方式部署哨兵模式和叢集模式的全過程,redis部署在docker中,適用於本地、開發、測試等環境,生產環境請慎用,除非你對docker有很強的掌控力。

關注我,下一篇繼續