在Docker上部署redis四种模式

一、单机部署

1.创建挂载目录

1
2
mkdir -p /data/redis/conf
mkdir -p /data/redis/data

2.添加配置文件

1
2
3
4
5
6
7
8
tee /data/redis/conf/redis.conf << EOF
# 设置服务端口 默认6379
port 6379
# 关闭保护模式,允许远程连接
protected-mode no
# 该redis远程连接用到的密码
requirepass 123456
EOF

3.启动redis

1
2
3
4
5
6
7
8
9
10
docker run -d \
-p 6379:6379 \
--name redis-server \
--restart always \
--privileged=true \
-v /etc/localtime:/etc/localtime \
-v /data/redis/conf/redis.conf:/etc/redis/redis.conf \
-v /data/redis/data:/data \
redis:[TAG] \
redis-server /etc/redis/redis.conf

二、主从复制部署

服务器信息

ip server name
172.19.0.101 master
172.19.0.102 slave1
172.19.0.103 slave2

1.分别创建挂载目录

1
2
3
4
5
6
mkdir -p /data/redis/master/conf
mkdir -p /data/redis/master/data
mkdir -p /data/redis/slave1/conf
mkdir -p /data/redis/slave1/data
mkdir -p /data/redis/slave2/conf
mkdir -p /data/redis/slave2/data

2.添加配置文件

主节点

1
2
3
4
5
6
7
8
tee /data/redis/master/conf/redis.conf << EOF
# 设置服务端口 6666
port 6666
# 关闭保护模式,允许远程连接
protected-mode no
# 该redis远程连接用到的密码
requirepass 123456
EOF

从节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
tee /data/redis/slave{1..2}/conf/redis.conf << EOF
# 服务端口 slave1 7777 slave2 8888 注意修改
port 7777
# 关闭保护模式,允许远程连接
protected-mode no
# 该redis远程连接用到的密码
requirepass 123456
# 主节点密码
masterauth 123456

# 配置主从复制 从节点默认只读
replicaof 192.168.1.101 6666
slave-read-only yes

#redis 5.0之前的版本配置主从复制用下面这个
# slaveof 192.168.1.101 6666

EOF

3.启动redis

master

1
2
3
4
5
6
7
8
9
10
docker run -d \
-p 6666:6666 \
--name redis-master \
--restart always \
--privileged=true \
-v /etc/localtime:/etc/localtime \
-v /data/redis/master/conf/redis.conf:/etc/redis/redis.conf \
-v /data/redis/master/data:/data \
redis:[TAG] \
redis-server /etc/redis/redis.conf

slave1

1
2
3
4
5
6
7
8
9
10
docker run -d \
-p 7777:7777 \
--name redis-slave1 \
--restart always \
--privileged=true \
-v /etc/localtime:/etc/localtime \
-v /data/redis/slave1/conf/redis.conf:/etc/redis/redis.conf \
-v /data/redis/slave1/data:/data \
redis:[TAG] \
redis-server /etc/redis/redis.conf

slave2

1
2
3
4
5
6
7
8
9
10
docker run -d \
-p 8888:8888 \
--name redis-slave2 \
--restart always \
--privileged=true \
-v /etc/localtime:/etc/localtime \
-v /data/redis/slave2/conf/redis.conf:/etc/redis/redis.conf \
-v /data/redis/slave2/data:/data \
redis:[TAG] \
redis-server /etc/redis/redis.conf

4.查看各个节点信息

查看master信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@redis-master ~]# docker exec -it redis-master redis-cli -p 6666 -a 123456 info replication

Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:master # 当前为主节点
connected_slaves:2 # 连接两个从节点
slave0:ip=172.19.0.102,port=7777,state=online,offset=42,lag=1 # 从节点1
slave1:ip=172.19.0.103,port=8888,state=online,offset=42,lag=1 # 从节点2
master_failover_state:no-failover
master_replid:f0214d7b9870fe4c5cbabdddf1ee743317ae74e5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:42
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:42

查看slave1信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[root@redis-slave1 ~]# docker exec -it redis-slave1 redis-cli -p 7777 -a 123456 info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:slave
master_host:172.19.0.101
master_port:6666
master_link_status:up
master_last_io_seconds_ago:10
master_sync_in_progress:0
slave_read_repl_offset:322
slave_repl_offset:322
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:f0214d7b9870fe4c5cbabdddf1ee743317ae74e5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:322
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:15
repl_backlog_histlen:308

查看slave2信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@redis-slave2 ~]# docker exec -it redis-slave2 redis-cli -p 8888 -a 123456 info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:slave
master_host:172.19.0.101
master_port:6666
master_link_status:up
master_last_io_seconds_ago:7
master_sync_in_progress:0
slave_read_repl_offset:420
slave_repl_offset:420
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:f0214d7b9870fe4c5cbabdddf1ee743317ae74e5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:420
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:29
repl_backlog_histlen:392

5.测试主从复制

master

1
2
3
4
5
6
[root@redis-master ~]# docker exec -it redis-master redis-cli -p 6666 -a 123456 set name stave
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
OK # 成功写入数据
[root@redis-master ~]# docker exec -it redis-master redis-cli -p 6666 -a 123456 get name
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
"stave" # 成功读取

slave1

1
2
3
4
5
6
7
[root@redis-slave1 ~]# docker exec -it redis-slave1 redis-cli -p 7777 -a 123456 get name
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
"stave" # slave1 成功读取数据
[root@redis-slave1 ~]# docker exec -it redis-slave1 redis-cli -p 7777 -a 123456 set name stave
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
(error) READONLY You can't write against a read only replica.
# 由于从节点只读,所以写入数据报错

slave2

1
2
3
4
5
6
7
[root@redis-slave2 ~]# docker exec -it redis-slave2 redis-cli -p 8888 -a 123456 get name
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
"stave"
[root@redis-slave2 ~]# docker exec -it redis-slave2 redis-cli -p 8888 -a 123456 set name stave
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
(error) READONLY You can't write against a read only replica.
# 同slave1,可以成功读取数据但不能写入数据

三、哨兵部署

基于上面的主从模式

1.创建挂载目录

1
2
3
mkdir -p /data/redis/sentinel1/conf
mkdir -p /data/redis/sentinel2/conf
mkdir -p /data/redis/sentinel3/conf

2.添加配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
tee /data/redis/sentinel1/conf/sentinel.conf << EOF
port 6667
sentinel monitor mymaster 172.19.0.101 6666 2
sentinel auth-pass mymaster 123456
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 10000
EOF

tee /data/redis/sentinel2/conf/sentinel.conf << EOF
port 7778
sentinel monitor mymaster 172.19.0.101 6666 2
sentinel auth-pass mymaster 123456
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 10000
EOF

tee /data/redis/sentinel3/conf/sentinel.conf << EOF
port 8889
sentinel monitor mymaster 172.19.0.101 6666 2
sentinel auth-pass mymaster 123456
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 10000
EOF

sentinel monitor mymaster 2
mymaster :哨兵监控的master名称可以随便起
172.19.0.101 6666 ip和端口固定
2 quorum值,当哨兵是集群时,有多少个哨兵认为master失效(客观下线),master才算失效。 防止脑裂 配置计算最好是 哨兵总数量/2+1

这个 Sentinel 配置文件设置了 Redis Sentinel 的行为,以下是每个配置项的解析:

  1. **port 6667**:指定 Sentinel 实例监听的端口,默认是 26379。

  2. **sentinel monitor mymaster redis-master 6666 2**:

    • mymaster:设置被监控的主节点名称。
    • redis-master:主节点的主机名或 IP 地址。
    • 6666:主节点的端口号。
    • 2:表示在故障转移决策中需要的哨兵数量,意思是至少需要两个哨兵确认主节点故障才能进行故障转移。当哨兵是集群时,有多少个哨兵认为master失效(客观下线),master才算失效。 防止脑裂 配置计算最好是 哨兵总数量/2+1 ,哨兵模式是单节点时 此处为 1
  3. **sentinel auth-pass mymaster yourpassword**:配置 Sentinel 访问主节点的密码。如果 Redis 实例启用了密码保护,需要在这里指定。

  4. **sentinel down-after-milliseconds mymaster 5000**:设置 Sentinel 认为主节点不可用的时间阈值(以毫秒为单位),这里是 5000 毫秒(即 5 秒)。

  5. **sentinel parallel-syncs mymaster 1**:指定故障转移期间并行同步从节点的数量。在故障转移时,最多有 1 个从节点将被并行同步到新的主节点。

  6. **sentinel failover-timeout mymaster 10000**:设置故障转移超时(以毫秒为单位),这里是 10000 毫秒(即 10 秒)。在此时间内,Sentinel 需要完成故障转移过程。

这些配置项共同工作,以确保在主节点发生故障时,Sentinel 可以迅速检测到问题并完成自动故障转移。

3.启动sentinel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
docker run -d \
-p 6667:6667 \
--name redis-sentinel1 \
--network redis-net \
-v /etc/localtime:/etc/localtime \
-v /data/redis/sentinel1/conf/sentinel.conf:/usr/local/etc/redis/sentinel.conf \
redis:7.0.0 \
redis-sentinel /usr/local/etc/redis/sentinel.conf

docker run -d \
-p 7778:7778 \
--name redis-sentinel2 \
--network redis-net \
-v /etc/localtime:/etc/localtime \
-v /data/redis/sentinel2/conf/sentinel.conf:/usr/local/etc/redis/sentinel.conf \
redis:7.0.0 \
redis-sentinel /usr/local/etc/redis/sentinel.conf

docker run -d \
-p 8889:8889 \
--name redis-sentinel3 \
--network redis-net \
-v /etc/localtime:/etc/localtime \
-v /data/redis/sentinel3/conf/sentinel.conf:/usr/local/etc/redis/sentinel.conf \
redis:7.0.0 \
redis-sentinel /usr/local/etc/redis/sentinel.conf

4.查看哨兵信息

1
2
3
4
5
6
7
8
9
10
[root@redis-sentinel1 /]# docker exec -it redis-sentinel1 bash
root@6409bc6f6ce5:/data# redis-cli -p 6667 info Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_tilt_since_seconds:-1
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=172.19.0.101:6666,slaves=2,sentinels=1

5.模拟主节点故障

停止主节点

1
docker stop redis-master

查看哨兵节点信息 此时主节点变成了 172.19.0.102 原来的 slave1

1
2
3
4
5
6
7
8
9
10
[root@redis-sentinel1 /]# docker exec -it redis-sentinel1 bash
root@b69b7fc37a49:/data# redis-cli -p 6667 info Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_tilt_since_seconds:-1
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=172.19.0.102:7777,slaves=2,sentinels=3

查看其他两个从节点信息 此时之前的 slave1 的角色变成了 master

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# slave1
[root@redis-slave1 /]# docker exec -it redis-slave1 redis-cli -p 7777 -a 123456 info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:master
connected_slaves:1
slave0:ip=172.19.0.103,port=8888,state=online,offset=180670,lag=1
master_failover_state:no-failover
master_replid:8a814c929ed52b786c36b5d1e07ebad1b907a7dc
master_replid2:e7107664d2c67a733e3f6901252ba88823eb51e6
master_repl_offset:180670
second_repl_offset:172840
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:15
repl_backlog_histlen:180656

slave1 的角色 未变,主节点变成了 172.19.0.102

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# slave2
[root@node2 /]# docker exec -it redis-slave2 redis-cli -p 8888 -a 123456 info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:slave
master_host:172.19.0.102
master_port:7777
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_read_repl_offset:184084
slave_repl_offset:184084
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:8a814c929ed52b786c36b5d1e07ebad1b907a7dc
master_replid2:e7107664d2c67a733e3f6901252ba88823eb51e6
master_repl_offset:184084
second_repl_offset:172840
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:29
repl_backlog_histlen:184056

重新启动 redis-master

1
docker start redis-master

查看redis-master的节点信息 原来的主节点变成了从节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[root@redis-master /]# docker exec -it redis-master redis-cli -p 6666 -a 123456 info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:slave
master_host:172.19.0.102
master_port:7777
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_read_repl_offset:184150
slave_repl_offset:184150
master_link_down_since_seconds:-1
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:14a30a8a3b44d169f4dc071a059ab38be7b4759a
master_replid2:e7107664d2c67a733e3f6901252ba88823eb51e6
master_repl_offset:184150
second_repl_offset:172840
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:172840
repl_backlog_histlen:11311

四、redis集群部署

1.创建容器实例

创建6个docker容器实例

1
2
3
4
5
6
7
8
9
10
11
docker run -d --name redis-node-1 --net host --privileged=true -v /data/redis/cluster1/data:/data redis:7.0.0 --cluster-enabled yes --appendonly yes --port 6381
docker run -d --name redis-node-2 --net host --privileged=true -v /data/redis/cluster2/data:/data redis:7.0.0 --cluster-enabled yes --appendonly yes --port 6382
docker run -d --name redis-node-3 --net host --privileged=true -v /data/redis/cluster3/data:/data redis:7.0.0 --cluster-enabled yes --appendonly yes --port 6383
docker run -d --name redis-node-4 --net host --privileged=true -v /data/redis/cluster4/data:/data redis:7.0.0 --cluster-enabled yes --appendonly yes --port 6384
docker run -d --name redis-node-5 --net host --privileged=true -v /data/redis/cluster5/data:/data redis:7.0.0 --cluster-enabled yes --appendonly yes --port 6385
docker run -d --name redis-node-6 --net host --privileged=true -v /data/redis/cluster6/data:/data redis:7.0.0 --cluster-enabled yes --appendonly yes --port 6386

--net host : 使用宿主机deIP和端口,默认
--privileged=true :容器卷,宿主机地址:docker内部地址
--cluster-enabled yes : 开启redis集群
--appendonly yes : 开启持久化

此时用docker exec -it redis-node-1 redis-cli -p 6381 info replication查看每个节点信息,所有节点都是普通的redis节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 此处用 redis-node-1 redis-node-4 示例
[root@RedisCluster ~]# docker exec -it redis-node-1 redis-cli -p 6381 info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:bec614547c3678f29215c6d141954400fb23cb4d
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

[root@RedisCluster ~]# docker exec -it redis-node-4 redis-cli -p 6384 info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:9c05447fce753e2820b78d68c2bdbf05b13fcd94
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

2.构建集群关系

在任意一台redis容器,为6台机器构建集群关系

1
2
3
docker exec -it redis-node-1 redis-cli --cluster create 192.168.8.89:6381 192.168.8.89:6382 192.168.8.89:6383 192.168.8.89:6384 192.168.8.89:6385 192.168.8.89:6386 --cluster-replicas 1

--cluster-replicas 1 : 表示为每个master创建一个slave节点

此时用docker exec -it redis-node-1 redis-cli -p 6381 info replication查看每个节点信息,其中三台成为了主节点,各有一个从节点,另外三个成为了从节点,分别与三个主节点对应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# 再看 redis-node-1 redis-node-4
[root@RedisCluster ~]# docker exec -it redis-node-1 redis-cli -p 6381 info replication
# Replication
role:master
connected_slaves:1 # 有了一个从节点
slave0:ip=192.168.8.89,port=6384,state=online,offset=56,lag=0 # 从节点为 redis-node-4
master_failover_state:no-failover
master_replid:0fd96b71a984b7fc49ce3db85ada2f5278f343c0
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:56
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:56

[root@RedisCluster ~]# docker exec -it redis-node-4 redis-cli -p 6384 info replication
# Replication
role:slave # 成为了从节点
master_host:192.168.1.89 # 主节点为 redis-node-1
master_port:6381
master_link_status:up
master_last_io_seconds_ago:5
master_sync_in_progress:0
slave_read_repl_offset:84
slave_repl_offset:84
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:0fd96b71a984b7fc49ce3db85ada2f5278f343c0
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:84
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:84

3.查看集群状态

在 redis-node-1 节点 查看集群状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
[root@RedisCluster ~]# docker exec -it redis-node-1 redis-cli -p 6381 cluster info
cluster_state:ok # 集群状态正常,没有发现问题。
cluster_slots_assigned:16384 # 集群中总共分配的槽位数量,Redis 集群有 16384 个槽位用于数据分片。
cluster_slots_ok:16384 # 当前所有分配的槽位都处于正常状态。
cluster_slots_pfail:0 # 处于部分故障状态的槽位数量,即有节点部分不可用但未完全失败。
cluster_slots_fail:0 # 完全故障的槽位数量,即存在故障的槽位无法访问。
cluster_known_nodes:6 # 当前集群中已知的节点总数。
cluster_size:3 # 集群中实际的主节点数量,说明集群由 3 个主节点组成。
cluster_current_epoch:6 # 当前的集群周期(epoch),用于跟踪集群配置变更的版本。
cluster_my_epoch:1 # 当前节点的 epoch 版本,表明该节点的配置周期。
cluster_stats_messages_ping_sent:896 # 当前节点发送的 PING 消息数量,用于检查节点状态。
cluster_stats_messages_pong_sent:908 # 当前节点发送的 PONG 消息数量,响应 PING 消息。
cluster_stats_messages_sent:1804 # 当前节点总共发送的集群消息数量。
cluster_stats_messages_ping_received:903 # 当前节点接收到的 PING 消息数量。
cluster_stats_messages_pong_received:896 # 当前节点接收到的 PONG 消息数量。
cluster_stats_messages_meet_received:5 # 当前节点接收到的 MEET 消息数量,用于节点加入集群时的通知。
cluster_stats_messages_received:1804 # 当前节点接收到的总集群消息数量。
total_cluster_links_buffer_limit_exceeded:0 # 总的超出集群链接缓冲区限制的情况次数,即没有网络缓冲区溢出的情况。

[root@RedisCluster ~]# docker exec -it redis-node-1 redis-cli -p 6381 cluster nodes
e60b10ab474e0f5486a81a4cbedff8ebdceb30d6 192.168.8.89:6383@16383 master - 0 1724982408000 3 connected 10923-16383 # redis-node-3 该节点负责槽位10923-16383
12b6cf941b53841c5ff87c40ca6bf40a1faffd3c 192.168.8.89:6384@16384 slave 4907c84ab99f8a6ec66ae9e4dbd4eba7e6f0175b 0 1724982408048 1 connected
f7525d3c24d723a4ec54c3f382f65ef3bea36659 192.168.8.89:6382@16382 master - 0 1724982410056 2 connected 5461-10922 # redis-node-2 该节点负责槽位5461-10922
4907c84ab99f8a6ec66ae9e4dbd4eba7e6f0175b 192.168.8.89:6381@16381 myself,master - 0 1724982408000 1 connected 0-5460 # redis-node-1 该节点负责槽位0-5460
c3ab49b00116b0bd8eda65a1a16125281df62f25 192.168.8.89:6385@16385 slave f7525d3c24d723a4ec54c3f382f65ef3bea36659 0 1724982407044 2 connected
92a667a6d591a297304cc8fef6c4ad6f8edca8ec 192.168.8.89:6386@16386 slave e60b10ab474e0f5486a81a4cbedff8ebdceb30d6 0 1724982409052 3 connected


4.数据读写

redis集群读取数据需要以 redis-cli -p 6381 -c 集群的方式连接,否则会添加数据时会出现 (error) MOVED 12706 192.168.8.89:6382

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@node2 ~]# docker exec -it redis-node-1 bash
root@node2:/data# redis-cli -p 6381 -c
127.0.0.1:6381> set k1 v1
-> Redirected to slot [12706] located at 192.168.8.89:6383
OK
192.168.8.89:6383> set k2 v2
-> Redirected to slot [449] located at 192.168.8.89:6381
OK
192.168.8.89:6381> set k3 v3
OK
192.168.8.89:6381>
192.168.8.89:6381> set k4 v4
-> Redirected to slot [8455] located at 192.168.8.89:6382
OK
192.168.8.89:6382>
192.168.8.89:6382> keys *
1) "k4"

Redis 集群使用分片(sharding)机制将数据分布在多个节点上,每个节点只存储一部分数据。因此,不同节点的数据是不同的。集群中的主节点负责处理写操作,并将数据分片分配给从节点进行复制和备份。

1
2
3
4
5
# 此处以下面的操作为例
127.0.0.1:6381> set k1 v1
-> Redirected to slot [12706] located at 192.168.8.89:6383
OK
# 当前在 redis-node-1 操作,将键 k1 设置为值 v1,由于 Redis 集群的分片机制,键 k1 被映射到集群中的槽位 12706。当前的节点 127.0.0.1:6381 并不是该槽位的主节点,因此该操作被重定向到负责槽位 12706 的节点,即 192.168.8.89:6383

查看redis-node-2中所有key值

1
2
192.168.8.89:6382> keys *
1) "k4"

5.故障模拟

5.1 关闭 redis-node-1 节点,通过redis-node-2查看集群信息

1
2
3
4
5
6
7
8
9
10
11
12
[root@node2 ~]# docker stop redis-node-1
redis-node-1
[root@node2 ~]# docker exec -it redis-node-2 redis-cli -p 6382 cluster nodes
e60b10ab474e0f5486a81a4cbedff8ebdceb30d6 192.168.8.89:6383@16383 master - 0 1724990223934 3 connected 10923-16383
4907c84ab99f8a6ec66ae9e4dbd4eba7e6f0175b 192.168.8.89:6381@16381 master,fail - 1724990202776 1724990200000 1 disconnected
c3ab49b00116b0bd8eda65a1a16125281df62f25 192.168.8.89:6385@16385 slave f7525d3c24d723a4ec54c3f382f65ef3bea36659 0 1724990223000 2 connected
f7525d3c24d723a4ec54c3f382f65ef3bea36659 192.168.8.89:6382@16382 myself,master - 0 1724990224000 2 connected 5461-10922
92a667a6d591a297304cc8fef6c4ad6f8edca8ec 192.168.8.89:6386@16386 slave e60b10ab474e0f5486a81a4cbedff8ebdceb30d6 0 1724990225944 3 connected
12b6cf941b53841c5ff87c40ca6bf40a1faffd3c 192.168.8.89:6384@16384 master - 0 1724990224939 7 connected 0-5460

此时 192.168.8.89:6381@16381 master,fail redis-node-1 节点 fail
原来的 redis-node-4 上位,由原来的slave成为了master

重新启动 redis-node-1

1
2
3
4
5
6
7
8
9
10
[root@node2 ~]# docker start redis-node-1
redis-node-1
[root@node2 ~]# docker exec -it redis-node-2 redis-cli -p 6382 cluster nodes
e60b10ab474e0f5486a81a4cbedff8ebdceb30d6 192.168.8.89:6383@16383 master - 0 1724994223167 3 connected 10923-16383
4907c84ab99f8a6ec66ae9e4dbd4eba7e6f0175b 192.168.8.89:6381@16381 slave 12b6cf941b53841c5ff87c40ca6bf40a1faffd3c 0 1724994222995 7 connected
c3ab49b00116b0bd8eda65a1a16125281df62f25 192.168.8.89:6385@16385 slave f7525d3c24d723a4ec54c3f382f65ef3bea36659 0 1724994222000 2 connected
f7525d3c24d723a4ec54c3f382f65ef3bea36659 192.168.8.89:6382@16382 myself,master - 0 1724994222000 2 connected 5461-10922
92a667a6d591a297304cc8fef6c4ad6f8edca8ec 192.168.8.89:6386@16386 slave e60b10ab474e0f5486a81a4cbedff8ebdceb30d6 0 1724994224171 3 connected
12b6cf941b53841c5ff87c40ca6bf40a1faffd3c 192.168.8.89:6384@16384 master - 0 1724994222089 7 connected 0-5460
此时 redis-node-4 上位,还是master,redis-node-1为slave

6.主从扩容

6.1 新增机器 6387 6388

1
2
docker run -d --name redis-node-7 --net host --privileged=true -v /data/redis/cluster7/data:/data redis:7.0.0 --cluster-enabled yes --appendonly yes --port 6387
docker run -d --name redis-node-8 --net host --privileged=true -v /data/redis/cluster8/data:/data redis:7.0.0 --cluster-enabled yes --appendonly yes --port 6388

6.2 将6387节点(空槽号)作为master节点加入原集群

1
docker exec -it redis-node-7 redis-cli --cluster add-node 192.168.8.89:6387 192.168.8.89:6381

6.3 第一次检查集群情况

1
docker exec -it redis-node-1 redis-cli --cluster check 192.168.8.89:6381

6.4 重新分配槽号

1
docker exec -it redis-node-1 redis-cli --cluster reshard 192.168.8.89:6381

initialAdminPassword

6.5 第二次检查集群情况

1
docker exec -it redis-node-1 redis-cli --cluster check 192.168.8.89:6381

initialAdminPassword

6.6 为6387主节点分配6388从节点

1
2
3
4
docker exec -it redis-node-7 redis-cli --cluster add-node 192.168.8.89:6388 192.168.8.89:6387 --cluster-slave --cluster-master-id 00633b62dd8f9e6ba5d03dc8c963667f63e57975

redis-cli --cluster add-node ip:新slave端口 ip:新master端口 --cluster-slave --cluster-master-id slave的编号

initialAdminPassword

6.7 第三次检查集群情况

1
docker exec -it redis-node-1 redis-cli --cluster check 192.168.8.89:6381

initialAdminPassword

7.主从缩容

7.1 删除6388节点

1
docker exec -it redis-node-1 redis-cli --cluster del-node 192.168.8.89:6388 fd91a8aeadac79fe892007c32ab23b8ed41c0846

7.2 对集群重新分配槽位

删除6387节点前需要先将分配给其的槽位全部分配置去,否则删除会报错,因此先重新分配槽位

1
docker exec -it redis-node-1 redis-cli --cluster reshard 192.168.8.89:6381

initialAdminPassword

在此处将 redis-node-7 的4096个槽位全部分给了 redis-node-1

7.3 删除6387节点

1
docker exec -it redis-node-1 redis-cli --cluster del-node 192.168.8.89:6387 00633b62dd8f9e6ba5d03dc8c963667f63e57975

initialAdminPassword

7.4 检查集群情况

1
docker exec -it redis-node-1 redis-cli --cluster check 192.168.8.89:6381

initialAdminPassword

此时 redis-node-7 redis-node-8 两个节点都已经删除