使用 Docker Compose 本地部署基於 Sentinel 的高可用 Redis 集羣

說明

項目地址:github.com/TomCzHen/re…node

根據官方文檔 Redis Sentinel Documentation 中的 Example 2: basic setup with three boxes 示例建立的實例,但由於是單機部署,因此不知足 Redis 實例 與 Sentinel 實例分別處於 3 臺機器的要求,所以僅用於開發環境測試與學習。nginx

使用方法

  • 使用 docker-compose up -d 部署運行。git

  • 使用 docker-compose pause master 能夠模擬對應的 Redis 實例不可用。github

  • 使用 docker-compose pause sentinel-1 能夠模擬對應的 Sentinel 實例不可用。redis

  • 使用 docker-compose unpause service_name 將暫停的容器恢復運行。docker

  • 使用支持 Sentinel 的客戶端鏈接 localhost:62379 進行應用測試。shell

注:Windows 和 Mac 可能須要修改 Volumes 掛載參數。bash

注意事項

Sentinel, Docker, NAT, and possible issues網絡

將容器端口 EXPOSE 時,Sentinel 所發現的 master/slave 鏈接信息(IP 和 端口)對客戶端來講不必定可用。負載均衡

例如:將 Reids 實例端口 6379 EXPOSE16379, Sentinel 容器使用 LINK 的方式訪問 Redis 容器,那麼對於 Sentinel 容器 6379 端口是可用的,但對於外部客戶端是不可用的。

解決方法是 EXPOSE 端口時保持內外端口一致,或者使用 host 網絡運行容器。若是你想使用本項目中的編排文件部署的集羣對外部可用,那麼只能將 Redis 容器運行在 host 網絡之上。

注:實際上 bridge 模式下 Redis 性能也會受到影響。

文件結構

.
├── docker-compose.yaml
├── nginx
│   └── nginx.conf
├── README.md
├── .env
└── sentinel
    ├── docker-entrypoint.sh
    ├── Dockerfile-sentinel
    └── sentinel.conf.sample
複製代碼

Sentinel

鏡像使用 Dockerfile-sentinel 構建,運行時根據環境變量生成 sentinel.conf 文件,詳細配置說明請查看 sentinel.conf.sample 內容。

docker-entrypoint.sh

使用 Reids 官方鏡像中的 docker-entrypoint.sh 腳本修改而來,添加了生成 sentienl.conf 語句。

...
# create sentinel.conf
if [ ! -e ${SENTINEL_CONF_PATH} ]; then
    envsubst < /etc/redis/sentinel.conf.sample > ${SENTINEL_CONF_PATH}
    chown redis:redis /etc/redis/sentinel.conf
fi
...
複製代碼

修改配置 Sentinel 的環境變量後須要從新建立容器才能生效。

可用環境變量

SENTINEL_CONF_PATH=/etc/redis/sentinel.conf
SENTINEL_PORT=26379
SENTINEL_MASTER_NAME=redis-master
SENTINEL_REDIS_IP=127.0.0.1
SENTINEL_REDIS_PORT=6379
SENTINEL_REDIS_PWD=
SENTINEL_QUORUM=2
SENTINEL_DOWN_AFTER=30000
SENTINEL_PARALLEL_SYNCS=1
SENTINEL_FAILOVER_TIMEOUT=180000
複製代碼

docker-compose.yaml

能夠使用 docker-compose config 可查看完整的編排內容。

Redis 實例運行參數

詳細可用參數請查看官方示例文件 Redis Configuration File Example,須要注意 port 參數須要與編排中的 PORTS 保持一致,或修改編排文件讓容器網絡使用 host 模式。

因爲 master 會被 Sentinel 切換爲 slave ,所以最好保持每一個 Redis 實例的口令一致。

master:
    image: redis:4.0.8-alpine
    ports:
      - 6379:6379
    volumes:
      - type: volume
        source: master-data
        target: /data
    command: [
      '--requirepass "${REDIS_PWD}"',
      '--masterauth "${REDIS_PWD}"',
      '--maxmemory 512mb',
      '--maxmemory-policy volatile-ttl',
      '--save ""',
    ]
複製代碼

Sentinel 實例運行參數

詳細可用參數請查看 sentinel 目錄下的 sentinel.conf.sample 文件。因爲容器使用的配置文件是運行時根據環境變量生成的,所以使用 environment 進行配置,可用環境變量請查看文檔 Sentinel 部分。

最後使用了 Nginx 做爲 Sentinel 實例的代理,所以 Sentinel 容器不須要對外訪問。

sentinel-1: &sentinel
    build:
      context: ./sentinel
      dockerfile: Dockerfile-sentinel
    image: redis-sentinel:dev
    environment:
      - SENTINEL_REDIS_PWD=${REDIS_PWD}
      - SENTINEL_REDIS_IP=${SENTINEL_MASTER_NAME}
      - SENTINEL_QUORUM=2
      - SENTINEL_DOWN_AFTER=3000
    command: [
      '${SENTINEL_CONF_PATH}',
      '--sentinel'
    ]
    depends_on:
      - master
      - node-1
      - node-2
    links:
      - master:${SENTINEL_MASTER_NAME}
      - node-1
      - node-2
  sentinel-2:
    <<: *sentinel
  sentinel-3:
    <<: *sentinel
複製代碼

Nginx

使用 Nginx 做爲 Sentinel 負載均衡以及高可用代理。

nginx:
    image: nginx:1.13.9-alpine
    ports:
      - 26379:26379
    volumes:
      - type: bind
        source: ./nginx/nginx.conf
        target: /etc/nginx/nginx.conf
        read_only: true
    depends_on:
      - sentinel-1
      - sentinel-2
      - sentinel-3
複製代碼

修改 nginx 目錄下的 nginx.conf 進行配置。

...
stream {
    server {
        listen 26379;
        proxy_pass redis_sentinel;
    }

    upstream redis_sentinel {
        server sentinel-1:26379;
        server sentinel-2:26379;
        server sentinel-3:26379;
    }
}
...

複製代碼
相關文章
相關標籤/搜索