有人在学习Docker 之部署Redis集群之后,达到了16薪

前言

本小节我们学习使用Docker部署Redis集群(标准的一主两从).

案例

目录结构

[root@iZ2ze8sm5upgi8z1dcazqeZ redis]# pwd/workspace/redis[root@iZ2ze8sm5upgi8z1dcazqeZ redis]# tree.├── data│ ├── appendonly.aof│ ├── docker-compose.yml│ └── dump.rdb└── sentinel ├── config └── data4 directories, 3 files[root@iZ2ze8sm5upgi8z1dcazqeZ redis]#

拉取redis镜像

docker pull redis

[root@iZ2ze8sm5upgi8z1dcazqeZ redis]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEredis latest 01a52b3b5cd1 4 hours ago 98.2MB


编写docker-compose.yml文件实现redis一主二从

<code>version: '3.7'/<code>

<code>services:/<code>

<code> master:/<code>

<code> image: redis/<code>

<code> container_name: redis-master/<code>

<code> restart: always/<code>

<code> command: redis-server --port 6379 --requirepass Dustyone --appendonly yes/<code>

<code> ports:/<code>

<code> - 6379:6379/<code>

<code> volumes:/<code>

<code> - /workspace/redis/data:/data/<code>

<code> slave1:/<code>

<code> image: redis/<code>

<code> container_name: redis-slave-1/<code>

<code> restart: always/<code>

<code> command: redis-server --slaveof 182.92.0.228 6379 --port 6380 --requirepass Dustyone --masterauth Dustyone --appendonly yes/<code>

<code> ports:/<code>

<code> - 6380:6380/<code>

<code> volumes:/<code>

<code> - /workspace/redis/data:/data/<code>

<code> slave2:/<code>

<code> image: redis/<code>

<code> container_name: redis-slave-2/<code>

<code> restart: always/<code>

<code> command: redis-server --slaveof 182.92.0.228 6379 --port 6381 --requirepass Dustyone --masterauth Dustyone --appendonly yes/<code>

<code> ports:/<code>

<code> - 6381:6381/<code>

<code> volumes:/<code>

<code> - /workspace/redis/data:/data/<code>

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成功

<code>[root@iZ2ze8sm5upgi8z1dcazqeZ redis]# docker ps -a/<code>

<code>CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES/<code>

<code>a43bcfd77e5a redis "docker-entrypoint.s…" 14 minutes ago Up 14 minutes 6379/tcp, 0.0.0.0:6380->6380/tcp redis-slave-1/<code>

<code>19b10ac59405 redis "docker-entrypoint.s…" 14 minutes ago Up 14 minutes 6379/tcp, 0.0.0.0:6381->6381/tcp redis-slave-2/<code>

<code>9acdc4bd4086 redis "docker-entrypoint.s…" 14 minutes ago Up 14 minutes 0.0.0.0:6379->6379/tcp redis-master/<code>

验证redis是否实现了一主二从的功能

进入主redis容器中,使用如下命令

docker exec -it redis-master bash

链接Redis Client并对主Redis操作

<code>[root@iZ2ze8sm5upgi8z1dcazqeZ redis]# docker exec -it redis-master bash/<code>

<code>root@9acdc4bd4086:/data# redis-cli/<code>

<code>127.0.0.1:6379> auth Dustyone/<code>

<code>OK/<code>

<code>127.0.0.1:6379> set sales Dustyone/<code>

<code>OK/<code>

<code>127.0.0.1:6379> get sales/<code>

<code>"Dustyone"/<code>

<code>127.0.0.1:6379>/<code>

进入任意从Redis并验证数据是否同步

ctrl+c退出redis,输入exit如下命令退出容器。

<code>[root@iZ2ze8sm5upgi8z1dcazqeZ redis]# docker exec -it redis-slave-1 bash/<code>

<code>root@a43bcfd77e5a:/data# redis-cli -p 6380/<code>

<code>127.0.0.1:6380> auth Dustyone/<code>

<code>OK/<code>

<code>127.0.0.1:6380> keys */<code>

<code>1) "broker"/<code>

<code>2) "sales"/<code>

<code>127.0.0.1:6380> get slave/<code>

<code>(nil)/<code>

<code>127.0.0.1:6380> get sales/<code>

<code>"Dustyone"/<code>

<code>127.0.0.1:6380> set sales Aron/<code>

<code>(error) READONLY You can't write against a read only replica./<code>

<code>127.0.0.1:6380> /<code>


如上命令中我们尝试了在从Redis上做set操作,结果提示从Redis只有读的操作。

如此我们便验证完毕了。

小结

如果使用失败了,可以使用如下命令查看日志,观察是什么原因造成的

docker logs -f 容器Id

停止redis,使用如下命令

<code>docker-compose down/<code>

<code>docker stop 容器Id/<code>

<code>docker rm 容器Id/<code>


停止并移除所有容器可以使用如下命令

<code>docker stop $(docker ps -a -q)/<code>

<code>docker rm $(docker ps -a -q)/<code>

启动redis

<code>docker-compose up -d/<code>


在使用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 └── data4 directories, 8 files[root@iZ2ze8sm5upgi8z1dcazqeZ redis]#

在中workspace/redis/sentinel/config编写sentinel.conf文件

port 26379

<code>dir /workspace/redis/sentinel/config/<code>

<code># 自定义集群名,其中 182.92.0.228 为 redis-master 的 ip,6379 为 redis-master 的端口,2 为最小投票数(因为有 3 台 Sentinel 所以可以设置成 2)/<code>

<code>sentinel monitor redis-master 182.92.0.228 6379 2/<code>

<code>sentinel down-after-milliseconds redis-master 30000/<code>

<code>sentinel parallel-syncs redis-master 1/<code>

<code>sentinel auth-pass redis-master Dustyone/<code>

<code>sentinel failover-timeout redis-master 180000/<code>

<code>sentinel deny-scripts-reconfig yes/<code>

将sentinel.conf复制三份,复制文件与sentinel.conf同路径

cp sentinel.conf sentinel1.confcp sentinel.conf sentinel2.confcp sentinel.conf sentinel3.conf

编写docker-composr.yml

<code>version: '3.7'/<code>

<code>services:/<code>

<code> sentinel1:/<code>

<code> image: redis/<code>

<code> container_name: redis-sentinel-1/<code>

<code> command: redis-sentinel /workspace/redis/sentinel/config/sentinel.conf/<code>

<code> restart: always/<code>

<code> ports:/<code>

<code> - 26379:26379/<code>

<code> volumes:/<code>

<code> - /workspace/redis/sentinel/config/sentinel1.conf:/workspace/redis/sentinel/config/sentinel.conf/<code>

<code> sentinel2:/<code>

<code> image: redis/<code>

<code> container_name: redis-sentinel-2/<code>

<code> command: redis-sentinel /workspace/redis/sentinel/config/sentinel.conf/<code>

<code> restart: always/<code>

<code> ports:/<code>

<code> - 26380:26380/<code>

<code> volumes:/<code>

<code> - /workspace/redis/sentinel/config/sentinel2.conf:/workspace/redis/sentinel/config/sentinel.conf/<code>

<code> sentinel3:/<code>

<code> image: redis/<code>

<code> container_name: redis-sentinel-3/<code>

<code> command: redis-sentinel /workspace/redis/sentinel/config/sentinel.conf/<code>

<code> restart: always/<code>

<code> ports:/<code>

<code> - 26381:26381/<code>

<code> volumes:/<code>

<code> - /workspace/redis/sentinel/config/sentinel3.conf:/workspace/redis/sentinel/config/sentinel.conf/<code>

在/workspace/redis/sentinel/config启动docker-compose.yml

docker-compose up -d

查看redis-sentinel是否启动成功

[root@iZ2ze8sm5upgi8z1dcazqeZ config]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES72eb47246eec redis "docker-entrypoint.s…" 6 minutes ago Up 6 minutes 6379/tcp, 0.0.0.0:26380->26380/tcp redis-sentinel-2c68c5d3c1ecf redis "docker-entrypoint.s…" 6 minutes ago Up 6 minutes 6379/tcp, 0.0.0.0:26381->26381/tcp redis-sentinel-3a5df697f45bd redis "docker-entrypoint.s…" 6 minutes ago Up 6 minutes 6379/tcp, 0.0.0.0:26379->26379/tcp redis-sentinel-1a43bcfd77e5a redis "docker-entrypoint.s…" 2 hours ago Up 2 hours 6379/tcp, 0.0.0.0:6380->6380/tcp redis-slave-119b10ac59405 redis "docker-entrypoint.s…" 2 hours ago Up 2 hours 6379/tcp, 0.0.0.0:6381->6381/tcp redis-slave-29acdc4bd4086 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选举为主

<code>[root@iZ2ze8sm5upgi8z1dcazqeZ config]# docker logs redis-sentinel-2/<code>

<code>1:X 26 Sep 2019 03:28:51.588 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo/<code>

<code>1:X 26 Sep 2019 03:28:51.588 # Redis version=5.0.6, bits=64, commit=00000000, modified=0, pid=1, just started/<code>

<code>1:X 26 Sep 2019 03:28:51.588 # Configuration loaded/<code>

<code>1:X 26 Sep 2019 03:28:51.590 * Running mode=sentinel, port=26379./<code>

<code>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./<code>

<code>1:X 26 Sep 2019 03:28:51.590 # Sentinel ID is 02dd0257960310b300feef92f56d484f55df4b44/<code>

<code>1:X 26 Sep 2019 03:28:51.590 # +monitor master redis-master 182.92.0.228 6380 quorum 2/<code>

<code>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/<code>

<code>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/<code>

<code>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/<code>

<code>[root@iZ2ze8sm5upgi8z1dcazqeZ config]# /<code>

如上可知,6380上的Redis被选举为主Redis了。

测试端口号为6380的redis是否具备写功能,如下则表明成功

<code>[root@iZ2ze8sm5upgi8z1dcazqeZ config]# docker exec -it redis-slave-1 bash/<code>

<code>root@a43bcfd77e5a:/data# redis-cli -p 6380/<code>

<code>127.0.0.1:6380> auth Dustyone/<code>

<code>OK/<code>

<code>127.0.0.1:6380> keys */<code>

<code>1) "reob"/<code>

<code>2) "broker"/<code>

<code>3) "sales"/<code>

<code>127.0.0.1:6380> set buyers Duyb/<code>

<code>OK/<code>

<code>127.0.0.1:6380> keys */<code>

<code>1) "reob"/<code>

<code>2) "broker"/<code>

<code>3) "buyers"/<code>

<code>4) "sales"/<code>

<code>127.0.0.1:6380> get buyers/<code>

<code>"Duyb"/<code>

<code>127.0.0.1:6380> /<code>

如上便检验成功了

小节

本案例实现为单机版集群,如若主从不在同一服务器上,请设置合理的主从之间的心跳检测时间

场景:本案例中将6379的Redis设置成主Redis,当主Redis挂了之后在重新加入集群时,不再是Master角色了。

开发的安全组