0.引言
公司開發需要用到redis,雖然有運維自動搭建,還是記錄下如何搭建redis叢集和Sentinel。
採用的是vagrant虛擬機器+docker的方式進行搭建。
搭建思路:
首先是借鑑下其他部落格的docker搭建步驟,直接搭建。主要是:
https://blog.csdn.net/qq_40369435/article/details/91357479
然後就是記錄搭建過程中遇到的問題,以及如何一步步解決的。
最後測試。
搭建的叢集是:
redis叢集:1主2從
sentinel叢集:3臺
1.基礎安裝
注:基礎安裝是根據已有部落格搭建的,有很多問題,不是最終步驟。最終步驟在第三部分總結給出,當然也可能有問題,畢竟各個環境可能不同。
(1)在虛擬機器中安裝docker-compose
預設已經安裝過了docker。
1)拉取安裝包
curl -L "https://get.daocloud.io/docker/compose/releases/download/1.27.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
2)給docker-compose增加執行許可權
chmod +x /usr/local/bin/docker-compose
注:最開始安裝docker-compose是先安裝python的pip,再通過pip安裝docker-compose,但升級pip時問題太多,乾脆直接找個拉取原始碼的直接下載。慚愧之前搞了那麼久的python。
(2)搭建redis叢集
1)新建docker-compose.yml檔案
version: '2.0' services: master: image: redis container_name: redis-master ports: - 6379:6379 slave1: image: redis container_name: redis-slave-1 ports: - 6380:6379 command: redis-server --slaveof redis-master 6379 slave2: image: redis container_name: redis-slave-2 ports: - 6381:6379 command: redis-server --slaveof redis-master 6379
2)啟動redis叢集
docker-compose up -d
啟動後,
docker ps; # 檢視容器啟動情況
如果容器啟動不成功,docker ps不會列出正在執行的容器,需要檢視已經啟動過的容器
docker ps -a; #檢視啟動過的容器
這個時候,如果啟動失敗,通過docker ps -a知道啟動失敗的容器id,再通過檢視日誌的方式找出錯誤:
docker logs 容器id(一部分即可); # 檢視容器的日誌
docker logs -f 容器id(一部分即可); # 動態檢視容器的日誌
(3)搭建sentinel叢集
1)sentinel配置檔案
一共三臺sentinel,準備三份配置檔案,分別是sentinel1.conf、sentinel2.conf和sentinel3.conf,將這三份配置檔案放在
/usr/local/etc/redis/sentinel.conf目錄下。
port 26379 dir "/tmp" # 自定義叢集名,其中 127.0.0.1 為 redis-master 的 ip,6379 為 redis-master 的埠,2 為最小投票數(因為有 3 臺 Sentinel 所以可以設定成 2) sentinel deny-scripts-reconfig yes #自己的虛擬機器ip地址 sentinel monitor mymaster 192.168.165.10 6379 2 sentinel config-epoch mymaster 0 sentinel leader-epoch mymaster 0 # Generated by CONFIG REWRITE(後面這3個註釋掉了) # sentinel known-replica mymaster 172.26.0.2 6379 # sentinel known-replica mymaster 172.26.0.3 6379 # sentinel current-epoch 0
同樣的內容,複製到sentinel2.conf和sentinel3.conf'
2)docker-compose.yml
version: '2.0' services: sentinel1: image: redis container_name: redis-sentinel-1 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 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
docker-compose.yml檔案也放在/usr/local/etc/redis/sentinel.conf目錄下
3)啟動sentinel叢集
docker-compose up -d
redis叢集和sentinel叢集按照上面步驟,可以通過docker執行,以為已經搭建成功,也可以連線到redis叢集中。測試在主庫中寫,兩個從庫中都可以讀出來,從庫也不可以寫內容。但是測試主庫下線時,此時2個從庫並沒有有一個切換到主庫。開始進行找錯。
2.找問題與解決
主要問題:
redis叢集的主從是成功的,但故障遷移時是失敗的。
先看看測試故障遷移的方法:
1)進入redis-master容器
docker exec -it redis-master /bin/bash
2)進入redis環境
redis-cli -p 6379
3)檢視redis角色
info
檢視,知道redis-master是master節點。同樣步驟檢視redis-slave-1和redis-slave-2,都是slave節點
4)停掉master節點
docker stop redis-master
再去檢視redis-slave-1和redis-slave-2,發現這兩個節點還是slave,並沒有一個成為master,表示sentinel故障轉移失敗。
注:之前沒有找到檢視sentinel日誌的方法(docker logs -f 容器id),在master節點下線時直接檢視sentinel的日誌可以直觀看到redis的下線、選舉和當選主節點的過程。
初步認為原因可能是sentinel監控節點失敗的原因:
檢視過程:
1)進入到redis-sentinel-1節點,檢視節點資訊
docker exec -it redis-sentinel-1/bin/bash redis-cli -p 26379 sentinel master mymaster sentinel slaves mymaster
2)發現redis-slave節點都下線了
但實際redis-slave節點是線上的,表明是sentinel認為redis-slave下線 了。可能是之間網路不通的原因導致的。
此時,查詢其他網頁,發現可以看到sentinel的logs。
檢視sentinel的日誌:
docker logs redis-sentinel-1
有:
看日誌,確實在sentinel啟動後,redis-slave是下線了。
嘗試1:
最開始看到WARN的資訊:Device or resource busy,以為是裝置被佔用(conf檔案會被sentinel再寫入),就往這個方向解決:
出現這個Warning,原因可能是:不能修改配置檔案,容器中的配置檔案是掛載到外部的。(一般修改檔案都是新生成一個然後替換原來的),就會報Device or resource busy.----->不是主要原因(因為發現其他可以正常故障遷移的也會有這個warning資訊)
嘗試2:
萬能的防火牆、埠原因
檢查本地的防火牆,發現防火牆是關閉的,不是我這邊下線的原因。
嘗試3:
sentinel.conf配置檔案問題,沒有開啟引數
https://blog.csdn.net/weixin_30649859/article/details/97698005
按照上面思路解決,仍然行不通
嘗試4:
找到關鍵性原因:sentinel和slave不能通訊,導致sentinel認為slave下線了---》主動下線
https://blog.csdn.net/woluoyifan/article/details/84252705
https://www.cnblogs.com/erbiao/archive/2018/06/08/9156215.html
上面特別強調docker的1:1埠對映。但沒有給出具體的解決方案。
繼續找尋解決方法:
https://cloud.tencent.com/developer/article/1343834
https://www.cnblogs.com/JulianHuang/p/12650721.html
這篇文章具有決定性幫助作用,首先他考慮到了docker環境下埠對映問題,其次他考慮到了網路問題。
按照這篇文章從新搭建下,發現最後還是出現了redis-slave在sentinel一啟動就下線的問題。
看評論,應該是配置檔案中sentinel埠都一樣,實際應該每個配置檔案都不同的。按照這種方法進行修改,不幸的是,還是失敗。
繼續再這篇部落格的思路上思考,裡面提出了network和redis_defalut的網路配置,將重心放到解決這個上面。
最開始在配置檔案中配置這個,啟動redis-sentinel叢集會報錯:
按照上面的提示,進行docker network create redis_default操作,應該是建立這個網路,就可以成功啟動sentinel叢集。
按照道理說,redis-master中應該有自己的network資訊的,可能是這篇博主的network資訊是redis_default和我機器上的不同,不然怎麼會又要建立一個。按照這個思路,進入到redis-master容器中,檢視資訊。
docker inspect redis-master
發現:
確實,我的機器上加redisconf_default
到這算是有個突破口了。
根據這幾輪的探索,主要針對最後一篇部落格做了如下幾個點的修改:
1)redis叢集的埠對應是:
6379:6379 6380:6379 6381:6379
這樣在commond中 master的埠才是6379,在sentinel.conf中的埠也是6379。
2)sentinel資料夾的docker-compose.yml
networks:
default:
external:
name: redisconf_default
3)sentinel.conf
sentinel1.conf、sentinel2.conf和sentinel3.conf的port都不相同,分別是26379、26380和26381 。
sentinel monitor的ip地址是master節點的dockerip地址,port就是master的port。
經過上面的修改,發現故障遷移是成功的。
3.最終安裝步驟
下面是適合我的機器的最終安裝步驟,經過測試可以行的通。但不能保證完全沒有問題。有問題就解決唄。
(1)安裝docker-compose
curl -L "https://get.daocloud.io/docker/compose/releases/download/1.27.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose
(2)搭建redis叢集
1)在/usr/local/etc/redis/redis.conf目錄下,新建docker-compose.yml
version: '3' services: master: image: redis container_name: redis-master command: redis-server --requirepass redis_pwd --masterauth redis_pwd ports: - 6379:6379 slave1: image: redis container_name: redis-slave-1 ports: - 6380:6380 command: redis-server --slaveof redis-master 6379 --requirepass redis_pwd --masterauth redis_pwd slave2: image: redis container_name: redis-slave-2 ports: - 6381:6381 command: redis-server --slaveof redis-master 6379 --requirepass redis_pwd --masterauth redis_pwd
--requirepass:指定redis登陸的密碼。redis叢集指定了,sentinel也指定相同的,否則都不指定(沒驗證過)
2)docker-compose up -d啟動redis叢集
3)檢視redis-master節點的docker-ip和network name
docker inspect redis-master
關鍵的是上面的redisconf_default和IPAddress
(2)搭建sentinel叢集
1)在/usr/local/etc/redis/sentinel.conf目錄下,新建docker-compose.yml
具體內容為:
version: '3' services: sentinel1: image: redis container_name: redis-sentinel-1 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 ports: - 26380:26380 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:26381 command: redis-sentinel /usr/local/etc/redis/sentinel.conf volumes: - ./sentinel3.conf:/usr/local/etc/redis/sentinel.conf networks: default: external: name: redisconf_default
2)在/usr/local/etc/redis/sentinel.conf目錄下,新建sentinel1.conf、sentinel2.conf和sentinel3.conf
sentinel1.conf
port 26379 dir /tmp sentinel monitor mymaster 172.20.0.3 6379 2 sentinel auth-pass mymaster redis_pwd sentinel down-after-milliseconds mymaster 30000 sentinel parallel-syncs mymaster 1 sentinel failover-timeout mymaster 180000 sentinel deny-scripts-reconfig yes
sentinel2.conf的port為26380,sentinel3.conf的port為26381,其他都一樣
3)docker-compose up -d啟動sentinel叢集
4.測試
sentinel啟動之後,通過docker logs -f sentinel容器id看日誌:
之前mymaster的192.168網段(錯誤的配置下)變成和現在slave的同網段了,就可以ping通了,後面沒有+sdown slave的資訊。就會一直阻塞在這,等待新的操作記錄日誌。
此時在另一個視窗關閉master節點:docker stop redis-master
日誌為:
進入到sentinel的redis-cli中,sentinel slaves mymaster檢視,slave都啟動的
至此,搭建叢集應該成功,有問題再記錄解決。