使用Docker配置Redis主从复制

这篇文章主要介绍如何使用Docker在本机搭建一个带有主从复制功能的Redis环境,内容包括涉及的目录结构、docker-compose.yml的编写,以及结果的验证。

目录结构

本文将采用如下的目录结构,其中data目录将用于存放各个容器的数据,server目录存放docker-compose.yml以及针对masterslave节点的配置文件。

1
2
3
4
5
6
.
├── data
└── server
├── docker-compose.yml
├── redis-master.conf
└── redis-slave.conf

配置Redis节点

配置master节点

编辑redis-master.conf,修改下列配置:

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
# 监听来自外部的连接
bind 0.0.0.0

# 启用保护模式
# 即在没有使用bind指令绑定具体地址时
# 或在没有设定密码时
# Redis将拒绝来自外部的连接
protected-mode yes

# 监听端口
port 6379

# 启动时不打印logo
# 这个不重要,想看logo就打开它
always-show-logo no

# 设定密码认证
requirepass redis

# 禁用KEYS命令
# 一方面 KEYS * 命令可以列出所有的键,会影响数据安全
# 另一方面 KEYS 命令会阻塞数据库,在数据库中存储了大量数据时,该命令会消耗很长时间
# 期间对Redis的访问也会被阻塞,而当锁释放的一瞬间,大量请求涌入Redis,会造成Redis直接崩溃
rename-command KEYS ""

# 此外还应禁止 FLUSHALL 和 FLUSHDB 命令
# 这两个命令会清空数据,并且不会失败

配置slave节点

编辑redis-slave.conf,修改下列配置:

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
# 监听来自外部的连接
bind 0.0.0.0

# 启用保护模式
# 即在没有使用bind指令绑定具体地址时
# 或在没有设定密码时
# Redis将拒绝来自外部的连接
protected-mode yes

# 监听端口
port 6379

# 启动时不打印logo
# 这个不重要,想看logo就打开它
always-show-logo no

# 设定密码认证
requirepass redis

# 禁用KEYS命令
# 一方面 KEYS * 命令可以列出所有的键,会影响数据安全
# 另一方面 KEYS 命令会阻塞数据库,在数据库中存储了大量数据时,该命令会消耗很长时间
# 期间对Redis的访问也会被阻塞,而当锁释放的一瞬间,大量请求涌入Redis,会造成Redis直接崩溃
rename-command KEYS ""

# 此外还应禁止 FLUSHALL 和 FLUSHDB 命令
# 这两个命令会清空数据,并且不会失败

# 配置master节点信息
# 格式:
#slaveof <masterip> <masterport>
# 此处masterip所指定的redis-server-master是运行master节点的容器名
# Docker容器间可以使用容器名代替实际的IP地址来通信
slaveof redis-server-master 6379

# 设定连接主节点所使用的密码
masterauth "redis"

配置及启动容器

编写docker-compose.yml

本例中使用docker-compose编排相关容器。要说为什么不用Kubernetes,那是因为对于一个示例来说这玩意太重了。说的一套一套的还不是因为不会用

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
version: '3'

services:
# 主节点容器配置
redis-server-master:
image: redis
# 对应slave节点配置的主节点地址
container_name: redis-server-master
restart: always
# 向外暴露6379端口
ports:
- 6379:6379
networks:
# 最下面的networks部分定义了一个容器网络,在这里将该容器加入这个网络
- redis-cluster
volumes:
# 将配置文件映射到容器内
- ./redis-master.conf:/usr/local/etc/redis/redis.conf
# 将数据文件保存到本地
- ../data/redis-master:/data
# 根据Redis需要调整系统参数
sysctls:
net.core.somaxconn: '511'
# 根据指定的配置文件来启动Redis服务器
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
# 从节点-1容器配置
# 下面内容大同小异,不做重复解释
redis-server-slave-1:
image: redis
container_name: redis-server-slave-1
restart: always
networks:
- redis-cluster
volumes:
- ./redis-slave.conf:/usr/local/etc/redis/redis.conf
- ../data/redis-slave-1:/data
sysctls:
net.core.somaxconn: '511'
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
# 从节点-2容器配置
# 下面内容大同小异,不做重复解释
redis-server-slave-2:
image: redis
container_name: redis-server-slave-2
restart: always
networks:
- redis-cluster
volumes:
- ./redis-slave.conf:/usr/local/etc/redis/redis.conf
- ../data/redis-slave-2:/data
sysctls:
net.core.somaxconn: '511'
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]

# 创建一个容器网络,并命名
networks:
redis-cluster:

启动容器

docker-compose.yml所在位置执行docker-compose up即可启动上述三个容器,docker-compose会将容器日志打印到终端,在日志中可以看到三个Redis服务器在启动过程中的动作,以及从节点加入主节点的信息。

启动成功后,可以在本机使用redis-cli连接至主节点。连接成功后,可以使用info replication命令检查主从复制的信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
127.0.0.1:6379> auth redis
OK
127.0.0.1:6379> info replicas
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=172.28.0.4,port=6379,state=online,offset=1177967,lag=1
slave1:ip=172.28.0.3,port=6379,state=online,offset=1178106,lag=0
master_replid:0bf82af249e03abf769d71c45797942fc649ffaa
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1178245
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:129670
repl_backlog_histlen:1048576

其中第6行的role:master指示该节点为主节点,第7行的connected_slaves:2说明当前有2个从节点,第8、9行则是两个从节点的信息,包括它们的地址、端口号,和状态。

如果此时查看该项目的目录结构,则可以发现在data目录中增加了三个Redis服务器的数据目录。

1
2
3
4
5
6
7
8
9
10
11
12
.
├── data
│   ├── redis-master
│   │   └── dump.rdb
│   ├── redis-slave-1
│   │   └── dump.rdb
│   └── redis-slave-2
│   └── dump.rdb
└── server
├── docker-compose.yml
├── redis-master.conf
└── redis-slave.conf

系列博文