# 在Windows中使用Docker建立Redis (單機 & 主從 & 哨兵 & 分段叢集) ## Docker 安裝 1. 下載舊版DockerDestop for Windows 2.0.0.3並安裝[https://download.docker.com/win/stable/31259/Docker%20for%20Windows%20Installer.exe](https://) 2. 開啟Docker,從右下角Docker圖是可以看到Docker是否運行。 3. 開啟後請先對route進行設置,請參考[https://www.cnblogs.com/brock0624/p/9788710.html](https://),進行設置。 ## Redis 單機(Standalone) 1. 先使用docker下載redis映像 ``` docker pull redis:5.0 //redis後方可以指定版本 ``` 2. 開始創建redis容器 創建後會出現一組此Redis容器的ID ``` docker run --name MyRedis -p 6379:6379 -d redis:5.0 ``` 3. 測試/驗證 此處為對此容器進行指令 ``` docker exec -it MyRedis bash ``` 使用Redis cli輸入指令 ``` redis-cli ``` 透過基本的 SET / GET 指令確認服務是否正常 ``` <127.0.0.1:6379>set name Toms //設定一個key為name value為Toms的資料 OK <127.0.0.1:6379>get name //取出key為name的value "Toms" ``` ## Reids 主從結構(Master-Slave) #### 主從結構有多個方法可以建構,此處使用conf配置跟docker命令進行實作。 ##### 兩者的差異就在一個為引用已寫好的redis.conf來建立redis容器,另一個為用docker將配置寫入redis.conf ### Conf配置 透過redis.conf來建立redis容器 請先下載redis.conf [http://download.redis.io/redis-stable/redis.conf](https://),將他放置在特定資料夾中。 開始配置redis.conf----Master ``` bash bind 0.0.0.0 //接受所有ip請求,測試用 protected-mode no //關閉保護模式 port 6379 //監聽port ``` 開始配置redis.conf----Slave ``` bash port 6380 //監聽port replicaof 172.17.0.1 6379 //此處為redismaster ip請在master創建之後進Docker看他的IPAddress replica-read-only yes //只允許從節點讀取 ``` --- --restart=always : Container會隨者Docker開啟而開啟\ -v C:/work/redis/redisConf/redisMaster.conf:/redis.conf 將redisMaster.conf替代redis.conf 此為一主一從配置。 配置完成後開始創建redis容器 ---- Master ``` bash docker run -p 6379:6379 --name redis-master -v C:/work/redis/redisConf/redisMaster.conf:/redis.conf -d --restart=always redis:5.0 redis-server /redis.conf ``` 配置完成後開始創建redis容器 ---- Slave ``` bash docker run -p 6380:6380 --name redis-slave -v C:/work/redis/redisConf/redisSlave1.conf:/redis.conf -d --restart=always redis:5.0 redis-server /redis.conf ``` ### Docker 命令 #### 透過直接在docker命令中輸入配置來建立主從關係 1. 現在docker中建立Network ``` bash docker network create redis-network ``` 2. 建立redis-master 主節點redis ``` bash docker run -d --name redis-master --network redis-network -p 6379:6379 redis ``` 3. 建立額外兩個從節點 redis-slave ``` bash docker run -d --name redis-slave1 --network redis-network -p 6380:6379 redis:5.0 redis-server --slaveof redis-master 6379 docker run -d --name redis-slave2 --network redis-network -p 6381:6379 redis:5.0 redis-server --slaveof redis-master 6379 ``` 4. 測試/驗證 此處可看到master節點有兩個connected_slave ``` bash docker exec -it redis-master bash root@91b4e61ecc1b:/data# redis-cli 127.0.0.1:6379> info replication # Replication role:master connected_slaves:2 slave0:ip=172.50.0.3,port=6379,state=online,offset=8061,lag=0 slave1:ip=172.50.0.4,port=6379,state=online,offset=8061,lag=1 ``` ## Redis 哨兵結構(Sentinel) ### Docker Redis Sentinel 此部分會沿用前面主從結構一主二從後新增三哨兵來實做,Sentinel做的事情只負責監視Master跟Slave跟做故障切換僅此而已,而在Redis Manager 中可以利用Sentinel連進DB只是因為她去找誰是現在的Master而已。在Docker中此方法不可行因為Sentinel.conf紀錄的Master ip 是Docker中的Linux ip Windows會連不進去導致錯誤。 1. 製作sentinel.conf ``` bash protected-mode no port 26379 daemonize no pidfile /var/run/redis-sentinel.pid loglevel notice dir /tmp sentinel monitor mymaster 172.17.0.1 6379 2 //此處的172.17.0.1 6379 為 master ip | 2 為 sentinel 投票2票以上時才會判定此服務器當機 sentinel down-after-milliseconds mymaster 5000 //判斷失聯超過多少毫秒判定為當機 ``` 如果此處master有設置密碼請加上 ``` bash sentinel auth-pass mymaster <password> ``` 2. 創建Sentinel的Container ``` bash docker run -p 26379:26379 --name redis-sentinel1 -v C:/work/redis/redisConf/sentinel1.conf:/etc/redis/sentinel.conf -d redis:5.0 redis-sentinel /etc/redis/sentinel.conf docker run -p 26380:26380 --name redis-sentinel2 -v C:/work/redis/redisConf/sentinel2.conf:/etc/redis/sentinel.conf -d redis:5.0 redis-sentinel /etc/redis/sentinel.conf docker run -p 26381:26381 --name redis-sentinel3 -v C:/work/redis/redisConf/sentinel3.conf:/etc/redis/sentinel.conf -d redis:5.0 redis-sentinel /etc/redis/sentinel.conf ``` 3. 測試/驗證 將redis-master關閉 查看sentinel的log可以看到他將master轉為172.17.0.4這個從節點 ![](https://hackmd.io/_uploads/HkIy7_cZT.png) 將redis-master開啟 查看sentinel的log可以看到他監測到172.17.0.2脫離sdown狀態並將master從172.17.0.4轉為172.17.0.2 ![](https://hackmd.io/_uploads/B12M7u9ZT.png) --- ### Windows Redis Sentinel ``` C:/Redis/6381/redis-server.exe --service-install C:/Redis/6381/redis.windows.conf --service-name redis6381 C:/Redis/6382/redis-server.exe --service-install C:/Redis/6382/redis.windows.conf --service-name redis6382 C:/Redis/6383/redis-server.exe --service-install C:/Redis/6383/redis.windows.conf --service-name redis6383 C:/Redis/6384/redis-server.exe --service-install C:/Redis/6384/redis.windows.conf --service-name redis6384 C:/Redis/6385/redis-server.exe --service-install C:/Redis/6385/redis.windows.conf --service-name redis6385 sc.exe create "redis16381" start= auto binPath= "\"C:\Redis\6381\redis-server.exe\" --service-run \"C:\Redis\6381\sentinel.conf\" --sentinel" DisplayName= "redis16381" sc.exe create "redis16382" start= auto binPath= "\"C:\Redis\6382\redis-server.exe\" --service-run \"C:\Redis\6382\sentinel.conf\" --sentinel" DisplayName= "redis16382" sc.exe create "redis16383" start= auto binPath= "\"C:\Redis\6383\redis-server.exe\" --service-run \"C:\Redis\6383\sentinel.conf\" --sentinel" DisplayName= "redis16383" sc.exe create "redis16384" start= auto binPath= "\"C:\Redis\6384\redis-server.exe\" --service-run \"C:\Redis\6384\sentinel.conf\" --sentinel" DisplayName= "redis16384" sc.exe create "redis16385" start= auto binPath= "\"C:\Redis\6385\redis-server.exe\" --service-run \"C:\Redis\6385\sentinel.conf\" --sentinel" DisplayName= "redis16385" ``` ## Redis 分片集群結構(Cluster) #### 這部分因為在Windows下使用docker會無法ping到docker中的容器會導致Cluster抓不到其他的cluster所以這邊的教學僅供參考,如果你將要連線的應用也掛載到Docker中那是能連上的,所以還是建議使用Docker for Linux 更好,這邊附上Windows Redis的Cluster建構方式。 ### Docker Redis Cluster #### 此部分請先參考Route設定,後續作業上才會更輕鬆。[https://www.cnblogs.com/brock0624/p/9788710.html](https://) 1. 先配置好redis.conf ``` bash protected-mode no port 7001 cluster-enabled yes cluster-config-file node.conf cluster-node-timeout 5000 appendonly no ``` 2. 開始建構cluster容器 ``` bash docker run --name redis-r1 -p 8001:8001 -p 18001:18001 -v C:/work/redis/redisConf/redisCluster1.conf:/etc/redis/redis.conf -d --restart=always redis:5.0 redis-server /etc/redis/redis.conf docker run --name redis-r2 -p 8002:8002 -p 18002:18002 -v C:/work/redis/redisConf/redisCluster2.conf:/etc/redis/redis.conf -d --restart=always redis:5.0 redis-server /etc/redis/redis.conf docker run --name redis-r3 -p 8003:8003 -p 18003:18003 -v C:/work/redis/redisConf/redisCluster3.conf:/etc/redis/redis.conf -d --restart=always redis:5.0 redis-server /etc/redis/redis.conf docker run --name redis-r4 -p 8004:8004 -p 18004:18004 -v C:/work/redis/redisConf/redisCluster4.conf:/etc/redis/redis.conf -d --restart=always redis:5.0 redis-server /etc/redis/redis.conf docker run --name redis-r5 -p 8005:8005 -p 18005:18005 -v C:/work/redis/redisConf/redisCluster5.conf:/etc/redis/redis.conf -d --restart=always redis:5.0 redis-server /etc/redis/redis.conf docker run --name redis-r6 -p 8006:8006 -p 18006:18006 -v C:/work/redis/redisConf/redisCluster6.conf:/etc/redis/redis.conf -d --restart=always redis:5.0 redis-server /etc/redis/redis.conf ``` 3. 建立Cluster群組 ``` bash docker exec -it redis-r1 bash redis-cli --cluster create --cluster-replicas 1 172.17.0.1:7001 172.17.0.1:7002 172.17.0.1:7003 172.17.0.1:7004 172.17.0.1:7005 172.17.0.1:7006 ``` ![](https://hackmd.io/_uploads/Sk0onssbp.png) 4. 驗證 ``` bash docker exec -it redis-r1 bash redis-cli -p 7001 cluster info ``` ![](https://hackmd.io/_uploads/rJsAAasZp.png) ### Windows Redis Cluster 1. 請先下載Redis Windows 版本 [https://github.com/tporadowski/redis/releases](https://)下載5.0.10 ZIP ![](https://hackmd.io/_uploads/Sym74MabT.png) 2. 在特定資料夾中創建六個資料夾分別是7004~7009,將下載後的redis解壓縮進各資料夾。 ![](https://hackmd.io/_uploads/SkLn4f6b6.png) ![](https://hackmd.io/_uploads/HJ8JSG6Wp.png) 3. 修改redis.windows.conf ``` bash protected-mode no port <port> requirepass "JI(blradex5566" masterauth "JI(blradex5566" cluster-enabled yes cluster-config-file nodes.6380.conf cluster-node-timeout 15000 cluster-slave-validity-factor 10 cluster-migration-barrier 1 cluster-require-full-coverage yes tcp-backlog 511 timeout 0 tcp-keepalive 0 loglevel notice logfile "" databases 16 save 900 1 save 300 10 save 60 10000 stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes dbfilename dump.rdb dir ./ slave-serve-stale-data yes slave-read-only yes repl-diskless-sync no repl-diskless-sync-delay 5 repl-disable-tcp-nodelay no slave-priority 100 appendonly no appendfilename "appendonly.aof" appendfsync everysec no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb aof-load-truncated yes lua-time-limit 5000 slowlog-log-slower-than 10000 slowlog-max-len 128 latency-monitor-threshold 0 notify-keyspace-events "" hash-max-ziplist-entries 512 hash-max-ziplist-value 64 list-max-ziplist-entries 512 list-max-ziplist-value 64 set-max-intset-entries 512 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 hll-sparse-max-bytes 3000 activerehashing yes client-output-buffer-limit normal 0 0 0 client-output-buffer-limit slave 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 hz 10 aof-rewrite-incremental-fsync yes ``` 4. 創建service ``` bash C:/work/redis/rediscluster/7004/redis-server.exe --service-install C:/work/redis/rediscluster/7004/redis.windows.conf --service-name redis7004 #後面的7005~7009 以此類推 ``` 5. 建立集群,將service都啟動後 ``` bash C:/work/redis/rediscluster/7004>redis-cli.exe --cluster create --cluster-replicas 1 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006 ``` 之後會詢問你Can i set the above configuration (type 'yes' to accept)這邊填入yes 後面就會自動完成了。 6. 驗證 顯示出不只一個cluster node就表示成功了。 ![](https://hackmd.io/_uploads/SJGRvzpZ6.png)