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的从节点是6384,按照道理说,6381关闭了,应该是6384上位,怎么反而是主节点6383对应的从节点6385上位呢?
原来在Redis集群中,主节点的故障转移(failover)并不总是选择其对应的从节点作为新的主节点。选择哪个从节点晋升为新的主节点由Redis集群的故障转移过程决定,该过程遵循以下步骤:
-
检测主节点故障:集群中的其他节点(主要是从节点)会持续检测与主节点的通信。如果一个主节点无法访问,它的从节点将开始一个故障转移流程。
-
选举投票:在开始故障转移时,从节点会向集群中的其他主节点请求投票来成为新的主节点。
-
选择一个从节点:其他主节点将根据从节点的状态和偏移量(表示数据的新鲜程度)投票。通常拥有最完整数据集的从节点,即数据偏移量最大的从节点,会赢得选举。
-
晋升过程:一旦一个从节点赢得大多数票,它就会被晋升为新的主节点,并开始接收写请求。
-
更新集群状态:集群的状态将更新,新的主节点的信息将被传播到整个集群。
2、重启6381主节点,再观察
发现6381恢复正常后,并没有如想象中的那样会把刚刚上位成为master节点的6385给踢下去做回从节点,而自己则重新成为master。原因如下:
在Redis集群中一旦一个从节点晋升为主节点,这个变化是有持续性的。也就是说,即使原来的主节点重新上线,晋升的从节点通常不会自动降级回从节点。原因如下:
-
稳定性:集群晋升新的主节点是为了维持稳定性和数据完整性。一旦一个从节点被晋升为主节点,它就会承担起响应客户端请求和数据同步的责任。将它再次降级可能会引起不必要的风险和混乱。
-
避免脑裂:晋升后,为了防止“脑裂”(split-brain)情况的发生,集群会避免出现两个节点声称自己是相同数据分片的主节点的情况。
-
数据最新:通常一个节点被晋升为主节点,是因为它有最新的数据副本。当原主节点恢复时,它的数据可能已经落后于新的主节点,因此原主节点会成为新主节点的从节点,以同步最新的数据。
-
自动化运维:大多数Redis集群的运维是自动化的,当集群自我修复后,不会再进行不必要的角色更改,除非由管理员手动介入。
-
人为干预:如果希望原主节点恢复其主节点角色,需要管理员手动介入进行调整。这通常包括将新主节点降级为从节点,并恢复原主节点的主节点角色。