从零 Redis 系列 -- 使用 Docker Compose 创建集群


使用 Docker Compose 创建集群

集群的作用

redis 集群可以把大量的数据分散到 n 个节点中,同时可以对每个节点做备份,来保障 redis 数据的高可用和稳定性

Docker Compose 是一个轻量级的容器编排工具,它使用 yaml 来编排容器,可以在 n 个容器中做通信。

redis 集群模型

redis 集群最少需要 6 个节点,基础的集群模型如下图,分别有 3 个主节点,3个从节点,数据被分配到 3 个主节点上,redis 的集群是根据它内部的槽(slot)来实现的,redis 有 16384 个槽, 根据 CRC16(key)%1638 可以计算出 key 应该存放在哪个槽中。同时每个节点之间通过 redis 的 Gossip 协议 来传播信息,检查目标节点是否存活等。如果有一个主节点宕机,redis 会选举 出一个新的主节点来替代宕机的主节点,以此来保证服务的可用性。

集群模型

docker compose 编写

redis的集群需要容器的内部和外部通信,所以一般都设置容器的 network 为 host 模式,但是如果你使用的 mac docker 则不支持 host 模式

version: '3.3'
services:
  # 节点1
  redis1:
    # 启动之后的容器名称
    container_name: redis-node-1
    env_file: 
      # 环境配置
      - ./.env
    # 使用哪种镜像
    image: 'redis:5.0.4'
    # 端口映射
    ports:
      - ${redis1_ports}
      - ${redis1_cluster}
    networks:
        cluster-net:
          ipv4_address: 172.16.238.11
    volumes:
      # 容器的data映射到宿主机
      - /Users/g5niusx/Soft/docker/redis/node-${redis1_port}/data:/data
      # 加载配置文件
      - /Users/g5niusx/Soft/docker/redis/node-${redis1_port}/redis.conf:/usr/local/etc/redis/redis.conf
    # 启动redis的时候指定配置文件
    command: redis-server /usr/local/etc/redis/redis.conf
    environment: 
      # 设置时区为上海,否则时间会有问题
      - TZ=Asia/Shanghai
  # 节点2
  redis2:
    container_name: redis-node-2
    env_file: 
      - ./.env
    # 使用哪种镜像
    image: 'redis:5.0.4'
    # 端口映射
    ports:
      - ${redis2_ports}
      - ${redis2_cluster}
    networks:
        cluster-net:
          ipv4_address: 172.16.238.12
    volumes:
      # 容器的data映射到宿主机
      - /Users/g5niusx/Soft/docker/redis/node-${redis2_port}/data:/data
      # 加载配置文件
      - /Users/g5niusx/Soft/docker/redis/node-${redis2_port}/redis.conf:/usr/local/etc/redis/redis.conf
    # 启动redis的时候指定配置文件  
    command: redis-server /usr/local/etc/redis/redis.conf
    environment: 
      # 设置时区为上海,否则时间会有问题
      - TZ=Asia/Shanghai
  # 节点3
  redis3:
    container_name: redis-node-3
    env_file:
      - ./.env
    # 使用哪种镜像
    image: 'redis:5.0.4'
    # 端口映射
    ports:
      - ${redis3_ports}
      - ${redis3_cluster}
    networks:
        cluster-net:
          ipv4_address: 172.16.238.13
    volumes:
      # 容器的data映射到宿主机
      - /Users/g5niusx/Soft/docker/redis/node-${redis3_port}/data:/data
      # 加载配置文件
      - /Users/g5niusx/Soft/docker/redis/node-${redis3_port}/redis.conf:/usr/local/etc/redis/redis.conf
    # 启动redis的时候指定配置文件
    command: redis-server /usr/local/etc/redis/redis.conf
    environment:
      # 设置时区为上海,否则时间会有问题
      - TZ=Asia/Shanghai
  # 节点4
  redis4:
    container_name: redis-node-4
    env_file:
      - ./.env
    # 使用哪种镜像
    image: 'redis:5.0.4'
    # 端口映射
    ports:
      - ${redis4_ports}
      - ${redis4_cluster}
    networks:
        cluster-net:
          ipv4_address: 172.16.238.14
    volumes:
      # 容器的data映射到宿主机
      - /Users/g5niusx/Soft/docker/redis/node-${redis4_port}/data:/data
      # 加载配置文件
      - /Users/g5niusx/Soft/docker/redis/node-${redis4_port}/redis.conf:/usr/local/etc/redis/redis.conf
    # 启动redis的时候指定配置文件
    command: redis-server /usr/local/etc/redis/redis.conf
    environment:
      # 设置时区为上海,否则时间会有问题
      - TZ=Asia/Shanghai
  # 节点5
  redis5:
    container_name: redis-node-5
    env_file:
      - ./.env
    # 使用哪种镜像
    image: 'redis:5.0.4'
    # 端口映射
    ports:
      - ${redis5_ports}
      - ${redis5_cluster}
    networks:
        cluster-net:
          ipv4_address: 172.16.238.15
    volumes:
      # 容器的data映射到宿主机
      - /Users/g5niusx/Soft/docker/redis/node-${redis5_port}/data:/data
      # 加载配置文件
      - /Users/g5niusx/Soft/docker/redis/node-${redis5_port}/redis.conf:/usr/local/etc/redis/redis.conf
    # 启动redis的时候指定配置文件
    command: redis-server /usr/local/etc/redis/redis.conf
    environment:
      # 设置时区为上海,否则时间会有问题
      - TZ=Asia/Shanghai
  # 节点6
  redis6:
    container_name: redis-node-6
    env_file:
      - ./.env
    # 使用哪种镜像
    image: 'redis:5.0.4'
    # 端口映射
    ports:
      - ${redis6_ports}
      - ${redis6_cluster}
    networks:
        cluster-net:
          ipv4_address: 172.16.238.16
    volumes:
      # 容器的data映射到宿主机
      - /Users/g5niusx/Soft/docker/redis/node-${redis6_port}/data:/data
      # 加载配置文件
      - /Users/g5niusx/Soft/docker/redis/node-${redis6_port}/redis.conf:/usr/local/etc/redis/redis.conf
    # 启动redis的时候指定配置文件
    command: redis-server /usr/local/etc/redis/redis.conf
    environment:
      # 设置时区为上海,否则时间会有问题
      - TZ=Asia/Shanghai
networks:
  # 创建集群网络,在容器之间通信
  cluster-net:
    ipam:
      config:
        - subnet: 172.16.238.0/24

如果你使用的是 linux 来部署 redis 的集群,就不需要自定义 network,可以直接设置 network=host来完成容器的通信 上面 docker-compose.yml 的重点在于自己声明来一个自定义的 network–cluster-net 来实现不同容器之间的通信。由于 docker 里面的 ip 是不固定的,我们没有办法 获取 docker 里面的 ip,所以在自定义 network 的时候,通过配置 subnet=172.16.238.0/24cluster-net 的 ip 范围固定在 172.16.238.0/254 之间,然后在 每一个 redis 的节点中指定该节点的 ip 地址在我们配置的范围之内,就可以实现容器之间的相互通信。

Redis 集群启动

启动容器

可以观察到容器在启动的时候加载的 network 是我们自定义的 network

在进入任意一个 redis 容器后,执行以下的命令,输入 yes 就可以配置成功 redis 集群

# -a redis 表示连接密码为 redis
#--cluster-replicas 表示创建一个从节点
redis-cli -a redis --cluster create 172.16.238.11:6379 172.16.238.12:6379 172.16.238.13:6379 172.16.238.14:6379 172.16.238.15:6379 172.16.238.16:6379 --cluster-replicas 1

配置成功的界面如下:

配置成功

详细配置

  #redis 

« 从零 Redis 系列 -- 持久化数据
blog comments powered by Disqus