文章目錄
使用 docker 建立 Redis Cluster - 更新版
請參考新版內容 使用 Docker Compose 建立 Redis Cluster
之前筆記 使用 docker 建立 Redis Cluster 成功建立了 redis cluster,也測試過 sentinel 可以正常 failover,興高采烈測試程式碼時才發現有 bug:在加入 cluster 時使用的是 container ip 與 port (因為 redis cluster 不支援使用 host name),以致 redis key 在不同 slot 間無法正確做移動,所以我們馬上來看看可以如何解決吧
基本環境說明
- macOS Mojave 10.14.2
- Docker Community 18.09.2
- docker-compose version 1.23.2, build 1110ad01
- docker-py version: 3.6.0
- CPython version: 3.6.6
- OpenSSL version: OpenSSL 1.1.0h 27 Mar 2018
測試用程式碼
|
|
錯誤訊息
訊息內容
1Key has MOVED from Endpoint 172.19.0.2:6379 and hashslot 4768 but CommandFlags.NoRedirect was specified - redirect not followed for SET test1. IOCP: (Busy=0,Free=1000,Min=8,Max=1000), WORKER: (Busy=0,Free=1023,Min=8,Max=1023), Local-CPU: n/a錯誤截圖
Master 與 Slave node :內容相同
準備 redis config
redis 預設未啟用 cluster,需要透過 config 來啟用
1234567891011121314# 指定 redis portport 6379# 啟用 clustercluster-enabled yes# 指定 cluster config 檔案cluster-config-file nodes.conf# 指定 node 無法連線時間cluster-node-timeout 5000# 更新操作後進行日誌記錄# appendonly yes# 設定連線至 master 密碼masterauth pass.123# 設定連線密碼requirepass pass.123準備 dockerfile
使用上述建立的 config 來啟動 redis
1234567FROM redis:5.0.3-alpine3.9MAINTAINER Yowko Tsai <yowko@yowko.com>EXPOSE 6379 16379COPY rediscluster.conf /etc/redis/rediscluster.confENTRYPOINT redis-server /etc/redis/rediscluster.conf
Sentinel node :內容不變
準備 sentinel 用的 config
因為 redis cluster 有三個 node,所以 sentinel 需加入三組 replication 的 monitor
1234567891011121314151617181920212223# sentinel portport 26379# bind ipbind 0.0.0.0# 監控的 redis master host 與 port,並指定兩個 sentinel 同意決定sentinel monitor mymaster1 redis-master1 6379 2# 無法連線 3000 毫秒,判定為離線sentinel down-after-milliseconds mymaster1 3000# 同時可以從 master 拉取資料的 slave 個數為 1sentinel parallel-syncs mymaster1 1# sentinel 執行 failover 失敗時間為 10000 毫秒sentinel failover-timeout mymaster1 10000sentinel monitor mymaster2 redis-master2 6379 2sentinel down-after-milliseconds mymaster2 3000sentinel parallel-syncs mymaster2 1sentinel failover-timeout mymaster2 10000sentinel monitor mymaster3 redis-master3 6379 2sentinel down-after-milliseconds mymaster3 3000sentinel parallel-syncs mymaster3 1sentinel failover-timeout mymaster3 10000準備 dockerfile
使用上述的 sentinel config 來啟動 sentinel
1234567FROM redis:5.0.3-alpine3.9MAINTAINER Yowko Tsai <yowko@yowko.com>EXPOSE 26379COPY sentinel.conf /etc/redis/sentinel.confENTRYPOINT redis-server /etc/redis/sentinel.conf --sentinel
Cluster Creator node :內容不變
- 這邊使用固定 ip,因為 redis 使用 container name 建立 cluster 時會出現無法解析的錯誤,固定 ip 的綁定則會透過 docker-compose 處理
- 透過 redis-cli 建立 cluster 是 redis 5 加入的功能,已經無法使用 redis-trib.rb
建立 cluster 時需要輸入
yes
確認加入12345FROM redis:5.0.3-alpine3.9MAINTAINER Yowko Tsai <yowko@yowko.com>ENTRYPOINT echo "yes"|redis-cli -a pass.123 --cluster create 172.19.0.2:6379 172.19.0.3:6379 172.19.0.4:6379 172.19.0.5:6379 172.19.0.6:6379 172.19.0.7:6379 --cluster-replicas 1
docker-compose :設定改變 - 移除 port mapping
我嘗試透過 host 做 port forward ,但在 cluster join 時一直 hang 在 wait to join 畫面,查官方文件提到除了 redis port 之外,還需要 redis port + 10000 為 redis cluster bus 使用的 port,解決方式就是直接使用 container ip 來設定 cluster
|
|
資料夾結構:內容相同
資料夾及檔案名稱只是範例,不需相同
|
|
建立 Redis Cluster 並確認運作正常:內容相同
進入
docker-redis-cluster
資料夾中1cd docker-redis-cluster啟動 Redis Cluster
1docker-compose up -d --build確認 Redis Cluster 正確設定
出現
cluster_state:ok
即是正確設定1docker exec -it redis-master1 redis-cli -a pass.123 -c cluster info
加入 ip route rule :新增動作
讓 host 可以透過 container ip 直接 access 相關服務
以 Docker for Windows 為例
1route add 172.19.0.0 MASK 255.255.255.0 10.0.75.2Docker for Mac 不支援該作法
實際使用
測試用程式碼
redis 連線改用 container ip
1234var configString= "172.19.0.2:6379,172.19.0.3:6379,172.19.0.4:6379,172.19.0.5:6379,172.19.0.6:6379,172.19.0.7:6379,password=pass.123,connectTimeout=10000,configCheckSeconds=3,allowAdmin=true";ConfigurationOptions options = ConfigurationOptions.Parse(configString);var conn = ConnectionMultiplexer.Connect(options);conn.GetDatabase().StringSetAsync("test3","test123").ConfigureAwait(false).GetAwaiter().GetResult().Dump();依 key 將資料儲存至不同 node 上
心得
一心一意想要用 redis 5 來建立 cluster,結果反而最重要的功能沒有設定好,實在糟糕,幸虧沒有花太多時間發現問題,只是解法上依舊不甚滿意,尤其是 Docker for Mac 不支援:因為 Docker for Mac 與 Docker for Windows 及 Linux 不同,docker0 的網卡存在 vm 內部,沒辦法透過 ip route 來處理
詳細的檔案內容都在:yowko/docker-redis-5-cluster
請參考新版內容 使用 Docker Compose 建立 Redis Cluster
參考資訊
文章作者 Yowko Tsai
上次更新 2020-12-11
授權合約
本部落格 (Yowko's Notes) 所有的文章內容(包含圖片),任何轉載行為,必須通知並獲本部落格作者 (Yowko Tsai) 的同意始得轉載,且轉載皆須註明出處與作者。
Yowko's Notes 由 Yowko Tsai 製作,以創用CC 姓名標示-非商業性-相同方式分享 3.0 台灣 授權條款 釋出。