本文讲述docker中安装redis和redis集群的配置和使用
以Redis 6.0.8为例:
docker pull redis:6.0.8
一、单机版安装
简单版本Redis
docker run -p 6379:6379 -d redis:6.0.8
简单版本没有容器卷映射,当容器被删除时数据无法恢复。
实际应用版Redis
配置文件和数据文件都和容器卷进行映射
步骤:
- 宿主机创建目录/app/redis
- 在/app/redis下创建文件redis.conf,主要修改以下几项配置
# 开启密码验证(可选)
requirepass 123
# 允许redis外地连接,需要注释掉绑定的IP
# bind 127.0.0.1
# 关闭保护模式(可选)
protected-mode no
# 注释掉daemonize yes,或者配置成 daemonize no。因为该配置和 docker run中的 -d 参数冲突,会导致容器一直启动失败
daemonize no
# 开启redis数据持久化, (可选)
appendonly yes
- 启动docker容器:(因为要使用自定义的配置文件,所以需要指定容器运行的命令为redis-server 容器内配置文件路径)
docker run -d -p 6379:6379 --name redis --privileged=true \
-v /home/mrluo/Desktop/app/redis/redis.conf:/etc/redis/redis.conf \
-v /home/mrluo/Desktop/app/redis/data:/data \
redis:6.0.8 \
redis-server /etc/redis/redis.conf
接下来可以看看redis集群储存算法:https://www.yuque.com/tmfl/cloud/ixlgsl
二、搭建3主3从Redis集群
1、启动6台redis容器
# 启动第1台节点
# --net host 使用宿主机的IP和端口,默认
# --cluster-enabled yes 开启redis集群
# --appendonly yes 开启redis持久化
# --port 6381 配置redis端口号
docker run -d --name redis-node-1 --net host --privileged=true -v /home/mrluo/Desktop/app/redis-cluster/share/redis-node-1:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6381
docker run -d --name redis-node-2 --net host --privileged=true -v /home/mrluo/Desktop/app/redis-cluster/share/redis-node-2:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6382
docker run -d --name redis-node-3 --net host --privileged=true -v /home/mrluo/Desktop/app/redis-cluster/share/redis-node-3:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6383
docker run -d --name redis-node-4 --net host --privileged=true -v /home/mrluo/Desktop/app/redis-cluster/share/redis-node-4:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6384
docker run -d --name redis-node-5 --net host --privileged=true -v /home/mrluo/Desktop/app/redis-cluster/share/redis-node-5:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6385
docker run -d --name redis-node-6 --net host --privileged=true -v /home/mrluo/Desktop/app/redis-cluster/share/redis-node-6:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6386
用docker ps命令可以查看是否启动成功
[mrluo@localhost share]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1f118819c944 redis:6.0.8 "docker-entrypoint.s…" 4 seconds ago Up 3 seconds redis-node-6
e3ca874eae39 redis:6.0.8 "docker-entrypoint.s…" 30 seconds ago Up 29 seconds redis-node-5
c1d7bdb2c8e1 redis:6.0.8 "docker-entrypoint.s…" 42 seconds ago Up 41 seconds redis-node-4
9c7c1860f53e redis:6.0.8 "docker-entrypoint.s…" 53 seconds ago Up 52 seconds redis-node-3
c9442c359007 redis:6.0.8 "docker-entrypoint.s…" About a minute ago Up About a minute redis-node-2
d5f0ef6ade0a redis:6.0.8 "docker-entrypoint.s…" 3 minutes ago Up 3 minutes redis-node-1
2、构建主从关系
1、进入任意一个节点,
docker exec -it redis-node-1 /bin/bash
2、构建主从关系
redis-cli --cluster create 192.168.23.181:6381 192.168.23.181:6382 192.168.23.181:6383 192.168.23.181:6384 192.168.23.181:6385 192.168.23.181:6386 --cluster-replicas 1
- 192.168.23.181为宿主机的ip,根据实际情况来
- –cluster-replicas 1 表示每个主节点都有一个从节点。这意味着,如果主节点出现故障,则可以从从节点中选举出一个新的主节点。
–cluster-replicas 的默认值是 1,但您可以根据需要调整该值。如果您需要更高的可用性,可以将该值设置为更高的数字。
以下是 --cluster-replicas 的其他一些用法:
- –cluster-replicas 0 表示每个主节点都没有从节点。这意味着,如果主节点出现故障,则无法从从节点中选举出新的主节点。
- –cluster-replicas 2 表示每个主节点都有两个从节点。这意味着,如果主节点出现故障,则可以从两个从节点中选举出新的主节点。
3、redis自动分配主从节点
4、下面可以看到redis自动分配的结果,输入yes确认
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.23.181:6385 to 192.168.23.181:6381
Adding replica 192.168.23.181:6386 to 192.168.23.181:6382
Adding replica 192.168.23.181:6384 to 192.168.23.181:6383
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: 469916c48fae044dd82645e0c5776c5ce9b37d16 192.168.23.181:6381
slots:[0-5460] (5461 slots) master
M: 31c39b2e9f6ef14e6a8977872d0b6ee4dcd131c6 192.168.23.181:6382
slots:[5461-10922] (5462 slots) master
M: ea43d4d0f9664b72f45893bcd1f202b6b6045ab5 192.168.23.181:6383
slots:[10923-16383] (5461 slots) master
S: af168b3a9c235e2b8fe703052da0bdabf216adc0 192.168.23.181:6384
replicates 31c39b2e9f6ef14e6a8977872d0b6ee4dcd131c6
S: c76ad0a77f5d515a0a86c11a714cea13ba7a8ee6 192.168.23.181:6385
replicates ea43d4d0f9664b72f45893bcd1f202b6b6045ab5
S: 4ec398d19f1d57788be11125d7d181f29ef55af2 192.168.23.181:6386
replicates 469916c48fae044dd82645e0c5776c5ce9b37d16
Can I set the above configuration? (type 'yes' to accept): yes
5、输入Yes确认后,redis会向其他节点发送信息加入集群,并分配哈希槽
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.
>>> Performing Cluster Check (using node 192.168.23.181:6381)
M: 469916c48fae044dd82645e0c5776c5ce9b37d16 192.168.23.181:6381
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: af168b3a9c235e2b8fe703052da0bdabf216adc0 192.168.23.181:6384
slots: (0 slots) slave
replicates 31c39b2e9f6ef14e6a8977872d0b6ee4dcd131c6
S: 4ec398d19f1d57788be11125d7d181f29ef55af2 192.168.23.181:6386
slots: (0 slots) slave
replicates 469916c48fae044dd82645e0c5776c5ce9b37d16
M: ea43d4d0f9664b72f45893bcd1f202b6b6045ab5 192.168.23.181:6383
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
M: 31c39b2e9f6ef14e6a8977872d0b6ee4dcd131c6 192.168.23.181:6382
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: c76ad0a77f5d515a0a86c11a714cea13ba7a8ee6 192.168.23.181:6385
slots: (0 slots) slave
replicates ea43d4d0f9664b72f45893bcd1f202b6b6045ab5
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
从结果可以看出 端口6381、6383、6382为主节点master,端口6384、6386、6385为从节点slave,且6381对应6386、6383对应6385、6382对应6384(每个人情况不一样)
槽点:redis集群一共有16384个槽位,均匀分配在三个主节点中,存储数据根据不同的槽点插入到对应的redis节点中
3、查看集群状态
1、 进入容器节点1(或集群中其他节点)
docker exec -it redis-node-1 /bin/bash
2、 使用redis-cli连接到6381节点:
redis-cli -p 6381
3、使用redis的相关命令查看集群状态:
cluster info
其中,分配的哈希槽数量 cluster_slots_assigned为16384,集群节点数量cluster_known_nodes为6
4、 查看集群节点信息
cluster nodes
接下来,进入任一节点,使用redis-cli连接,不加-c参数时
docker exec -it redis-node-1 /bin/bash
redis-cli -p 6381
5、插入数据可能会出错
127.0.0.1:6381> set k1 v1
(error) MOVED 12706 192.168.23.183:6383
127.0.0.1:6381> set k2 v2
OK
127.0.0.1:6381>
原因是经过哈希计算,k1的哈希槽和节点的哈希槽区间不匹配,所以存不进去
解决方法:使用 -c参数的redis-cli命令连接即可
redis-cli -p 6381 -c
root@localhost:/data# redis-cli -p 6381 -c
127.0.0.1:6381> set k1 v1
-> Redirected to slot [12706] located at 192.168.23.183:6383
OK
加入-c后添加的数据如果不在当前槽位上会重定向到指定的位置
三、集群信息检查
1、进入容器节点1
docker exec -it redis-node-1 /bin/bash
2、进入集群信息检查
# 输入任意一台主节点地址都可以进行集群检查
redis-cli --cluster check 192.168.xxx.xxx:6381
四、主从扩容
可能会因为业务需求,需要从之前的3主3从再添加一个主节点和一个从节点
1、再重新添加2台新的节点
docker run -d --name redis-node-7 --net host --privileged=true -v /home/mrluo/Desktop/app/redis-cluster/share/redis-node-7:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6387
docker run -d --name redis-node-8 --net host --privileged=true -v /home/mrluo/Desktop/app/redis-cluster/share/redis-node-8:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6388
2、进入6387(节点7)容器内部
docker exec -it redis-node-7 /bin/bash
3、将6387作为master加入集群
# redis-cli --cluster add-node 本节点地址 要加入的集群中的其中一个节点地址
redis-cli --cluster add-node 192.168.23.183:6387 192.168.23.183:6381
一片ok,前程大好
4、检查当前集群节点状态
redis-cli --cluster check 192.168.23.183:6381
可以发现,6371节点已经作为master加入了集群,但是该节点没有被分配槽位。
5. 重新分配集群的槽位
redis-cli --cluster reshard 192.168.23.183:6381
弹出提示,意思是你要移动多少个槽位
因为redis集群最多是16384个槽位,之前被随机均等的分成了三分,现在我们均等的分成4份,16384除以4等于4096,所以这里我们输入4096
接着弹出提示`
What is the receiving node ID? cd7e720e41c7cb5a8a3bc2eff9520c93c3be2c65
意思是你用哪个节点去节点去接收这些数据,这里我们选择新创建的节点7,需要填入id,上图可以看到
然后会提示,询问要从哪些节点中拨出一部分槽位凑足4096个分给Node7。一般选择 all,即将之前的3个主节点的槽位都均一些给Node7,这样可以使得每个节点的槽位数相等均衡。
Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
Source node #1: all
输入all之后,redis会列出一个计划,内容是自动从前面的3台master中拨出一部分槽位分给Node7的槽位,需要确认一下分配的计划。
输入yes确认后,redis便会自动重新洗牌,给Node7分配槽位。
6、再次查看节点状态,发现节点7已经分配好了槽位
redis-cli --cluster check 192.168.23.183:6381
7、为主节点6387分配从节点6388
redis-cli --cluster add-node 192.168.23.183:6388 192.168.23.183:6381 --cluster-slave --cluster-master-id node7节点的十六进制编号字符串
查询当前集群状态
redis-cli --cluster check 192.168.23.183:6381
五、主从缩容
假如业务高峰期过去,需要将4主4从重新缩容到3主3从。即从集群中移除node8和node7.
首先删除从节点6388:
1、进入容器节点1
docker exec -it redis-node-1 /bin/bash
2、 检查容器状态,获取6388的节点编号
redis-cli --cluster check 192.168.23.183:6381
3、将6388从集群中移除
redis-cli --cluster del-node 192.168.23.183:6388 6388节点编号
对node7重新分配哈希槽:
1、对集群重新分配哈希槽
redis-cli --cluster reshard 192.168.23.183:6381
2、 redis经过槽位检查后,会提示需要分配的槽位数量
How many slots do you want to move (from 1 to 16384)?
这里我们需要将节点7的槽位分配出去,可以均等的分配,也可以直接落在某一个节点上,这里为了省事,我直接将节点7的所有槽点分配到节点1上,所以输入4096
然后跟上面扩容一样
What is the receiving node ID?
表示用哪个节点接收,这里我们用1号节点,
接着是询问这些槽位从哪儿来
Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
Source node #1: cd7e720e41c7cb5a8a3bc2eff9520c93c3be2c65
Source node #2: done
在扩容中我们使用all,表示从其他所有主节点中拿出一部分,这里是直接用7号节点,然后输入done
node7上面没有了哈希槽,此时便可以将node7从集群中移除。(如果node7上面有哈希槽,直接从集群中移除会报错)
redis-cli --cluster del-node 192.168.23.183:6387 node7节点编号
结束