在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 两个节点都已经删除

docker部署jenkins

1、拉取jenkins镜像
1
docker pull jenkins/jenkins:2.426.2-lts
2、启动镜像

因2.426.2版本的jenkins镜像默认只有openjdk17,以及git,需要配置maven以及需要的jdk1.8和node,由于需要不同版本的node,因此安装了两个node
启动脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
docker run -d \
-p 8082:8080 \
-p 50000:50000 \
-v /data/middleware/jenkins/data:/var/jenkins_home \
-v /etc/localtime:/etc/localtime \
-v /usr/bin/docker:/usr/bin/docker \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /data/middleware/jenkins/apache-maven-3.8.8:/usr/local/src/apache-maven-3.8.8 \
-v /data/middleware/jenkins/jdk1.8.0_211:/usr/local/src/jdk1.8.0_211 \
-v /data/middleware/jenkins/node-v14.21.3-linux-x64:/usr/local/src/node-v14.21.3-linux-x64 \
-v /data/middleware/jenkins/node-v16.20.2-linux-x64:/usr/local/src/node-v16.20.2-linux-x64 \
-v /data/middleware/jenkins/repo:/usr/local/repo \
--restart=on-failure -u 0 \
--name jenkins \
jenkins/jenkins:2.426.2-lts
3、登录
1
docker logs myjenkins

查看初始密码
浏览器输入ip:8082登录jenkins
initialAdminPassword

4、系统配置
1、GitLab配置

initialAdminPassword

2、远程ssh配置

initialAdminPassword

5、全局工具配置
1、maven setting和jdk配置

initialAdminPassword

2、maven配置

initialAdminPassword

nacos不配置mysql忘记控制台密码处理

nacos不配置mysql忘记控制台密码处理

nacos单机模式启动,同时不配置mysql,那么nacos会使用自带的derby数据库,所有信息都保存在derby数据库中

当忘记控制台密码时可以在服务器安装对应版本的derby数据库,直接修改密码,以下是具体操作

1.下载derby-10.14(根据nacos版本确定,我用的是nacos2.2.1,对应derby-10.14)

1
wget https://archive.apache.org/dist/db/derby/db-derby-10.14.2.0/db-derby-10.14.2.0-bin.tar.gz

2.解压

1
tar -zxvf db-derby-10.14.2.0-bin.tar.gz

3.启动derby服务(临时使用就不配置环境变量了)

1
cd db-derby-10.14.2.0-bin/lib && java -jar derbyrun.jar server start &

4.连接derby数据库

1
2
cd db-derby-10.14.2.0-bin/bin && ./ij                       #启动客户端
connect 'jdbc:derby:/data/nacos/data/derby-data/'; #连接nacos的derby数据库,需要先停了nacos

nacos自带derby不需要用户名密码,直接连接。/data/nacos/data/derby-data/ 根据自己的nacos数据文件目录修改。

5.修改密码(此处将密码修改为123456)

1
UPDATE nacos.USERS SET PASSWORD = '$2a$10$GMWR8bPg1456AvJfM3/rIORA2FFawj5qN4rsLGO.U0HNZdPDOxmdG' WHERE username = 'nacos';

6.启动nacos

1
sh startup.sh -m standalone     # 单机模式启动

此时就可以用nacos/123456登录nacos控制台 ,登录之后将密码修改成复杂密码即可,derby数据库相关也可以关闭了。

生成测试环境自签名ssl证书

生成测试环境自签名ssl证书

一、openssh生成

1.生成 CA

生成 CA 私钥(ca.key),如下步骤都会涉及输入密码

1
openssl genrsa -des3 -out ca.key 2048

生成 CA 证书签名请求(ca.csr)

1
openssl req -new -key ca.key -out ca.csr

生成自签名 CA 证书(ca.cert)

1
openssl x509 -req -days 3650 -in ca.csr -signkey ca.key -out ca.crt
2.修改openss配置

修改 openssl.cnf,将如下这三个由 match 改为 optional

1
2
3
4
5
vim /etc/pki/tls/openssl.cnf
[ policy_match ]
countryName = optional
stateOrProvinceName = optional
organizationName = optional

缺少 private 文件夹,创建 /etc/pki/CA/private

1
mkdir /etc/pki/CA/private

缺少 CA 私钥,生成对应 cakey.pem

1
openssl genrsa 1024 > /etc/pki/CA/private/cakey.pem

缺少 newcerts 文件夹,创建 /etc/pki/CA/newcerts

1
mkdir /etc/pki/CA/newcerts

缺少索引文件,创建 /etc/pki/CA/index.txt

1
touch /etc/pki/CA/index.txt

缺少序列化文件,创建 /etc/pki/CA/serial

1
echo 01 > /etc/pki/CA/serial
3.生成服务端证书

生成服务端证书,有一个确定是否生成证书这一步骤,连着输入两个 y 即可

1
2
3
4
5
6
# 生成服务端私钥(server.key)
$ openssl genrsa -out server.key 2048
# 生成服务端证书签名请求(server.csr)
$ openssl req -new -key server.key -out server.csr
# 使用ca证书签署服务端csr以生成服务端证书(server.cert)
$ openssl ca -days 3650 -in server.csr -out server.crt -cert ca.crt -keyfile ca.key
4.nginx中配置ssl证书
1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /usr/local/nginx/cert/server.crt;
ssl_certificate_key /usr/local/nginx/cert/server.key;
ssl_session_timeout 5m;
ssl_ciphers TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm;
}
}

二、mkcert生成

1.下载mkcert

下载地址:https://github.com/FiloSottile/mkcert/tags

在cmd终端输入 echo %PROCESSOR_ARCHITECTURE% 查看电脑是arm还是amd架构下载对应的版本

将mkcert单独放在一个文件夹,在终端中打开该文件夹

2.安装

在执行该命令时会弹出一个安全警告窗口,然后选择是

1
mkcert-v1.4.4-windows-amd64.exe -install
3.查看CA证书存放位置
1
mkcert-v1.4.4-windows-amd64.exe -CAROOT
4.打开windows的证书控制台

按住键盘的,“Win键+R键”调出运行框,输入certmgr.msc命令。打开证书控制台

5.生成自签证书,可供局域网内使用其他主机访问

生成 localhost+3-key.pem localhost+3.pem 两个证书

1
mkcert-v1.4.4-windows-amd64.exe localhost 127.0.0.1 ::1 192.168.1.1 (192.168.1.1 这个IP改成服务器ip,还可以添加域名)
6.在nginx中配置ssl证书
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
server {
listen 4433 ssl; # 改一下端口号,如果使用默认的端口号,可能会造成端口号冲突,导致nginx启动失败
server_name localhost; # 这里可以根据自己的需要填,我这里直接使用localhost了

ssl_certificate localhost+3-key.pem; # 这个就是证书的存放路径了,这里可以写绝对路径,也可以使用相对路径
ssl_certificate_key localhost+3.pem; # 这个就是证书的存放路径了,这里可以写绝对路径,也可以使用相对路径

ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;

ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;

location / {
root html;
index index.html index.htm;
}
}

访问 https://localhost:4433/ 即可

docker部署MySQL主从同步

docker部署MySQL主从同步

一、创建网络

1
docker network create --subnet=172.18.0.0/16 mysql-net

二、主库 my.cnf

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
[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
[mysqld]
# 设置东八区时区
default-time_zone = '+8:00'
# 限制导入和导出的数据目录
# 为空,不限制导入到处的数据目录;
secure_file_priv=
init_connect='SET collation_connection = utf8mb4_general_ci'
init_connect='SET NAMES utf8mb4'
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
skip-character-set-client-handshake
skip-name-resolve
# 开启logbin
log_bin=mysql-bin
# binlog日志格式
binlog_format=ROW
# mysql主从备份serverId
server_id=1
# 配置数据库表名小写
lower_case_table_names=1
# 指定要复制的数据库名称,这里替换为您要复制的具体数据库名。
binlog-do-db = your_database_name

三、启动主数据库

1
2
3
4
5
6
7
8
9
10
docker run -p 43306:3306 \
--name mysql_master \
--restart=always \
--privileged=true \
-v /data/mysqlc/log1:/var/log/mysql \
-v /data/mysqlc/data1:/var/lib/mysql \
-v /data/mysqlc/conf1/:/etc/mysql/ \
-v /etc/localtime:/etc/localtime:ro \
--network mysql-net --ip 172.18.0.2 \
-e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7

四、主库用户设置

1
2
3
4
5
6
7
8
9
10
docker exec -it mysql_master /bin/bash
mysql -u root -p
#查看数据库
show databases;
#切换到mysql库
use mysql;
#创建master用户
create USER 'master'@'%' IDENTIFIED BY '123456';
grant all on *.* to 'master'@'%';
FLUSH PRIVILEGES;

五、从库 my.cnf

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
[client]
default-character-set=utf8mb4

[mysql]
default-character-set=utf8mb4

[mysqld]
# 设置东八区时区
default-time_zone = '+8:00'
#设置密码验证规则
# 限制导入和导出的数据目录
# 为空,不限制导入到处的数据目录;
secure_file_priv=
init_connect='SET collation_connection = utf8mb4_general_ci'
init_connect='SET NAMES utf8mb4'
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
skip-character-set-client-handshake
skip-name-resolve

#server_id不要和主库的server_id相同就行
server_id=2
#一般从数据库作为读数据库
default-storage-engine=MyISAM
#配置数据库表名小写
lower_case_table_names=1

六、启动从库

1
2
3
4
5
6
7
8
9
10
docker run -p 53306:3306  \
--name mysql_slave \
--restart=always \
--privileged=true \
-v /data/mysqlc/log2:/var/log/mysql \
-v /data/mysqlc/data2:/var/lib/mysql \
-v /data/mysqlc/conf2/:/etc/mysql/ \
-v /etc/localtime:/etc/localtime:ro \
--network mysql-net --ip 172.18.0.3 \
-e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7

七、从库用户设置

1
2
3
4
5
6
7
8
9
10
docker exec -it mysql_slave /bin/bash
mysql -u root -p
#查看数据库
show databases;
#切换到mysql库
use mysql;
#创建slave用户
create USER 'slave'@'%' IDENTIFIED BY '123456';
grant all on *.* to 'slave'@'%';
FLUSH PRIVILEGES;

八、主库查看

1
2
3
4
5
6
show master status;
当在 MySQL 中执行 `SHOW MASTER STATUS;` 命令时,它会返回一行结果,通常包含如下几个字段:
1. File(文件名):这是二进制日志文件的名称。二进制日志文件记录了所有对数据库的更改操作,这些更改用于数据库的备份和复制。
2. Position(位置):这是在二进制日志文件中的位置,标记了数据库正在写入的具体位置。复制从这个位置开始。
3. Binlog_Do_DB(需要操作的数据库):这个字段指定了在主服务器上生成二进制日志文件时应记录的数据库。通常设置了一组数据库,只有这些数据库上的操作才会被记录。
4. Binlog_Ignore_DB(忽略操作的数据库):这个字段指定了在主服务器上生成二进制日志文件时应忽略的数据库。即使启用了全局日志记录,也不会记录这些数据库上的操作。

九、从库配置主服务器信息

1
2
3
4
5
6
7
8
9
10
stop slave;

CHANGE MASTER TO MASTER_HOST = '172.18.0.2', #主库host
MASTER_PORT = 3306,#主库端口
MASTER_USER = 'master',#主库用于binlog同步的账户
MASTER_PASSWORD = '123456',#主库用于binlog同步的账户密码
MASTER_LOG_FILE = 'binlog.000002',#主库binlog文件,show master status;File 字段
MASTER_LOG_POS = 154;#主库binlog文件位置,show master status; Position 字段

start slave;

报错处理

1
2
3
4
5
6
7
8
如果在start slave;时遇到 1872 - Slave failed to initialize relay log info structure from the repository  报错
1、停止从服务器的复制进程
STOP SLAVE;
2、清除现有的中继日志和配置信息
RESET SLAVE ALL;
3、使用 CHANGE MASTER TO 语句重新配置复制,确保你提供了正确的主服务器 IP 地址、端口、用户、密码、二进制日志文件名和位置。
4、启动从服务器的复制进程
start salve;

十、主从状态检查

1
2
3
4
在从服务器上执行 SHOW SLAVE STATUS\G; 命令,查看返回的结果。关注以下字段:
Slave_IO_State:应该是 Waiting for master to send event。
Slave_IO_Running 和 Slave_SQL_Running:应该都是 Yes,表示复制的 IO 和 SQL 线程都在运行。
Last_Error:如果有错误信息,需要根据错误信息来调试问题。

十一、停止容器并删除网络

1
2
3
4
5
6
7
8
9
10
# 关闭容器
docker stop imgid
# 删除容器
docker rm imgid
# 查看所有网络
docker network ls
# 删除指定网络
docker network rm netname
# 强制删除所有网络(需要先关闭容器再删除网络)
docker network prune -f

linux文件加密导出

1.导出数据库数据

首先,使用mysqldump命令导出数据库数据。例如,要导出名为mydatabase的数据库,可以执行以下命令:

1
mysqldump -u [username] -p[password] mydatabase > mydatabase_backup.sql

请注意,[username]和[password]应替换为您的MySQL用户名和密码。如果您不想在命令行中直接显示密码,只需使用-p标志而不跟密码,命令执行后系统会提示您输入密码。

2.生成加密密钥

使用openssl生成一个自定义的加密密钥。这个密钥将用于加密和解密数据。

1
openssl rand -base64 32 > my_encryption_key

上述命令会生成一个32字节的随机密钥,并将其以Base64编码的形式保存到my_encryption_key文件中。请确保将此文件保存在安全的地方,并且只有授权的用户可以访问。

3.加密数据

接下来,使用openssl的enc命令来加密导出的SQL文件。这里我们使用AES-256-CBC加密算法,这是一种广泛认为安全的对称加密算法。

1
openssl enc -aes-256-cbc -salt -in mydatabase_backup.sql -out mydatabase_backup_encrypted.sql -K $(cat my_encryption_key)

-K选项允许您指定一个自定义的加密密钥。在这里,我们通过$(cat my_encryption_key)命令将之前生成的密钥文件的内容传递给-K选项。加密后的数据将保存在mydatabase_backup_encrypted.sql文件中。

4.安全地分享加密数据

将加密后的文件mydatabase_backup_encrypted.sql安全地分享给开发人员。由于文件已加密,您可以通过任何安全的方式(如加密的电子邮件、安全的文件传输协议等)进行分享。

5.解密数据

开发人员收到加密文件后,需要使用相同的密钥来解密数据。首先,确保开发人员拥有my_encryption_key文件,然后使用以下命令解密数据:

1
openssl enc -d -aes-256-cbc -in mydatabase_backup_encrypted.sql -out mydatabase_backup_decrypted.sql -K $(cat my_encryption_key)

解密后的数据将保存在mydatabase_backup_decrypted.sql文件中,开发人员可以使用这个文件来恢复数据库。

注意事项:
密钥安全:确保my_encryption_key文件的安全存储和传输。不要将密钥泄露给未经授权的人员。
算法和模式选择:虽然AES-256-CBC是一个广泛认为安全的算法,但请根据您的具体需求和安全性要求选择合适的算法和加密模式。
备份原始文件:在加密之前,请确保对原始SQL文件进行备份,以防万一解密过程中出现问题。
传输安全:在分享加密文件时,使用安全的通信协议和传输方法,确保数据在传输过程中不被篡改或泄露。
遵循上述步骤,您可以安全地导出、加密、分享和解密MySQL数据库数据,同时确保数据的机密性和完整性。