Docker 部署三主三从 Redis 服务

Docker 部署三主三从 Redis 服务

Cocytus Elias 212 2023-05-22

Docker 部署三主三从 Redis 集群服务

redis 集群有三种:

  • 主从复制:一份数据,多个备份。可以实现读写分离及灾备。但是节点异常时需要人工介入切换主从。
  • 哨兵:在主从基础上增加了哨兵。除了主从的优点外,在某个节点异常时,哨兵可自动切换主从节点。
  • clusterredis 的分布式存储,主从和哨兵都有一个缺陷就是,每个节点上存储的都是全量数据,这样只能纵向扩展,而无法横向扩展。cluster 可以实现分片存储,并且可以与主从、哨兵结合使用。

本次部署采用 redis 6.2.6 。部署三主三从六个节点。分为单机及多机两种方式部署。

需要注意:redis 的磁盘建议使用 SSD

Redis 配置

# bind 127.0.0.1 是设置 redis 服务器redis所在服务器网卡的 ip 或域名的,即允许通过什么样的 ip 或 域名访问 redis。建议生产环境设置为机器 IP 或内网域名,并将 redis 所在机器与外网物理隔离。设置开启后如果不使用指定 ip 或 域名 访问会出现:Connection reset by peer。
# bind 127.0.0.1
# 自定义密码 连接 reids 的登陆密码
requirepass 123123123
# 指定 Redis 监听端口(默认:6379),如果是一台机器上跑两个以上的节点,建议更改此设置。推荐端口范围为 6370 - 6379。
port 6379
# 客户端闲置指定时长后关闭连接(单位:秒。0:关闭该功能)
timeout 0
#开启aof持久化策略
appendonly yes
appendfsync everysec
# 900s内如果至少一次写操作则执行bgsave进行RDB持久化操作
save 900 1
# 在300s内,如果至少有10个key进行了修改,则进行持久化操作
save 300 10
# 在60s内,如果至少有10000个key进行了修改,则进行持久化操作
save 60 10000
# 是否压缩数据存储(默认:yes。Redis采用LZ 压缩,如果为了节省 CPU 时间,可以关闭该选项,但会导致数据库文件变的巨大)
rdbcompression no
# 指定本地数据文件名(默认:dump.rdb)
dbfilename dump.rdb
# 指定本地数据文件存放目录
dir /disk/redis/data
# 指定日志文件位置(如果是相对路径,redis会将日志存放到指定的dir目录下)
logfile /disk/redis/log/redis-server.log

#非保护模式
protected-mode no
#启用集群模式
cluster-enabled yes 
cluster-config-file nodes.conf 
#超时时间
cluster-node-timeout 15000 
# redis 集群间内部通信的 IP 地址,除非有相关需求或生产环境多机器,否则不建议配置
# cluster-announce-ip 192.168.0.1
#集群节点映射端口 对外提供服务端口 跟着上面的 port 走。如果上面的 port 是 6371,那这里也要写 6371。
cluster-announce-port 6379
#集群总线端口,内部通信端口 跟着上面的 port + 10000 走。。如果上面的 port 是 6371,那这里要写 16371。
cluster-announce-bus-port 16379

单机 Docker Compose 部署

可以创建时指定 redis ipip 可以自己调整,或删除 ip 设置。建议设置 ip,后面会有用。

如果你搭建了网桥可以不需要暴露内部端口,只需要暴露外部服务端口,如果你在 redis 集群前加了 redis 代理的话,那你只需要保留 redis 代理的外部服务端口即可。我这里为了展示全部都暴露了。

version: '3.5'

services:
  redis-1:
    image: redis:6.2.6
    container_name: redis-1
    restart: always
    tty: true
    ports:
      - "6371:6371"
      - "16371:16371"
    volumes:
      - ./redis-1.conf:/etc/redis/redis.conf:ro # ro为容器对该文件只读,默认 rw 为可读写
      - ./redis-1/data:/disk/redis/data
      - ./redis-1/logs:/disk/redis/log
    command: redis-server /etc/redis/redis.conf
    networks:
      backend:
        ipv4_address: 172.20.1.1
    
  redis-2:
    image: redis:6.2.6
    container_name: redis-2
    restart: always
    tty: true
    ports:
      - "6372:6372"
      - "16372:16372"
    volumes:
      - ./redis-2.conf:/etc/redis/redis.conf:ro # ro为容器对该文件只读,默认 rw 为可读写
      - ./redis-2/data:/disk/redis/data
      - ./redis-2/logs:/disk/redis/log
    command: redis-server /etc/redis/redis.conf
    networks:
      backend:
        ipv4_address: 172.20.1.2
    
  redis-3:
    image: redis:6.2.6
    container_name: redis-3
    restart: always
    tty: true
    ports:
      - "6373:6373"
      - "16373:16373"
    volumes:
      - ./redis-3.conf:/etc/redis/redis.conf:ro # ro为容器对该文件只读,默认 rw 为可读写
      - ./redis-3/data:/disk/redis/data
      - ./redis-3/logs:/disk/redis/log
    command: redis-server /etc/redis/redis.conf
    networks:
      backend:
        ipv4_address: 172.20.1.3

  redis-4:
    image: redis:6.2.6
    container_name: redis-4
    restart: always
    tty: true
    ports:
      - "6374:6374"
      - "16374:16374"
    volumes:
      - ./redis-4.conf:/etc/redis/redis.conf:ro # ro为容器对该文件只读,默认 rw 为可读写
      - ./redis-4/data:/disk/redis/data
      - ./redis-4/logs:/disk/redis/log
    command: redis-server /etc/redis/redis.conf
    networks:
      backend:
        ipv4_address: 172.20.1.4
    
  redis-5:
    image: redis:6.2.6
    container_name: redis-5
    restart: always
    tty: true
    ports:
      - "6375:6375"
      - "16375:16375"
    volumes:
      - ./redis-5.conf:/etc/redis/redis.conf:ro # ro为容器对该文件只读,默认 rw 为可读写
      - ./redis-5/data:/disk/redis/data
      - ./redis-5/logs:/disk/redis/log
    command: redis-server /etc/redis/redis.conf
    networks:
      backend:
        ipv4_address: 172.20.1.5
    
  redis-6:
    image: redis:6.2.6
    container_name: redis-6
    restart: always
    tty: true
    ports:
      - "6376:6376"
      - "16376:16376"
    volumes:
      - ./redis-6.conf:/etc/redis/redis.conf:ro # ro为容器对该文件只读,默认 rw 为可读写
      - ./redis-6/data:/disk/redis/data
      - ./redis-6/logs:/disk/redis/log
    command: redis-server /etc/redis/redis.conf
    networks:
      backend:
        ipv4_address: 172.20.1.6

networks:
  backend:
    ipam:
      config:
        - subnet: 172.20.0.0/16
          gateway: 172.20.0.1
          ip_range: 172.20.1.0/28

多机 docker 部署

按上面的配置及 Docker Compose 文件,将下面的命令中的 redis-namepwd、以及对应的网络信息替换掉执行即可。

docker run -d \
    --name ${redis-name} \
    --restart always \
    -p 3191:3191 \
    -p 13191:13191 \
    -v ${pwd}/${redis-name}.conf:/etc/redis/redis.conf:ro \
    -v ${pwd}/${redis-name}/data:/disk/redis/data \
    -v ${pwd}/${redis-name}/logs:/disk/redis/log \
    redis:6.2.6 redis-server /etc/redis/redis.conf

建立 Redis Cluster

首先登进任意一个 redis 节点中。

以下命令根据上面的配置及 Docker Compose 来写,执行前请先将对应的 ip 及端口进行替换。

如果想建立三主三从(官方推荐)的话,执行下列命令。执行完之后,前三个节点是主,后三个节点是从。

redis-cli -a 123123123  --cluster create 172.20.1.1:6371 172.20.1.2:6372 172.20.1.3:6373 172.20.1.4:6374 172.20.1.5:6375 172.20.1.6:6376  --cluster-replicas 1

如果不想要从节点,想要六个都是主节点的话,去掉最后的 --cluster-replicas 1 参数即可。

redis-cli -a 123123123 --cluster create 172.20.1.1:6371 172.20.1.2:6372 172.20.1.3:6373 172.20.1.4:6374 172.20.1.5:6375 172.20.1.6:6376

有一点需要注意,如果你在配置中未使用 requirepass,那你在创建集群时,就不需要携带密码来创建了(去掉 -a 及相关参数即可)。