该篇博文,主要介绍如何基于Docker搭建Redis集群,以及解决Redis集群搭建过程中,"Waiting for the cluster to join"环节阻塞等问题。
通过docker search redis,查询当前提供的Redis镜像,然后选择一个合适的镜像,基于docker pull命令下载即可。
当然,也可以通过诸如wget下载Redis文件、编译、执行redis-server等命令,编写Docker File文件,然后生成一个Docker镜像,这里不再阐述。
Redis镜像获取成功后,通过docker run命令创建6个镜像,这里先提供一种创建方式,在后续解答"Waiting for the cluster to join"环节,再提供另外一种。
docker run -d --net host --name redis-node1 -v /home/install/redis/data/node1:/data redis --cluster-enabled yes --cluster-config-file nodes-node-1.conf --port 6379
docker run -d --net host --name redis-node2 -v /home/install/redis/data/node2:/data redis --cluster-enabled yes --cluster-config-file nodes-node-2.conf --port 6380
docker run -d --net host --name redis-node3 -v /home/install/redis/data/node3:/data redis --cluster-enabled yes --cluster-config-file nodes-node-3.conf --port 6381
docker run -d --net host --name redis-node4 -v /home/install/redis/data/node4:/data redis --cluster-enabled yes --cluster-config-file nodes-node-4.conf --port 6382
docker run -d --net host --name redis-node5 -v /home/install/redis/data/node5:/data redis --cluster-enabled yes --cluster-config-file nodes-node-5.conf --port 6383
docker run -d --net host --name redis-node6 -v /home/install/redis/data/node6:/data redis --cluster-enabled yes --cluster-config-file nodes-node-6.conf --port 6384
通过docker ps,可查看到之前创建的6个实例。到此,6个Redis节点创建完成。
进入到redis-node1容器,通过cluster info命令,查看集群状态
由于此时,尚未进行集群槽位分配等操作,因此,当前集群状态为fail,且cluster_slots_ok数为0。接下来,在redis-node1容器中,执行redis-cli --cluster create命令,进行集群初始化
redis-cli --cluster create 192.168.0.100:6379 192.168.0.100:6380 192.168.0.100:6381 192.168.0.100:6382 192.168.0.100:6383 192.168.0.100:6384 --cluster-replicas 1
上述命令执行后,在此执行cluster info命令,此时cluster_state为ok,且cluster_slot_ok为16384。
简单操作一下Redis,命令成功执行。
同时,Redis Desktop Manager工具也能访问刚搭建的Redis集群,到此,Redis集群成功创建。
笔者在刚开始使用Docker搭建Redis集群的时候,在redis-cli --cluster create环节,一直卡到"Waiting for the cluster to join”环节。百思不得其解,后续通过Redis官网,耗费一段时间后,才得以解决。
Redis集群中的各个节点,需要开放一个端口,同其他节点建立连接,用于接收心跳数据等操作。也就是说,redis-node1节点,开放6379端口供client连接时,同时提供16379端口(10000 + 6379),供其他Redis节点连接。
集群初始化过程中,需要同其他Redis建立连接,进行通信。若节点间无法连接,此时会阻塞,这也就是一直阻塞到"Waiting for the cluster to join"环节的原因。
细心的读者,不难发现,上述给出Redis节点创建命令,通过–net host,指定网络类型为host,使得容器与宿主机使用同一网络,从而规避了这类问题。
当然,若不想修改容器网络类型的话,则,需要同时暴露两个端口,用于提供client和其他节点,进行通信。命令如下所示
docker run -d --name redis-node1 -v /home/install/redis/data/node1:/data -p 6379:6379 -p 16379:16379 redis --cluster-enabled yes --cluster-config-file nodes-node-1.conf --port 6379
docker run -d --name redis-node2 -v /home/install/redis/data/node2:/data -p 6380:6380 -p 16380:16380 redis --cluster-enabled yes --cluster-config-file nodes-node-2.conf --port 6380
docker run -d --name redis-node3 -v /home/install/redis/data/node3:/data -p 6381:6381 -p 16381:16381 redis --cluster-enabled yes --cluster-config-file nodes-node-3.conf --port 6381
docker run -d --name redis-node4 -v /home/install/redis/data/node4:/data -p 6382:6382 -p 16382:16382 redis --cluster-enabled yes --cluster-config-file nodes-node-4.conf --port 6382
docker run -d --name redis-node5 -v /home/install/redis/data/node5:/data -p 6383:6383 -p 16383:16383 redis --cluster-enabled yes --cluster-config-file nodes-node-5.conf --port 6383
docker run -d --name redis-node6 -v /home/install/redis/data/node6:/data -p 6384:6384 -p 16384:16384 redis --cluster-enabled yes --cluster-config-file nodes-node-6.conf --port 6384
通过上述介绍方式,创建的Redis集群,是没有认证功能的。那么,如何创建需要认证的集群呢?其实也简单,在创建Redis节点的时候,指定–requirepass XXX参数,开启认证(XXX,指的是认证密码)。有一个特别需要注意的是,若创建的节点需要认证,那么在集群初始化时,需要额外通过-a参数,指定节点认证密码,否则,会出现如下错误:
[ERR] Node 192.168.0.100:6379 NOAUTH Authentication required
docker run -d --name redis-node1 -v /home/install/redis/data/node1:/data -p 6379:6379 -p 16379:16379 redis --cluster-enabled yes --cluster-config-file nodes-node-1.conf --port 6379 --requirepass xxx
……//省略其余5个节点
redis-cli --cluster create 192.168.0.100:6379 192.168.0.100:6380 192.168.0.100:6381 192.168.0.100:6382 192.168.0.100:6383 192.168.0.100:6384 -a xxx --cluster-replicas 1
进入到Redis,通过config get appendonly命令,发现,上述创建的集群,没有开启AOF持久化。
那么,如果想开启AOF持久化,要怎么操作呢?笔者这边,想到如下两种方式,开启AOF持久化
redis-cli -c -h 192.168.0.100 -p 6379 -c config set appendonly yes
…… //省略其余5个
// 开启认证的时候,添加参数(请自行替换密码)
redis-cli -a que.longjiang --cluster call config set appendonly yes
进入到/data目录,可以发现,此时同时存在了rdb和aof文件,代表aof持久化成功。
上述提供的容器创建命令,指定了一些参数,如开启集群、端口等。那么,想必各位读者比较好奇,为什么是这些参数,以及还可以设置哪些其他参数呢?
要想解答这个问题,就需要知道这个镜像的创建细节。可通过docker inspect、docker history等命令获取镜像创建信息。
如下为docker inspect redis命令输出结果,通过该结果,可以知道该镜像暴露的端口、指定命令、工作目录等信息。
另一个比较直观的是docker history xxx命令,通过该命令,可以很明显查询该镜像各层信息。其中CREATED BY部分是截断显示,可添加–no-trunc命令,查看完整信息。
通过该命令,可以大致知道该镜像Docker File文件内容。
不难发现,当前镜像从Redis官网下载Redis后,进行编译等一系列操作后,生成的镜像。也就是说,Redis官方支持的参数,这里都可以指定。