哨兵模式的缺陷
在哨兵模式中,仍然只有一个master节点。当并发写请求较大时,哨兵模式并不能缓解写压力。
Redis-Cluster集群概述
- Redis集群是一个由多个主从节点群组成的分布式服务器群。
- 集群中有多个master主节点,每个主节点都可读可写。
- 节点之间会互相通信,两两相连。
- Redis集群无中心节点,可水平扩展【官方推荐不超过1000个节点】。
集群节点复制
在redis-cluster集群中,每一个主节点可以添加多个从节点,主节点和从节点遵循主从模式的特性。
当用户需要处理更多的读请求时,添加从节点可以扩展系统的读性能。
故障转移
redis集群的主节点内置了类似Sentinel的节点故障检测和自动故障转移功能。当集群中的某个主节点下线时,集群中的其他在线主节点发现了以后,会对已下线的主节点进行故障转移。集群进行故障转移的方法和Sentient进行故障转移的方法基本一致,不同的是,在集群里面,故障转移是由集群中其他在线的主节点负责进行的,所以集群中不需要使用Sentinel。
键分布模型
redis-cluster集群将键存储空间分割为16384个槽位(slot),事实上集群最大节点数量是16384个【官方建议最大节点数量不超过1000个节点】。
所有主节点都负责16384个哈希槽中的一部分,当16384个槽都有某个节点在负责处理时,集群进入上线状态,并开始处理客户端发送的数据命令请求。
一个slot槽位可以存放多个数据,key的槽位计算公式:HASH_SLOT = CRC16(key) mod 16384
集群redirect转向
由于Redis集群无中心节点,请求会随机发给任意主节点。
主节点只会处理自己负责槽位的命令请求,其他槽位的命令请求,该主节点会返回客户端一个转向错误。
客户端根据错误中包含的地址和端口重新向正确的负责的主节点发起命令请求。
集群搭建
前期准备
系统:CentOS7
Redis: 5.0.9
Redis节点
192.168.164.10:7000 192.168.164.10:7001
192.168.164.11:7000 192.168.164.11:7001
192.168.164.12:7000 192.168.164.12:7001
192.168.164.13:7000 192.168.164.13:7001【扩容测试使用】
注意:
- 一个Redis集群至少包括三主三从,奇数是为了选举。
- firewalld不关闭的话,需要开启Redis Cluster端口=Redis端口+10000,集群管理端口总是redis端口+10000,以上节点集群管理端口号就是17000和170001。
- 每一台服务器都需要安装redis
修改redis.conf配置,创建多个 redis节点
- 在
/usr/local/bin/
下创建cluster目录,其下创建7000、7001目录
cd /usr/local/bin/
mkdir cluster # 用于存放 redis.conf .rdb .aof nodes-xxxx.conf
cd cluster
mkdir 7000 #端口为 7000的配置文件目录 后续还会有 7001等
cp redis.conf 7000 #伪命令 将 redis根目录下的配置文件 拷贝一份到 新建的 7000目录下
vim ./7000/redis.conf #开始修改配置文件
配置文件主要修改:
bind 192.168.164.10 # 修改局域网中的ip地址,其他节点可通过局域网ip访问
port 7000 # 端口
daemonize yes # redis后台运行
pidfile /var/run/redis_7000.pid # 需要修改为 redis_{port}.pid 的形式
dir ./cluster/7000 # nodes.conf【nodes-{port}.conf】文件保存路径
appendonly yes # 开启AOF日志
cluster-enabled yes # 开启集群
cluster-config-file nodes-7000.conf #集群的配置文件 nodes_{port}.conf的形式
appendfsync always # aof每次修改都会同步 sync
logfile "/var/log/redis/7000/redis.log" # log日志保存位置
其他配置文件类似,把端口或ip修改一下就行
各服务器启动redis
redis-server ./cluster/7000/redis.config
redis-server ./cluster/7001/redis.config
创建集群,任意一台节点都行
redis-cli --cluster create 192.168.164.10:7000 192.168.164.10:7001 192.168.164.11:7000 192.168.164.11:7001 192.168.164.12:7000 192.168.164.12:7001 --cluster-replicas 1
执行结果
[root@localhost bin]# redis-cli --cluster create 192.168.164.10:7000 192.168.164.10:7001 192.168.164.11:7000 192.168.164.11:7001 192.168.164.12:7000 192.168.164.12:7001 --cluster-replicas 1
>>> 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.164.11:7001 to 192.168.164.10:7000
Adding replica 192.168.164.12:7001 to 192.168.164.11:7000
Adding replica 192.168.164.10:7001 to 192.168.164.12:7000
M: 08f43507a8035d575c7ee6b9fcefb782121c4ec5 192.168.164.10:7000
slots:[0-5460] (5461 slots) master
S: 3e38b4022016102d2095bc17469b8e293cdb0e3f 192.168.164.10:7001
replicates 32dc041d1966ce2796fca07c6c6cd9646d92448f
M: 7138044b0d6942f7929abcc95b04d10f12703636 192.168.164.11:7000
slots:[5461-10922] (5462 slots) master
S: 8c0afd052e18dc2efa395aad5b94c26878df693f 192.168.164.11:7001
replicates 08f43507a8035d575c7ee6b9fcefb782121c4ec5
M: 32dc041d1966ce2796fca07c6c6cd9646d92448f 192.168.164.12:7000
slots:[10923-16383] (5461 slots) master
S: 718984c94156f57f86e9f36e51186ff577219899 192.168.164.12:7001
replicates 7138044b0d6942f7929abcc95b04d10f12703636
Can I set the above configuration? (type 'yes' to accept): yes
>>> 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.164.10:7000)
M: 08f43507a8035d575c7ee6b9fcefb782121c4ec5 192.168.164.10:7000
slots:[0-5460] (5461 slots) master
1 additional replica(s)
M: 32dc041d1966ce2796fca07c6c6cd9646d92448f 192.168.164.12:7000
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 3e38b4022016102d2095bc17469b8e293cdb0e3f 192.168.164.10:7001
slots: (0 slots) slave
replicates 32dc041d1966ce2796fca07c6c6cd9646d92448f
S: 718984c94156f57f86e9f36e51186ff577219899 192.168.164.12:7001
slots: (0 slots) slave
replicates 7138044b0d6942f7929abcc95b04d10f12703636
S: 8c0afd052e18dc2efa395aad5b94c26878df693f 192.168.164.11:7001
slots: (0 slots) slave
replicates 08f43507a8035d575c7ee6b9fcefb782121c4ec5
M: 7138044b0d6942f7929abcc95b04d10f12703636 192.168.164.11:7000
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
[root@localhost bin]# redis-cli --check 192.168.164.12:7000
Unrecognized option or bad number of args for: '--check'
[root@localhost bin]# redis-cli --cluster check 192.168.164.12:7000
192.168.164.12:7000 (32dc041d...) -> 0 keys | 5461 slots | 1 slaves.
192.168.164.10:7000 (08f43507...) -> 0 keys | 5461 slots | 1 slaves.
192.168.164.11:7000 (7138044b...) -> 0 keys | 5462 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 192.168.164.12:7000)
M: 32dc041d1966ce2796fca07c6c6cd9646d92448f 192.168.164.12:7000
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
M: 08f43507a8035d575c7ee6b9fcefb782121c4ec5 192.168.164.10:7000
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: 3e38b4022016102d2095bc17469b8e293cdb0e3f 192.168.164.10:7001
slots: (0 slots) slave
replicates 32dc041d1966ce2796fca07c6c6cd9646d92448f
S: 8c0afd052e18dc2efa395aad5b94c26878df693f 192.168.164.11:7001
slots: (0 slots) slave
replicates 08f43507a8035d575c7ee6b9fcefb782121c4ec5
M: 7138044b0d6942f7929abcc95b04d10f12703636 192.168.164.11:7000
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: 718984c94156f57f86e9f36e51186ff577219899 192.168.164.12:7001
slots: (0 slots) slave
replicates 7138044b0d6942f7929abcc95b04d10f12703636
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
创建命令中--cluster-replicas 1表示每个主节点对应一个从节点
查询集群
[root@localhost bin]# redis-cli --cluster check 192.168.164.12:7000 # 任意节点
192.168.164.12:7000 (32dc041d...) -> 0 keys | 5461 slots | 1 slaves.
192.168.164.10:7000 (08f43507...) -> 0 keys | 5461 slots | 1 slaves.
192.168.164.11:7000 (7138044b...) -> 0 keys | 5462 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 192.168.164.12:7000)
M: 32dc041d1966ce2796fca07c6c6cd9646d92448f 192.168.164.12:7000
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
M: 08f43507a8035d575c7ee6b9fcefb782121c4ec5 192.168.164.10:7000
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: 3e38b4022016102d2095bc17469b8e293cdb0e3f 192.168.164.10:7001
slots: (0 slots) slave
replicates 32dc041d1966ce2796fca07c6c6cd9646d92448f
S: 8c0afd052e18dc2efa395aad5b94c26878df693f 192.168.164.11:7001
slots: (0 slots) slave
replicates 08f43507a8035d575c7ee6b9fcefb782121c4ec5
M: 7138044b0d6942f7929abcc95b04d10f12703636 192.168.164.11:7000
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: 718984c94156f57f86e9f36e51186ff577219899 192.168.164.12:7001
slots: (0 slots) slave
replicates 7138044b0d6942f7929abcc95b04d10f12703636
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
新增节点
按照之前的配置修改并启动,使用以下命令将其加入集群:
# redis-cli --cluster add-node {新节点IP}:{新节点端口} {任意集群节点IP}:{对应端口} #添加为主节点
redis-cli --cluster add-node 192.168.164.13:7000 192.168.164.11:7000
# redis-cli --cluster add-node {新节点IP}:{新节点端口} {任意集群节点IP}:{对应端口} --cluster-slave --cluster-master-id {对应的主节点ID} # 在上一条命令后面加上此行命令将新节点添加为 对应主节点的从节点
redis-cli --cluster add-node 192.168.164.13:7001 192.168.164.13:7000 --cluster-slave --cluster-master-id cb21c351b3d2378976bf7d215553d0e04d7fad43
hash槽重新分配
添加完新节点后,需要对新添加的主节点进行hash槽重新分配,这样该主节点才能存储数据,redis共有16384个槽。
- 自动平衡集群中的各节点哈希槽数
redis-cli --cluster rebalance --cluster-use-empty-masters 192.168.164.10:7000
删除节点
# 查看目前集群的信息
192.168.164.10:7000> cluster nodes
32dc041d1966ce2796fca07c6c6cd9646d92448f 192.168.164.12:7000@17000 master - 0 1616749551343 11 connected 8192-12287
3e38b4022016102d2095bc17469b8e293cdb0e3f 192.168.164.10:7001@17001 slave 08f43507a8035d575c7ee6b9fcefb782121c4ec5 0 1616749549000 9 connected
718984c94156f57f86e9f36e51186ff577219899 192.168.164.12:7001@17001 slave 7138044b0d6942f7929abcc95b04d10f12703636 0 1616749545791 10 connected
8c0afd052e18dc2efa395aad5b94c26878df693f 192.168.164.11:7001@17001 slave 32dc041d1966ce2796fca07c6c6cd9646d92448f 0 1616749550336 11 connected
08f43507a8035d575c7ee6b9fcefb782121c4ec5 192.168.164.10:7000@17000 myself,master - 0 1616749545000 9 connected 0-4095
7138044b0d6942f7929abcc95b04d10f12703636 192.168.164.11:7000@17000 master - 0 1616749551000 10 connected 4096-8191
b676413cd95149dfcad6b29ed47a06513f534118 192.168.164.13:7001@17001 master - 0 1616749548317 12 connected 12288-16383
cb21c351b3d2378976bf7d215553d0e04d7fad43 192.168.164.13:7000@17000 slave b676413cd95149dfcad6b29ed47a06513f534118 0 1616749549000 12 connected
删除从节点192.168.164.13:7000,node_id:cb21c351b3d2378976bf7d215553d0e04d7fad43
redis-cli --cluster del-node 192.168.164.10:7000 cb21c351b3d2378976bf7d215553d0e04d7fad43
执行结果
[root@localhost bin]# redis-cli --cluster del-node 192.168.164.10:7000 cb21c351b3d2378976bf7d215553d0e04d7fad43
>>> Removing node cb21c351b3d2378976bf7d215553d0e04d7fad43 from cluster 192.168.164.10:7000
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.
存在slot的主节点无法直接删除,所以我们需要先移动主节点192.168.164.13:7001的slot至其他三个主节点
redis-cli --cluster reshard 192.168.164.12:7000 --cluster-from b676413cd95149dfcad6b29ed47a06513f534118 --cluster-to 08f43507a8035d575c7ee6b9fcefb782121c4ec5 --cluster-slots 1365 --cluster-yes
redis-cli --cluster reshard 192.168.164.12:7000 --cluster-from b676413cd95149dfcad6b29ed47a06513f534118 --cluster-to 7138044b0d6942f7929abcc95b04d10f12703636 --cluster-slots 1365 --cluster-yes
redis-cli --cluster reshard 192.168.164.12:7000 --cluster-from b676413cd95149dfcad6b29ed47a06513f534118 --cluster-to 32dc041d1966ce2796fca07c6c6cd9646d92448f --cluster-slots 1366 --cluster-yes
查看集群节点信息
192.168.164.11:7001> cluster nodes
08f43507a8035d575c7ee6b9fcefb782121c4ec5 192.168.164.10:7000@17000 master - 0 1617090678564 13 connected 0-4095 12288-13652
718984c94156f57f86e9f36e51186ff577219899 192.168.164.12:7001@17001 slave 7138044b0d6942f7929abcc95b04d10f12703636 0 1617090679574 14 connected
7138044b0d6942f7929abcc95b04d10f12703636 192.168.164.11:7000@17000 master - 0 1617090678000 14 connected 4096-8191 13653-15017
b676413cd95149dfcad6b29ed47a06513f534118 192.168.164.13:7001@17001 master - 0 1617090678000 12 connected # 192.168.164.13:7001上已经没有slot
8c0afd052e18dc2efa395aad5b94c26878df693f 192.168.164.11:7001@17001 myself,slave 32dc041d1966ce2796fca07c6c6cd9646d92448f 0 1617090679000 4 connected
32dc041d1966ce2796fca07c6c6cd9646d92448f 192.168.164.12:7000@17000 master - 0 1617090680584 15 connected 8192-12287 15018-16383
3e38b4022016102d2095bc17469b8e293cdb0e3f 192.168.164.10:7001@17001 slave 08f43507a8035d575c7ee6b9fcefb782121c4ec5 0 1617090681591 13 connected
删除主节点
redis-cli --cluster del-node 192.168.164.11:7000 b676413cd95149dfcad6b29ed47a06513f534118
执行结果
[root@localhost bin]# redis-cli --cluster del-node 192.168.164.11:7000 b676413cd95149dfcad6b29ed47a06513f534118
>>> Removing node b676413cd95149dfcad6b29ed47a06513f534118 from cluster 192.168.164.11:7000
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.
查看集群信息
192.168.164.11:7001> cluster nodes
08f43507a8035d575c7ee6b9fcefb782121c4ec5 192.168.164.10:7000@17000 master - 0 1617091111000 13 connected 0-4095 12288-13652
718984c94156f57f86e9f36e51186ff577219899 192.168.164.12:7001@17001 slave 7138044b0d6942f7929abcc95b04d10f12703636 0 1617091112693 14 connected
7138044b0d6942f7929abcc95b04d10f12703636 192.168.164.11:7000@17000 master - 0 1617091111000 14 connected 4096-8191 13653-15017
8c0afd052e18dc2efa395aad5b94c26878df693f 192.168.164.11:7001@17001 myself,slave 32dc041d1966ce2796fca07c6c6cd9646d92448f 0 1617091110000 4 connected
32dc041d1966ce2796fca07c6c6cd9646d92448f 192.168.164.12:7000@17000 master - 0 1617091112000 15 connected 8192-12287 15018-16383
3e38b4022016102d2095bc17469b8e293cdb0e3f 192.168.164.10:7001@17001 slave 08f43507a8035d575c7ee6b9fcefb782121c4ec5 0 1617091110677 13 connected