使用docker 搭建 redis 集羣

docker redis 集羣搭建

本教程使用官方redis 鏡像+docker-compose 完成整個redis集羣的搭建,之所以使用docker-compose 是因爲只需要寫好配置文件部署執行方便

 

docker redis 集羣搭建省略步驟正式開始

 

省略步驟

請參考docker官方文檔

  1. docker 安裝

  2. docker compose 安裝

 

正式開始

說白了都是配置文件

爲了下面不迷路,先把配置的目錄結構貼上 不要急着建目錄結構,大多目錄後面我有腳本直接生成,下面高亮的爲目錄:

redis-cluster

-data

--7000

----conf

----data

----logs

--7001

----conf

----data

----logs

--7002

----conf

----data

----logs

--7003

----conf

----data

----logs

--7004

----conf

----data

----logs

--7005

----conf

----data

----logs

--redis-cluster.tmpl

--docker-compose.yml

好了,以上就是這次集羣的目錄結構,解釋一下:

  1. redis-cluster 目錄不用說了是我們工作空間

  2. data 目錄是所有redis 節點配置文件所以在目錄

  3. data 目錄下的700x 目錄是針對單個節點的配置所在目錄,至於700x 是redis 服務的端口。端口目錄下的 conf 目錄下存了當前redis 節點的真實配置文件。至於端口下的data目錄是我docker volume 映射的目錄,這個當然你隨便。

  4. redis-cluster.tmpl 爲redis 節點的模板文件

  5. 至於docker-compose.yml 文件就不必說了這個是docker-compose 啓動服務的配置文件

 

  1. 首先新建了一個工作目錄 redis-cluster

由於我實現redis 集羣用了6臺redis 節點 ,每臺都要寫配置文件總不方便

所以

首先爲redis 配置文件文件創建了一個模板 我命名爲 redis-cluster.tmpl 以下內容:

 ##節點端口
 port ${PORT}                                       
 ##開啓集羣模式
 protected-mode no                                  
 ##cluster集羣模式
 cluster-enabled yes                                
 ##集羣配置名
 cluster-config-file nodes.conf          
 ##超時時間           
 cluster-node-timeout 5000   
 ##實際爲各節點網卡分配ip                      
 cluster-announce-ip 172.19.0.${IPEND}           
 ##節點映射端口       
 cluster-announce-port ${PORT}           
 ##節點總線端口           
 cluster-announce-bus-port 1${PORT}  
 ##持久化模式               
 appendonly yes 
   

這裏有個配置需要解釋一下:cluster-announce-ip 這個參數的值 172.19.0.${IPEND} 不是我隨便寫的,這個是取自docker service 使用的network 的網關地址。如果你無法確定 請使用`docker inspect <network-name> 查看。

 

  1. 生成配置

    使用上面模板加上如下腳本來生成我們需要的redis 各個節點的目錄和配置,你可以把下面腳本寫進xx.sh 文件放到redis-cluster 工作空間執行

     #!/bin/bash
     for port in `seq 7000 7005`; do 
       mkdir -p ./data/${port}/conf && PORT=${port} IPEND=17${port:0-1:1} envsubst < ./redis-cluster.tmpl > ./data/${port}/conf/redis.conf && mkdir -p ./data/${port}/data; 
     done

    到此開始我們展示的目錄及除了 docker-compose.yml 文件都已經全了

     

    1. 寫 docker-compose.yml 文件

       
      
      version: '3'
       services:
         redis-7000: 
           image: redis:latest
           container_name: redis-7000
           volumes: 
             - ./data/7000/conf/redis.conf:/usr/local/etc/redis/redis.conf
             - ./data/7000/data:/data
             - ./data/7000/logs:/usr/local/redis/logs
           command: redis-server /usr/local/etc/redis/redis.conf --requirepass yasin
           ports: 
             - "7000:7000"
             - "17000:17000"
           restart: always
           networks: 
             redis-net:
               ipv4_address: 172.19.0.170
           logging:  
             driver: "json-file"
             options: 
               max-size: "1m"
       ​
       ​
         redis-7001: 
           image: redis:latest
           container_name: redis-7001
           volumes: 
             - ./data/7001/conf/redis.conf:/usr/local/etc/redis/redis.conf
             - ./data/7001/data:/data
             - ./data/7001/logs:/usr/local/redis/logs
           command: redis-server /usr/local/etc/redis/redis.conf --requirepass yasin
           ports: 
             - "7001:7001"
             - "17001:17001"
           restart: always
           networks:  
             redis-net:
               ipv4_address: 172.19.0.171
           logging: 
             driver: "json-file"
             options: 
               max-size: "1m"   
       ​
       ​
         redis-7002: 
           image: redis:latest
           container_name: redis-7002
           volumes: 
             - ./data/7002/conf/redis.conf:/usr/local/etc/redis/redis.conf
             - ./data/7002/data:/data
             - ./data/7002/logs:/usr/local/redis/logs
           command: redis-server /usr/local/etc/redis/redis.conf --requirepass yasin
           ports: 
             - "7002:7002"
             - "17002:17002"
           restart: always
           networks: 
             redis-net:
               ipv4_address: 172.19.0.172
           logging: 
             driver: "json-file"
             options: 
               max-size: "1m" 
       ​
       ​
         redis-7003: 
           image: redis:latest
           container_name: redis-7003
           volumes: 
             - ./data/7003/conf/redis.conf:/usr/local/etc/redis/redis.conf
             - ./data/7003/data:/data
             - ./data/7003/logs:/usr/local/redis/logs
           command: redis-server /usr/local/etc/redis/redis.conf --requirepass yasin
           ports: 
             - "7003:7003"
             - "17003:17003"
           restart: always
           networks: 
             redis-net:
               ipv4_address: 172.19.0.173
           logging: 
             driver: "json-file"
             options: 
               max-size: "1m" 
       ​
       ​
         redis-7004: 
           image: redis:latest
           container_name: redis-7004
           volumes: 
             - ./data/7004/conf/redis.conf:/usr/local/etc/redis/redis.conf
             - ./data/7004/data:/data
             - ./data/7004/logs:/usr/local/redis/logs
           command: redis-server /usr/local/etc/redis/redis.conf --requirepass yasin
           ports: 
             - "7004:7004"
             - "17004:17004"
           restart: always
           networks: 
             redis-net:
               ipv4_address: 172.19.0.174
           logging: 
             driver: "json-file"
             options: 
               max-size: "1m" 
       ​
       ​
         redis-7005: 
           image: redis:latest
           container_name: redis-7005
           volumes: 
             - ./data/7005/conf/redis.conf:/usr/local/etc/redis/redis.conf
             - ./data/7005/data:/data
             - ./data/7005/logs:/usr/local/redis/logs
           command: redis-server /usr/local/etc/redis/redis.conf --requirepass yasin
           ports: 
             - "7005:7005"
             - "17005:17005"
           restart: always
           networks: 
             redis-net:
               ipv4_address: 172.19.0.175
           logging: 
             driver: "json-file"
             options: 
               max-size: "1m" 
            
       ​
       networks:
        redis-net:
         external: true
      
      
       

--requirepass yasin 這個是我爲每個redis node 設置了 密碼 yasin ,不需要可以去掉。

ipv4_address 這裏的ip地址一定要與redis.conf 中的地址一致.

external: true 這裏external 值爲true 是我事前創建了docker network create --driver bridge redis-net 如果是Windows 機器可能會失敗 可以再嘗試docker network create --driver nat redis-net

  1. 創建並啓動容器

    好了,配置文件準備就緒就讓我們看一下效果吧,在我們的工作空間下執行以下命令來創建我們的6臺 docker redis 服務:

    docker-compose up

     

  2. 組建集羣

服務起來之後剩下的事情就是讓6臺redis 感知到彼此,進入到其中一臺容器

docker exec -it redis-7000 bash

(容器內執行)

 for N in `seq 0 5` ; do 
     redis-cli -h 172.19.0.170 -p 7000 -a yasin cluster meet 172.19.0.17${N} 700${N};
 done

teps: 我在執行到這一步的時候吃了大虧,按理說只要一臺節點去感知了其他節點其他節點都會自動相互感知,但是當時執行到這一步時,沒有執行上面命令的節點死活感知不到其他節點。問題在於reds 的配置文件裏我把 cluster-announce-ip 172.19.0.${IPEND} 寫死爲 cluster-announce-ip 0.0.0.0 導致其他節點一直在執行 :

cluster meet 0.0.0.0 7000

cluster meet 0.0.0.0 7001

cluster meet 0.0.0.0 7002

cluster meet 0.0.0.0 7003

cluster meet 0.0.0.0 7004

cluster meet 0.0.0.0 7005

其中一臺節點怎麼可能同時用於700x的所有redis 端口呢!

檢查一下所有節點是否都感知到了彼此:在每臺節點執行如下命令 打印出6臺節點的信息記錄下每行的id (節點標識),很重要下面要用

(容器內執行)

redis-cli -h 172.19.0.170 -p 7000 -a yasin cluster nodes

到此redis 集羣搭建完成

 

  1. 分配槽點

6 個節點,我們選出端口爲7000、7001、7002 三臺爲master 節點 ,並且爲他們分配槽點

(容器內執行)

 redis-cli -h 172.19.0.170 -p 7000 -a yasin  CLUSTER ADDSLOTS {0,5461}
 redis-cli -h 172.19.0.171 -p 7001 -a yasin  CLUSTER ADDSLOTS {5462,10922}
 redis-cli -h 172.19.0.171 -p 7001 -a yasin  CLUSTER ADDSLOTS {10923,16383}

 

  1. 分配slave

(容器內執行) 這裏就用到了上面記錄的 節點標識

 # 此命令是在 從redis節點內執行 關聯到 主redis 的節點標識
 # 主 redis-7000 從 redis-7003
 /usr/local/bin/redis-cli -h 172.19.0.173 -p 7003 -a yasin CLUSTER REPLICATE 5631cd7205b964c0c848ddc7292835fa8a4df57c
 # 主 redis-7001 從 redis-7004
 /usr/local/bin/redis-cli -h 172.19.0.174 -p 7004 -a yasin CLUSTER REPLICATE d0423573bfe628fb03cee2feead667ef5679c17d
 # 主 redis-7002 從 redis-7005
 /usr/local/bin/redis-cli -h 172.19.0.175 -p 7005 -a yasin CLUSTER REPLICATE 8563d43bf400b6435a921f4783420cca02fa2d5a

 

  1. 集羣密碼

    如果需要可以爲集羣設置密碼(容器內執行 密碼yasin

for n in `seq 0 5` ; do 
     # 爲每個節點設相同密碼
     redis-cli -h 172.19.0.17${n} -p 700${n} -a yasin config set requirepass yasin;
     # 爲slave節點設置主節點的密碼,可能用於同步主節點數據驗證使用(我這裏爲所有節點都設置了)
     redis-cli -h 172.19.0.17${n} -p 700${n} -a yasin config set masterauth yasin;
 done

 

  1. 驗證、結束

到目前redis cluster 搭建結束,試一下集羣連接 注意命令中的 -c 是用於連接集羣的。

redis-cli -h -c 172.19.0.170 -p 7000 -a yasin set name 張三

 
for n in `seq 0 5` ; do 
     redis-cli -h -c 172.19.0.17${n} -p 700${n} -a yasin get name 張三
 done

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章