Docker redis 集群搭建

Redis 集群是一個提供在多個 Redis 節點間共用數據的程式集。

Redis 集群並不支持處理多個 keys 的命令,因為這需要在不同的節點間移動數據,從而達不到像 Redis 那樣的性能,在高負載的情況下可能會導致不可預料的錯誤.

Redis 集群通過分區來提供一定程度的可用性,在實際環境中當某個節點宕機或者不可達的情況下繼續處理命令。

Redis 集群的優勢:

  • 自動分割數據到不同的節點上。
  • 整個集群的部分節點失敗或者不可達的情況下能夠繼續處理命令。

Redis 集群沒有使用一致性 hash, 而是引入了哈希槽的概念。Redis 集群有 16384 個哈希槽,每個 key 通過 CRC16 校驗後對 16384 取模來決定放置哪個槽,集群的每個節點負責一部分 hash 槽。

1、下載 redis.conf

下載地址:https://github.com/antirez/redis/blob/unstable/redis.conf

2、修改 redis.conf

開啟集群功能:

cluster-enabled yes

設置節點端口:

port 6391

節點超時時間,單位毫秒:

cluster-node-timeout 15000

集群內部配置檔:

cluster-config-file "nodes-6379.conf"

3、編寫 docker-compose.yml

節點規劃圖如下:

配置如下:

version: "3.6"
services:
  redis-master1:
     image: redis:5.0 # 基礎鏡像
     container_name: redis-master1 # 容器服務名

     working_dir: /config # 工作目錄
     environment: # 環境變數
       - PORT=6391 # 跟 config/nodes-6391.conf 裏的配置一樣的端口
     ports: # 映射端口,對外提供服務

       - "6391:6391" # redis 的服務端口

       - "16391:16391" # redis 集群監控端口
     stdin_open: true # 標準輸入打開
     networks: # docker 網路設置
        redis-master:
            ipv4_address: 172.50.0.2
     tty: true
     privileged: true # 擁有容器內命令執行的許可權

     volumes: ["/c/project/docker/redis/config:/config"] # 映射數據卷,配置目錄
     entrypoint: # 設置服務默認的啟動程式

       - /bin/bash
       - redis.sh
  redis-master2:
       image: redis:5.0
       working_dir: /config
       container_name: redis-master2
       environment:
              - PORT=6392
       networks:
          redis-master:
             ipv4_address: 172.50.0.3
       ports:
         - "6392:6392"
         - "16392:16392"
       stdin_open: true
       tty: true
       privileged: true
       volumes: ["/c/project/docker/redis/config:/config"]
       entrypoint:
         - /bin/bash
         - redis.sh
  redis-master3:
       image: redis:5.0
       container_name: redis-master3
       working_dir: /config
       environment:
              - PORT=6393
       networks:
          redis-master:
            ipv4_address: 172.50.0.4
       ports:
         - "6393:6393"
         - "16393:16393"
       stdin_open: true
       tty: true
       privileged: true
       volumes: ["/c/project/docker/redis/config:/config"]
       entrypoint:
         - /bin/bash
         - redis.sh
  redis-slave1:
       image: redis:5.0
       container_name: redis-slave1
       working_dir: /config
       environment:
            - PORT=6394
       networks:
          redis-slave:
             ipv4_address: 172.30.0.2
       ports:
         - "6394:6394"
         - "16394:16394"
       stdin_open: true
       tty: true
       privileged: true
       volumes: ["/c/project/docker/redis/config:/config"]
       entrypoint:
         - /bin/bash
         - redis.sh
  redis-salve2:
       image: redis:5.0
       working_dir: /config
       container_name: redis-salve2
       environment:
             - PORT=6395
       ports:
         - "6395:6395"
         - "16395:16395"
       stdin_open: true
       networks:
          redis-slave:
              ipv4_address: 172.30.0.3
       tty: true
       privileged: true
       volumes: ["/c/project/docker/redis/config:/config"]
       entrypoint:
         - /bin/bash
         - redis.sh
  redis-salve3:
       image: redis:5.0
       container_name: redis-slave3
       working_dir: /config
       environment:
          - PORT=6396
       ports:
         - "6396:6396"
         - "16396:16396"
       stdin_open: true
       networks:
          redis-slave:
            ipv4_address: 172.30.0.4
       tty: true
       privileged: true
       volumes: ["/c/project/docker/redis/config:/config"]
       entrypoint:
         - /bin/bash
         - redis.sh
networks:
  redis-master:
     driver: bridge # 創建一個docker 的橋接網路

     ipam:
       driver: default
       config:
          -
           subnet: 172.50.0.0/16
  redis-slave:
       driver: bridge
       ipam:
         driver: default
         config:
            -
             subnet: 172.30.0.0/16

4、編寫 redis 默認的啟動腳本

創建檔 config/redis.sh,內容如下:

redis-server  /config/nodes-${PORT}.conf

5、啟動集群

啟動服務命令如下:

$ docker-compose up -d

查看服務運行:

$ docker ps

初始化集群(這一步開始命令須在 redis5.0 及以上版本運行)。

創建 3 主 3 從的 redis 集群:

$ redis-cli --cluster create 192.168.99.100:6391 192.168.99.100:6392 192.168.99.100:6393 192.168.99.100:6394 192.168.99.100:6395 192.168.99.100:6396 --cluster-replicas 1

輸入 yes,確認要初始化:

查看初始化結果。

進入 redis-cli, 查看節點資訊:

root@ae9e587e62f4:/data# redis-cli -h 192.168.99.100 -p 6391
192.168.99.100:6391> cluster nodes

上圖顯示,redis 集群符合預期。

6、測試集群

普通模式連接:由於 test 根據哈希槽計算,是分佈在 6392 服務上。所以這裏會提示轉到 6392。

root@ae9e587e62f4:/data# redis-cli -h 192.168.99.100 -p 6391

集群模式連接:以下例子顯示操作正常。

root@ae9e587e62f4:/data# redis-cli -c -h 192.168.99.100 -p 6391 set test 1
root@ae9e587e62f4:/data# redis-cli -c -h 192.168.99.100 -p 6391 get test

集群模式連接讀寫正常,集群搭建成功。

本例涉及到的檔下載:

docker-redis