Docker学习笔记(高阶篇)二

Docker学习笔记(高阶篇)二

实战演练(Redis三主三从)


因手上经常玩的是Ubuntu,随测随删,所以示例用此版本演示,生产环境中以Centos为主,基本上玩法一致。

1.指定路径下创建一个测试目录test

cd /root/data/docker_workspace

mkdir test

cd test

2.创建编辑docker-compose.yml文件

vim docker-compose.yml

3.拷贝配置文件至yml文件中并保存

version: '3.3'
services:
  redis-node-1:
    image: redis:6.0.8
    command: ["redis-server", "--cluster-enabled", "yes", "--appendonly", "yes", "--port", "6381"]
    volumes:
      - /data/redis/share/redis-node-1:/data
    networks:
      - my_network
    privileged: true

  redis-node-2:
    image: redis:6.0.8
    command: ["redis-server", "--cluster-enabled", "yes", "--appendonly", "yes", "--port", "6382"]
    volumes:
      - /data/redis/share/redis-node-2:/data
    networks:
      - my_network
    privileged: true

  redis-node-3:
    image: redis:6.0.8
    command: ["redis-server", "--cluster-enabled", "yes", "--appendonly", "yes", "--port", "6383"]
    volumes:
      - /data/redis/share/redis-node-3:/data
    networks:
      - my_network
    privileged: true

  redis-node-4:
    image: redis:6.0.8
    command: ["redis-server", "--cluster-enabled", "yes", "--appendonly", "yes", "--port", "6384"]
    volumes:
      - /data/redis/share/redis-node-4:/data
    networks:
      - my_network
    privileged: true

  redis-node-5:
    image: redis:6.0.8
    command: ["redis-server", "--cluster-enabled", "yes", "--appendonly", "yes", "--port", "6385"]
    volumes:
      - /data/redis/share/redis-node-5:/data
    networks:
      - my_network
    privileged: true

  redis-node-6:
    image: redis:6.0.8
    command: ["redis-server", "--cluster-enabled", "yes", "--appendonly", "yes", "--port", "6386"]
    volumes:
      - /data/redis/share/redis-node-6:/data
    networks:
      - my_network
    privileged: true

networks:
  my_network:
    external: true

4.自定义网络

 docker network create my_network

5.运行实例

docker-compose up -d

6.查看自定义网络中运行的6个容器IP地址

docker network inspect my_network

根据显示的json表中找出对应的关系键值对:Name-IPv4Address,整理出如下列表:

test_redis-node-1_1 172.19.0.4
test_redis-node-2_1 172.19.0.2
test_redis-node-3_1 172.19.0.7
test_redis-node-4_1 172.19.0.5
test_redis-node-5_1 172.19.0.6
test_redis-node-6_1 172.19.0.3

每个节点后面的IP请根据自己实际的情况填写更改,IP是随机分配的。然后从节点一开始,每个节点的端口分别分配6381-6386结束

test_redis-node-1_1 172.19.0.4:6381
test_redis-node-2_1 172.19.0.2:6382
test_redis-node-3_1 172.19.0.7:6383
test_redis-node-4_1 172.19.0.5:6384
test_redis-node-5_1 172.19.0.6:6385
test_redis-node-6_1 172.19.0.3:6386

7.构建主从关系(该演示中此命令在宿主机上运行,而非进入某个节点中运行)

redis-cli --cluster create 172.19.0.4:6381 172.19.0.2:6382 172.19.0.7:6383 172.19.0.5:6384 172.19.0.6:6385 172.19.0.3:6386 --cluster-replicas 1

如果报Command 'redis-cli' not found, but can be installed with:

apt install redis-tools

8.请用命令安装redis-tools

apt install redis-tools

再次运行

redis-cli --cluster create 172.19.0.4:6381 172.19.0.2:6382 172.19.0.7:6383 172.19.0.5:6384 172.19.0.6:6385 172.19.0.3:6386 --cluster-replicas 1

确认无误,输入yes开始分配

9.进入主Master节点一查看所有节点信息

docker exec -it test_redis-node-1_1 /bin/bash
redis-cli -p 6381
cluster info

cluster_state:ok: 集群的状态是OK,意味着这个节点认为集群是健康的。
cluster_slots_assigned: 节点被分配了集群中所有16384个槽。
cluster_slots_ok: 所有16384个槽都正常工作。
cluster_known_nodes: 节点已知集群中有6个节点,包括它自己和其他节点。
该输出表明此节点是集群的一部分,集群中有6个节点,并且此节点已经分配了所有的槽,没有任何槽是处于失败状态。基于输出的其余部分,我们可以看到集群当前有3个主节点(cluster_size:3)

cluster nodes命令继续查询列出了集群中每个节点的ID、IP地址、端口号以及它们是主节点(master)还是从节点(slave)。例如第一个节点是一个主节点(master),其余的是与之关联的从节点。

  • 主节点 (test_redis-node-3_1)172.19.0.7:6383 与从节点 (test_redis-node-5_1)172.19.0.6:6385;
  • 主节点(test_redis-node-2_1) 172.19.0.2:6382 与从节点(test_redis-node-6_1) 172.19.0.3:6386;
  • 主节点 (test_redis-node-1_1)172.19.0.4:6381 与从节点(test_redis-node-4_1) 172.19.0.5:6384

主从切换测试

1、切换到宿主机上停止主节点一的容器(6381),观察其从节点6384是否会上位成为主节点?

6381节点正常运行时的槽位
6381关闭后,6385上位成了主节点

疑问?

为什么按照前面的那张主从对应表,原先主节点6381的从节点是6384,按照道理说,6381关闭了,应该是6384上位,怎么反而是主节点6383对应的从节点6385上位呢?

原来在Redis集群中,主节点的故障转移(failover)并不总是选择其对应的从节点作为新的主节点。选择哪个从节点晋升为新的主节点由Redis集群的故障转移过程决定,该过程遵循以下步骤:

  • 检测主节点故障:集群中的其他节点(主要是从节点)会持续检测与主节点的通信。如果一个主节点无法访问,它的从节点将开始一个故障转移流程。

  • 选举投票:在开始故障转移时,从节点会向集群中的其他主节点请求投票来成为新的主节点。

  • 选择一个从节点:其他主节点将根据从节点的状态和偏移量(表示数据的新鲜程度)投票。通常拥有最完整数据集的从节点,即数据偏移量最大的从节点,会赢得选举。

  • 晋升过程:一旦一个从节点赢得大多数票,它就会被晋升为新的主节点,并开始接收写请求。

  • 更新集群状态:集群的状态将更新,新的主节点的信息将被传播到整个集群。

2、重启6381主节点,再观察

发现6381恢复正常后,并没有如想象中的那样会把刚刚上位成为master节点的6385给踢下去做回从节点,而自己则重新成为master。原因如下:

在Redis集群中一旦一个从节点晋升为主节点,这个变化是有持续性的。也就是说,即使原来的主节点重新上线,晋升的从节点通常不会自动降级回从节点。原因如下:

  • 稳定性:集群晋升新的主节点是为了维持稳定性和数据完整性。一旦一个从节点被晋升为主节点,它就会承担起响应客户端请求和数据同步的责任。将它再次降级可能会引起不必要的风险和混乱。

  • 避免脑裂:晋升后,为了防止“脑裂”(split-brain)情况的发生,集群会避免出现两个节点声称自己是相同数据分片的主节点的情况。

  • 数据最新:通常一个节点被晋升为主节点,是因为它有最新的数据副本。当原主节点恢复时,它的数据可能已经落后于新的主节点,因此原主节点会成为新主节点的从节点,以同步最新的数据。

  • 自动化运维:大多数Redis集群的运维是自动化的,当集群自我修复后,不会再进行不必要的角色更改,除非由管理员手动介入。

  • 人为干预:如果希望原主节点恢复其主节点角色,需要管理员手动介入进行调整。这通常包括将新主节点降级为从节点,并恢复原主节点的主节点角色。