docker搭建redis集羣和Sentinel,實現故障轉移

0.引言

公司開發須要用到redis,雖然有運維自動搭建,仍是記錄下如何搭建redis集羣和Sentinel。html

採用的是vagrant虛擬機+docker的方式進行搭建。python

搭建思路:redis

  首先是借鑑下其餘博客的docker搭建步驟,直接搭建。主要是:docker

https://blog.csdn.net/qq_40369435/article/details/91357479bash

   而後就是記錄搭建過程當中遇到的問題,以及如何一步步解決的。網絡

  最後測試。運維

搭建的集羣是:curl

  redis集羣:1主2從測試

  sentinel集羣:3臺ui

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下線了---》主動下線

http://www.javashuo.com/article/p-gzfoxzib-ge.html 

https://www.cnblogs.com/erbiao/archive/2018/06/08/9156215.html 

 

 

上面特別強調docker的1:1端口映射。但沒有給出具體的解決方案。

繼續找尋解決方法:

https://cloud.tencent.com/developer/article/1343834 

 

http://www.javashuo.com/article/p-kihvrogn-bs.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集羣的端口對應是:

63796379
63806379
63816379

這樣在commondmaster的端口才是6379,sentinel.conf中的端口也是6379。

2)sentinel文件夾的docker-compose.yml

 

networks:
  default:
    external:
      name: redisconf_default

3)sentinel.conf

sentinel1.confsentinel2.confsentinel3.confport都不相同,分別是263792638026381 。

sentinel monitorip地址是master節點的dockerip地址,port就是masterport

 

通過上面的修改,發現故障遷移是成功的。

 

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都啓動的

 

 

 

 

 

至此,搭建集羣應該成功,有問題再記錄解決。

相關文章
相關標籤/搜索