序言
在目前我參與開發的程式碼倉庫中,當需要使用 Redis 時,基本上用的都是 Redis 叢集。因此,我在辦公電腦上也搭建了一個 Redis 叢集,以便讓我為這些倉庫編寫的單元測試能成功執行起來。
儘管 Redis 官方提供了部署叢集的指引,但這要求團隊內的每位成員都要依次執行如下操作:
用 Homebrew 安裝 Redis;
建立 6 個目錄;
建立 6 份
redis.conf
配置檔案;啟動 6 個
redis-server
程序;用
redis-cli
建立叢集。
爲了可以讓更多的人願意執行單元測試,必須要降低部署 Redis 叢集的操作難度。因此,本文旨在提供一種基於 Docker 的、一鍵部署 Redis 叢集的辦法。
啟動單個 Redis 容器
Redis 叢集需要至少 6 個例項,那麼首先要解決的問題便是如何啟動單個 Redis 容器。從前文提到的部署叢集的指引中可以知道,要啟動一個叢集模式的 Redis 例項,所需要的配置檔案redis.conf
的內容如下
port 8000 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes
參考官方的 redis 映象的文件的方式,讓redis-server
讀取來自於宿主機的配置檔案,示例程式碼如下
# 選項 --rm 使該容器在退出後(例如按下 ctrl-c)可以被刪除,畢竟這裏只是先做個演示,不需要留下它。 sudo docker run --rm -v "`pwd`:/usr/local/etc/redis" redis redis-server "/usr/local/etc/redis/redis.conf"
效果如下圖所示
啟動 6 個 Redis 容器
接下來以相似的方式啟動全部的 6 個 Redis 容器。首先建立 6 個目錄
# 這裏我用 Redis 監聽的埠號作為目錄名,但這並非強制要求。 mkdir 8000 8001 8002 8003 8004 8005
然後在每一個目錄中都建立配置檔案redis.conf
for port in 8000 8001 8002 8003 8004 8005 ; do cat << EOF > "./${port}/redis.conf" port ${port} cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes EOF done
最後啟動它們
# 建立出名為 some-network 的容器間網路。 docker network create some-network for port in 8000 8001 8002 8003 8004 8005 ; do # --name 選項讓這 6 個容器擁有確定的且不同的主機名,以便之後可以在 redis-cli 中指定它們。 # --network 選項讓這 6 個容器處於同一個網路下,以便叢集內的節點可以互相通訊。 docker run --name "some-redis-${port}" --network some-network --rm -d -v "`pwd`/${port}:/usr/local/etc/redis" redis redis-server '/usr/local/etc/redis/redis.conf' done
效果如下圖所示
建立叢集
此時 6 個執行中的 Redis 例項還不構成一個叢集,還需要執行redis-cli
的命令--cluster create
才行。
# 給 redis-cli 的選項 --cluster-yes 使其預設接受叢集內節點的分配情況。這在指令碼執行、無法透過標準輸出敲入 yes 的時候很有用。 docker run --network some-network --rm -i -t redis redis-cli --cluster create some-redis-8000:8000 some-redis-8001:8001 some-redis-8002:8002 some-redis-8003:8003 some-redis-8004:8004 some-redis-8005:8005 --cluster-replicas 1 --cluster-yes
但命令--cluster create
並非冪等的,只能在建立叢集的時候使用一次。因此,如果希望透過指令碼一鍵搭建、啟動叢集,則必須在建立前先檢查叢集是否曾經被建立過。藉助redis-cli
的命令--cluster check
可以實現
docker run --network some-network --rm -i -t redis redis-cli --cluster check some-redis-8000:8000 | grep 'All 16384 slots covered.' > /dev/null if [[ "$?" == '0' ]]; then echo "Redis 叢集已經建立好了。" else echo "開始建立 Redis 叢集。" docker run --network some-network --rm -i -t redis redis-cli --cluster create some-redis-8000:8000 some-redis-8001:8001 some-redis-8002:8002 some-redis-8003:8003 some-redis-8004:8004 some-redis-8005:8005 --cluster-replicas 1 --cluster-yes fi
建立成功後,只要新的容器也使用網路some-network
,就可以讀寫叢集中的資料了
docker run --network some-network --rm -i -t redis redis-cli -c -h some-redis-8000 -p 8000
效果如下圖所示
總結
我將上面的內容整合到了redis_cluster
這個 GitHub 倉庫中,只需要克隆到本地並執行指令碼start.sh
即可,效果如下圖所示
全文完。