基于docker搭建redis集群
上篇已写《linux离线安装docker》,再来写下基于docker搭建redis集群。
- 在docker已安装完毕的情况下,拉取redis镜像
#这里拉取最新的redis镜像。当然也可以拉取指定版本的镜像 docker pull redis:5.0 docker pull redis
- 创建redis容器
#命令如下
docker create --name redis-node1 --net=host -v /data/redis-data/node1:/data redis --cluster-enabled yes --cluster-config-file nodes-node-1.conf --cluster-node-timeout 10000 --appendonly yes --port 6371
docker create --name redis-node2 --net=host -v /data/redis-data/node2:/data redis --cluster-enabled yes --cluster-config-file nodes-node-2.conf --cluster-node-timeout 10000 --appendonly yes --port 6372
docker create --name redis-node3 --net=host -v /data/redis-data/node3:/data redis --cluster-enabled yes --cluster-config-file nodes-node-3.conf --cluster-node-timeout 10000 --appendonly yes --port 6373
docker create --name redis-node4 --net=host -v /data/redis-data/node4:/data redis --cluster-enabled yes --cluster-config-file nodes-node-4.conf --cluster-node-timeout 10000 --appendonly yes --port 6374
docker create --name redis-node5 --net=host -v /data/redis-data/node5:/data redis --cluster-enabled yes --cluster-config-file nodes-node-5.conf --cluster-node-timeout 10000 --appendonly yes --port 6375
docker create --name redis-node6 --net=host -v /data/redis-data/node6:/data redis --cluster-enabled yes --cluster-config-file nodes-node-6.conf --cluster-node-timeout 10000 --appendonly yes --port 6376
#创建redis容器参数解释:
# --net=host 容器和宿主机共用网络 不需要再做端口映射
# -v 创建容器数据卷
# --cluster-enabled:是否启动集群,选值:yes 、no
# --cluster-config-file 配置文件.conf :指定节点信息,自动生成
# --cluster-node-timeout 毫秒值: 配置节点连接超时时间
# --appendonly 是否开启持久化,选值:yes、no
# --port 端口
- 启动容器
# 在这里直接启动会报错
# Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "process_linux.go:449: container init caused \"write /proc/self/attr/keycreate: permission denied\"": unknown
# Error: failed to start containers: redis-node
# 这里是由于linux的策略原因:“/proc/self/attr/keycreate” 这里没有写入权限,需要把“/etc/selinux/config”里面的SELINUX值修改为disabled
# 修改以后要重启linux虚拟机,才能生效
# reboot。# 重启完执行容器启动命令
docker start redis-node1 redis-node2 redis-node3 redis-node4 redis-node5 redis-node6
- 组件redis集群
#进入任意一个创建的redis容器,以redis-node1为例
docker exec -it redis-node1 /bin/bash
#执行组件集群的命令,localhos替换成实际的主机ip
redis-cli --cluster create localhos:6371 localhos:6372 localhos:6373 localhos:6374 localhos:6375 localhos:6376 --cluster-replicas 1
#参数解释
# --cluster-replicas 1: 参数后面的数字表示的是主从比例,这里的1,表示1个主节点对应1个从节点。上面创建了6个reids容器,所以主从分配就是3个主节点,3个从节点。
# 注意 主节点最少3个,3个才能保证集群的健壮性。
#组建成功,进入redis查看一下集群节点信息:
redis-cli -c -p 6371
cluster nodes
# -c 代表集群模式
# -p 代表进入6371端口
- 开放端口
#批量添加开放端口
firewall-cmd --permanent --add-port=6371-6376/tcp
#重启
firewall-cmd --reload
- Redis Cluster主从模式
redis cluster 为了保证数据的高可用性,加入了主从模式,一个主节点对应一个或多个从节点,主节点提供数据存取,从节点则是从主节点拉取数据备份,当这个主节点挂掉后,就会有这个从节点选取一个来充当主节点,从而保证集群不会挂掉。
至此redis集群搭建完毕。
当然在redis集群不够用的情况下还能进行扩容。
添加主节点或者从节点:
- 向redis集群主节点添加从节点
当创建了3个主节点,3个从节点以后。redis集群不够用的情况下,主节点可以再次添加从节点,进行扩容。
#执行创建Redis容器命令
docker create --name redis-node7 --net=host -v /data/redis-data/node7:/data redis --cluster-enabled yes --cluster-config-file nodes-node-7.conf --cluster-node-timeout 10000 --appendonly yes --port 6377
#启动
docker start redis-node7
#进入redis容器
docker exec -it redis-node1 /bin/bash
redis-cli -c -p 6371
cluster nodes
# 获取到6371的容器id
#执行添加从节点 组建集群的命令 localhos替换成实际主机ip
redis-cli --cluster add-node localhos:6377 localhos:6371 --cluster-slave --cluster-master-id b0c32b1dae9e7b7f7f4b74354c59bdfcaa46f30a
#注意语法,一个新节点IP:端口 空格 一个旧节点IP:端口,注意点是:
#1.不能多个新节点一次性添加
#2.新节点后是旧节点
#3.如果设置--cluster-slave,新节点挂在旧节点下的一个从节点
#4.如果设置 --cluster-master-id <arg> ,arg设置旧节点的id,具体可以使用cluster nodes查看各个节点的id
#--cluster-master-id 键入的是上图localhos:6371的容器id
- 向redis集群添加主节点
#执行创建Redis容器命令
docker create --name redis-node8 --net=host -v /data/redis-data/node8:/data redis --cluster-enabled yes --cluster-config-file nodes-node-8.conf --cluster-node-timeout 10000 --appendonly yes --port 6378
#启动
docker start redis-node8
#进入redis容器
docker exec -it redis-node8 /bin/bash
#执行添加节点命令
redis-cli --cluster add-node localhos:6378 localhos:6371
#查看集群信息
redis-cli -c -p 6378
# 查看其它master的id
cluster nodes
exit
#上面只是把6381节点加入了集群中,但是并没有分配slot,所以这个节点并没有真正的开始分担集群工作,下面开始reshard分配空间
redis-cli --cluster reshard localhos:6378--cluster-from 9404359dd760507e86e1a267c0e29d438ee7349a,6c61074bc2c110d718cbc178cfb33505128fb6e8,564b5d2a8157cf6951a6dd8059407eae484b5803 --cluster-to 048bb5b664e32ffbc3a0540820e27802b8c14cfb --cluster-slots 1024
#参数解释
#--cluster-from:表示slot目前所在的节点的主节点ID,多个ID用逗号分隔
#--cluster-to:表示需要新分配节点的节点ID(6381的id)
#--cluster-slots:分配的slot数量
#根据提示键入yes 向集群添加主节点完成
#说明
#Redis 集群没有并使用传统的一致性哈希来分配数据,而是采用另外一种叫做哈希槽 (hash slot)的方式来分配的。redis cluster 默认分配了 16384 个slot,当我们set一个key 时,会用CRC16算法来取模得到所属的slot,然后将这个key 分到哈希槽区间的节点上,具体算法就是:CRC16(key) % 16384
- 开放端口
#批量添加开放端口
firewall-cmd --permanent --add-port=6377-6378/tcp
#重启
firewall-cmd --reload
- 测试集群数据
#随意进入一个已启动的redis
docker exec -it redis-node1 /bin/bash
#集群模式
redis-cli -c -p 6371
set test testData
#查看test的值
get test
#随意进入另一个已启动的redis
docker exec -it redis-node6 /bin/bash
#集群模式
redis-cli -c -p 6376
#查看test的值
get test
#可以获取到test的值,并且说明了数据的信息来源
- 主节点挂掉
当一个主节点和下面子节点全部挂掉,少于3个主节点时,redis集群将不可用。当再次启动至三个可用主节点时,之前挂掉的主节点不一定就还是主节点