前言
本小节我们学习使用Docker部署Redis集群(标准的一主两从).
案例
目录结构
- [root@iZ2ze8sm5upgi8z1dcazqeZ redis]# pwd
- /workspace/redis
- [root@iZ2ze8sm5upgi8z1dcazqeZ redis]# tree
- .
- ├── data
- │ ├── appendonly.aof
- │ ├── docker-compose.yml
- │ └── dump.rdb
- └── sentinel
- ├── config
- └── data
- 4 directories, 3 files
- [root@iZ2ze8sm5upgi8z1dcazqeZ redis]#
拉取redis镜像
docker pull redis
- [root@iZ2ze8sm5upgi8z1dcazqeZ redis]# docker images
- REPOSITORY TAG IMAGE ID CREATED SIZE
- redis latest 01a52b3b5cd1 4 hours ago 98.2MB
编写docker-compose.yml文件实现redis一主二从
version: '3.7'
services:
master:
image: redis
container_name: redis-master
restart: always
command: redis-server --port 6379 --requirepass Dustyone --appendonly yes
ports:
- 6379:6379
volumes:
- /workspace/redis/data:/data
slave1:
image: redis
container_name: redis-slave-1
restart: always
command: redis-server --slaveof 182.92.0.228 6379 --port 6380 --requirepass Dustyone --masterauth Dustyone --appendonly yes
ports:
- 6380:6380
volumes:
- /workspace/redis/data:/data
slave2:
image: redis
container_name: redis-slave-2
restart: always
command: redis-server --slaveof 182.92.0.228 6379 --port 6381 --requirepass Dustyone --masterauth Dustyone --appendonly yes
ports:
- 6381:6381
volumes:
- /workspace/redis/data:/data
version docker文件的版本
image 指定容器镜像就是之前拉取的redis镜像
container_name 给这个镜像起一个别名
restart always:表名开机自启动
command 相当于执行一些命令 (–requirepass 指定redis密码 --appendonly yes 这个命令是用于开启redis数据持久化)
ports 端口映射,将容器的端口映射到对应宿主机的端口
volumes 数据卷的映射.因为一旦容器停止了那么里面的数据也没有.所以我们需要把这个数据文件放在外面,然后映射到容器中
启动redis,使用如下命令 -d 挂在后台
- docker-compose up -d
查看redis是否启动成功,使用如下命令,看到红框中的三个并且状态是 UP 则表明启动redis成功
[root@iZ2ze8sm5upgi8z1dcazqeZ redis]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a43bcfd77e5a redis "docker-entrypoint.s…" 14 minutes ago Up 14 minutes 6379/tcp, 0.0.0.0:6380->6380/tcp redis-slave-1
19b10ac59405 redis "docker-entrypoint.s…" 14 minutes ago Up 14 minutes 6379/tcp, 0.0.0.0:6381->6381/tcp redis-slave-2
9acdc4bd4086 redis "docker-entrypoint.s…" 14 minutes ago Up 14 minutes 0.0.0.0:6379->6379/tcp redis-master
验证redis是否实现了一主二从的功能
进入主redis容器中,使用如下命令
- docker exec -it redis-master bash
链接Redis Client并对主Redis操作
[root@iZ2ze8sm5upgi8z1dcazqeZ redis]# docker exec -it redis-master bash
root@9acdc4bd4086:/data# redis-cli
127.0.0.1:6379> auth Dustyone
OK
127.0.0.1:6379> set sales Dustyone
OK
127.0.0.1:6379> get sales
"Dustyone"
127.0.0.1:6379>
进入任意从Redis并验证数据是否同步
ctrl+c退出redis,输入exit如下命令退出容器。
[root@iZ2ze8sm5upgi8z1dcazqeZ redis]# docker exec -it redis-slave-1 bash
root@a43bcfd77e5a:/data# redis-cli -p 6380
127.0.0.1:6380> auth Dustyone
OK
127.0.0.1:6380> keys *
1) "broker"
2) "sales"
127.0.0.1:6380> get slave
(nil)
127.0.0.1:6380> get sales
"Dustyone"
127.0.0.1:6380> set sales Aron
(error) READONLY You can't write against a read only replica.
127.0.0.1:6380>
如上命令中我们尝试了在从Redis上做set操作,结果提示从Redis只有读的操作。
如此我们便验证完毕了。
小结
如果使用失败了,可以使用如下命令查看日志,观察是什么原因造成的
docker logs -f 容器Id
停止redis,使用如下命令
docker-compose down
docker stop 容器Id
docker rm 容器Id
停止并移除所有容器可以使用如下命令
docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)
启动redis
docker-compose up -d
在使用Docker-compose 部署Docker集群式,在指定主机IP(主从)时,必须确保指定主机的端口在ECS上的安全组规则开启,否则在主Redis无法将数据同步至其他Slave上去。
比如我们的主从部署在182.92.0.228的6379/6380/6381上,该ECS实例的安全组规则必须开放6379-6381
- 本小节案例中是将Redis集群部署在同一服务器上的,如若需要将主从Redis部署在不同服务器上,按照本案例提供的思路,将各个配置项中的IP地址替换成相应的IP地址即可。
本小节我们学习一下使用Dokcer部署Redis集群之后为确保Redis HA性能实现Sentinel模式。
如何使用Docker部署Redis集群。
案例
参照前文,假设你已经成功部署了Redis集群。
目录参考
- [root@iZ2ze8sm5upgi8z1dcazqeZ redis]# tree
- .
- ├── data
- │ ├── appendonly.aof
- │ ├── docker-compose.yml
- │ └── dump.rdb
- └── sentinel
- ├── config
- │ ├── docker-compose.yml
- │ ├── sentinel1.conf
- │ ├── sentinel2.conf
- │ ├── sentinel3.conf
- │ └── sentinel.conf
- └── data
- 4 directories, 8 files
- [root@iZ2ze8sm5upgi8z1dcazqeZ redis]#
在中workspace/redis/sentinel/config编写sentinel.conf文件
port 26379
dir /workspace/redis/sentinel/config
# 自定义集群名,其中 182.92.0.228 为 redis-master 的 ip,6379 为 redis-master 的端口,2 为最小投票数(因为有 3 台 Sentinel 所以可以设置成 2)
sentinel monitor redis-master 182.92.0.228 6379 2
sentinel down-after-milliseconds redis-master 30000
sentinel parallel-syncs redis-master 1
sentinel auth-pass redis-master Dustyone
sentinel failover-timeout redis-master 180000
sentinel deny-scripts-reconfig yes
将sentinel.conf复制三份,复制文件与sentinel.conf同路径
- cp sentinel.conf sentinel1.conf
- cp sentinel.conf sentinel2.conf
- cp sentinel.conf sentinel3.conf
编写docker-composr.yml
version: '3.7'
services:
sentinel1:
image: redis
container_name: redis-sentinel-1
command: redis-sentinel /workspace/redis/sentinel/config/sentinel.conf
restart: always
ports:
- 26379:26379
volumes:
- /workspace/redis/sentinel/config/sentinel1.conf:/workspace/redis/sentinel/config/sentinel.conf
sentinel2:
image: redis
container_name: redis-sentinel-2
command: redis-sentinel /workspace/redis/sentinel/config/sentinel.conf
restart: always
ports:
- 26380:26380
volumes:
- /workspace/redis/sentinel/config/sentinel2.conf:/workspace/redis/sentinel/config/sentinel.conf
sentinel3:
image: redis
container_name: redis-sentinel-3
command: redis-sentinel /workspace/redis/sentinel/config/sentinel.conf
restart: always
ports:
- 26381:26381
volumes:
- /workspace/redis/sentinel/config/sentinel3.conf:/workspace/redis/sentinel/config/sentinel.conf
在/workspace/redis/sentinel/config启动docker-compose.yml
- docker-compose up -d
查看redis-sentinel是否启动成功
- [root@iZ2ze8sm5upgi8z1dcazqeZ config]# docker ps -a
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 72eb47246eec redis "docker-entrypoint.s…" 6 minutes ago Up 6 minutes 6379/tcp, 0.0.0.0:26380->26380/tcp redis-sentinel-2
- c68c5d3c1ecf redis "docker-entrypoint.s…" 6 minutes ago Up 6 minutes 6379/tcp, 0.0.0.0:26381->26381/tcp redis-sentinel-3
- a5df697f45bd redis "docker-entrypoint.s…" 6 minutes ago Up 6 minutes 6379/tcp, 0.0.0.0:26379->26379/tcp redis-sentinel-1
- a43bcfd77e5a redis "docker-entrypoint.s…" 2 hours ago Up 2 hours 6379/tcp, 0.0.0.0:6380->6380/tcp redis-slave-1
- 19b10ac59405 redis "docker-entrypoint.s…" 2 hours ago Up 2 hours 6379/tcp, 0.0.0.0:6381->6381/tcp redis-slave-2
- 9acdc4bd4086 redis "docker-entrypoint.s…" 2 hours ago Up 16 minutes 0.0.0.0:6379->6379/tcp redis-master
进入redis-sentinel容器中,查看主redis连接状态
[root@iZ2ze8sm5upgi8z1dcazqeZ config]# docker exec -it redis-sentinel-1 bash
root@a5df697f45bd:/data# redis-cli -p 26379
127.0.0.1:26379> sentinel master redis-master
1) "name"
2) "redis-master"
3) "ip"
4) "182.92.0.228"
5) "port"
6) "6380"
7) "runid"
8) "4ab8f3fb673651053d3750dd8a72d98f1bc872c1"
9) "flags"
10) "master"
11) "link-pending-commands"
12) "0"
13) "link-refcount"
14) "1"
15) "last-ping-sent"
16) "0"
17) "last-ok-ping-reply"
18) "858"
19) "last-ping-reply"
20) "858"
21) "down-after-milliseconds"
22) "30000"
23) "info-refresh"
24) "8224"
25) "role-reported"
26) "master"
27) "role-reported-time"
28) "520683"
29) "config-epoch"
30) "1"
31) "num-slaves"
32) "2"
33) "num-other-sentinels"
34) "2"
35) "quorum"
36) "2"
37) "failover-timeout"
38) "180000"
39) "parallel-syncs"
40) "1"
127.0.0.1:26379>
查看从redis信息是否正常
127.0.0.1:26379> sentinel slaves redis-master
1) 1) "name"
2) "182.92.0.228:6381"
3) "ip"
4) "182.92.0.228"
5) "port"
6) "6381"
7) "runid"
8) "54c6883557cc0cbb28e521997bb1b25ddd2908d9"
9) "flags"
10) "slave"
11) "link-pending-commands"
12) "0"
13) "link-refcount"
14) "1"
15) "last-ping-sent"
16) "0"
17) "last-ok-ping-reply"
18) "789"
19) "last-ping-reply"
20) "789"
21) "down-after-milliseconds"
22) "30000"
23) "info-refresh"
24) "1724"
25) "role-reported"
26) "slave"
27) "role-reported-time"
28) "644775"
29) "master-link-down-time"
30) "0"
31) "master-link-status"
32) "ok"
33) "master-host"
34) "182.92.0.228"
35) "master-port"
36) "6380"
37) "slave-priority"
38) "100"
39) "slave-repl-offset"
40) "432646"
2) 1) "name"
2) "182.92.0.228:6379"
3) "ip"
4) "182.92.0.228"
5) "port"
6) "6379"
7) "runid"
8) "e286d7fa7661b9c9cf4c984ee36ddb69a21ccc5b"
9) "flags"
10) "slave"
11) "link-pending-commands"
12) "0"
13) "link-refcount"
14) "1"
15) "last-ping-sent"
16) "0"
17) "last-ok-ping-reply"
18) "623"
19) "last-ping-reply"
20) "623"
21) "down-after-milliseconds"
22) "30000"
23) "info-refresh"
24) "623"
25) "role-reported"
26) "slave"
27) "role-reported-time"
28) "644775"
29) "master-link-down-time"
30) "1569469175000"
31) "master-link-status"
32) "err"
33) "master-host"
34) "182.92.0.228"
35) "master-port"
36) "6380"
37) "slave-priority"
38) "100"
39) "slave-repl-offset"
40) "1"
127.0.0.1:26379>
测试主redis挂了之后,哨兵能否正常选举redis
停掉主redis
docker stop redis-master
查看redis-sentinel日志,看其将那个redis选举为主
[root@iZ2ze8sm5upgi8z1dcazqeZ config]# docker logs redis-sentinel-2
1:X 26 Sep 2019 03:28:51.588 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:X 26 Sep 2019 03:28:51.588 # Redis version=5.0.6, bits=64, commit=00000000, modified=0, pid=1, just started
1:X 26 Sep 2019 03:28:51.588 # Configuration loaded
1:X 26 Sep 2019 03:28:51.590 * Running mode=sentinel, port=26379.
1:X 26 Sep 2019 03:28:51.590 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
1:X 26 Sep 2019 03:28:51.590 # Sentinel ID is 02dd0257960310b300feef92f56d484f55df4b44
1:X 26 Sep 2019 03:28:51.590 # +monitor master redis-master 182.92.0.228 6380 quorum 2
1:X 26 Sep 2019 03:28:53.707 * +sentinel-address-switch master redis-master 182.92.0.228 6380 ip 172.26.0.4 port 26379 for e41d3841f9c208262b8564d1678050b8e8fb2e06
1:X 26 Sep 2019 03:28:53.738 * +sentinel-address-switch master redis-master 182.92.0.228 6380 ip 172.26.0.3 port 26379 for 8be5d0ebdebe9b14139ac7db9b4d9d97f613e3e2
1:X 26 Sep 2019 03:43:50.239 # +sdown slave 182.92.0.228:6379 182.92.0.228 6379 @ redis-master 182.92.0.228 6380
[root@iZ2ze8sm5upgi8z1dcazqeZ config]#
如上可知,6380上的Redis被选举为主Redis了。
测试端口号为6380的redis是否具备写功能,如下则表明成功
[root@iZ2ze8sm5upgi8z1dcazqeZ config]# docker exec -it redis-slave-1 bash
root@a43bcfd77e5a:/data# redis-cli -p 6380
127.0.0.1:6380> auth Dustyone
OK
127.0.0.1:6380> keys *
1) "reob"
2) "broker"
3) "sales"
127.0.0.1:6380> set buyers Duyb
OK
127.0.0.1:6380> keys *
1) "reob"
2) "broker"
3) "buyers"
4) "sales"
127.0.0.1:6380> get buyers
"Duyb"
127.0.0.1:6380>
如上便检验成功了
小节
本案例实现为单机版集群,如若主从不在同一服务器上,请设置合理的主从之间的心跳检测时间
场景:本案例中将6379的Redis设置成主Redis,当主Redis挂了之后在重新加入集群时,不再是Master角色了。
开发的安全组