Redis集群官方推荐方案 Redis-Cluster
集群 redis cluster
通过分片实࣫容量扩展
通过主从复制实࣫节点的高可用
节点之间互相通信
每个节点都维护整个集群的节点信息
redis-cluster把所有的物理节点映射到[0-16383]slotЇ,cluster 负责维护node<->slot<->key
Redis-Cluster的优势
1、官方推荐,毋庸置疑。
2、去中心化,集群最大可增加1000个节点,性能随节点增加而线性扩展。
3、管理方便,后续可自行增加或摘除节点,移动分槽等等。
4、简单,易上手
redis-cluster名词介绍
1、master 主节点
2、slave 从节点
3、slot 槽,一共有16384数据分槽,分布在集群的所有主节点中
集群内部划分为16384个数据分槽,分布在三个主redis中
一致性hash
普通hash的缺点
– 当hash节点数量发生变化时,大部分的数据的hash值都会发生变化,这将导致数据的缓存命中率下降很多
– 随着业务的发展,换从容量会受限,进行扩容又是必然的需求
一致性hash
– Key空间比较大,为0~~(2^32)-1个,形成一个࣪
– 把机器也通过hash算法映射到此环上
– 把数据的key也映射到此环上,以相同的hash算法
– 按照顺时针的方向,把数据存储在最近的节点上
– 优点:
• 当新加入某个机器时,只会影响落入此节点左边和前一个节点之间的数据
• 当删除某个机器时,也只会影响这个节点左边和前一个节点之间的数据
– 缺点:
• 数据分布不够均匀,新加入的节点的数据较少,也不能能把旧节点的数据进行迁移
如何解决数据分布不均匀—平衡性
– 思路:足够多的机器节点-----构建虚拟节点,然后做虚拟节点与物理节点的映射
– 虚拟节点ࡁ物理节点多,分布较均匀
常用命令
cluster nodes 查看集群所有节点
cluster info 查看集群状态信息
cluster slots 查看集群槽位的分配信息
CLUSTER KEYSLOT key 返回某个key对应的槽位的槽位
CLUSTER DELSLOTS slot [slot ...] 删除当前节点的槽位
1 准备节点
ip:port
127.0.0.1 6379 127.0.0.1 6382
127.0.0.1 6383 127.0.0.1 6384
127.0.0.1 6385 127.0.0.1 6386
修改配置文件 /etc/redis/6379.conf
pidfile "/var/run/redis_6379.pid"
port 6379 //端口
logfile "/etc/redis/6379.log"
dbfilename "dump-6382.rdb"
cluster-enabled yes //开启集群模式
cluster-config-file nodes-6379.conf //集群内部的配置文件
cluster-node-timeout 15000 //节点超时时间,单位毫秒
// 其他配置和单机模式相同
#/usr/local/redis/src/redis-server /etc/redis/6379.conf
/usr/local/redis/src/redis-server /etc/redis/6382.conf
/usr/local/redis/src/redis-server /etc/redis/6383.conf
/usr/local/redis/src/redis-server /etc/redis/6384.conf
/usr/local/redis/src/redis-server /etc/redis/6385.conf
/usr/local/redis/src/redis-server /etc/redis/6386.conf
/usr/local/redis/src/redis-server /etc/redis/6387.conf
[root@hongquan1 redis]# /usr/local/redis/src/redis-server /etc/redis/6379.conf
*** FATAL CONFIG FILE ERROR ***
Reading the configuration file, at line 945
>>> 'slaveof 127.0.0.1 6380'
slaveof directive not allowed in cluster mode
[root@hongquan1 redis]# ps -ef|grep redis
root 30167 1 0 08:10 ? 00:00:00 /usr/local/redis/src/redis-server *:6387 [cluster]
root 30762 1 0 08:14 ? 00:00:00 /usr/local/redis/src/redis-server *:6382 [cluster]
root 30781 1 0 08:14 ? 00:00:00 /usr/local/redis/src/redis-server *:6383 [cluster]
root 30783 1 0 08:14 ? 00:00:00 /usr/local/redis/src/redis-server *:6384 [cluster]
root 30785 1 0 08:14 ? 00:00:00 /usr/local/redis/src/redis-server *:6385 [cluster]
root 30793 1 0 08:14 ? 00:00:00 /usr/local/redis/src/redis-server *:6386 [cluster]
root 30840 3385 0 08:14 pts/1 00:00:00 grep redis
/usr/local/redis/src/redis-cli -h 127.0.0.1 -p 6387
cluster-config-file nodes-6387.conf
集群配置文件的作用:当集群内节点发生信息变化时,如添加节点、节点下线、故障转移等。节点会自动保存集群的状态到配置文件中。该配置文件由Redis自行维护,不要手动修改,防止节点重启时产生集群信息错乱。
[root@hongquan1 redis]# tail -n 20 nodes-6387.conf
aa95cc1e617a173aba2a1839a9fcf03f1fa06a94 :0 myself,master - 0 0 0 connected
vars currentEpoch 0 lastVoteEpoch 0
127.0.0.1:6387> cluster nodes
aa95cc1e617a173aba2a1839a9fcf03f1fa06a94 :6387 myself,master - 0 0 0 connected
2 节点握手
节点握手是指一批运行在集群模式的节点通过Gossip协议彼此通信,达到感知对方的过程。节点握手是集群彼此通信的第一步,由客户端发起命令:cluster meet
127.0.0.1:6387> cluster meet 127.0.0.1 6382
OK
让所有的节点都互相感知
127.0.0.1:6387> cluster nodes
e70238d739f433b74d4e86c4f651ea97085e2306 127.0.0.1:6382 master - 0 1525825154654 0 connected
aa95cc1e617a173aba2a1839a9fcf03f1fa06a94 127.0.0.1:6387 myself,master - 0 0 1 connected
127.0.0.1:6387> cluster meet 127.0.0.1 6383
OK
127.0.0.1:6387> cluster meet 127.0.0.1 6384
OK
127.0.0.1:6387> cluster meet 127.0.0.1 6385
OK
127.0.0.1:6387> cluster meet 127.0.0.1 6386
OK
127.0.0.1:6387> cluster nodes
1b62871cebb802ebed82b7ce43d2a58a08168c35 127.0.0.1:6383 master - 0 1525825206274 2 connected
714ff9c0cf3c5c45c80bf093a17b290ed02415e9 127.0.0.1:6384 master - 0 1525825207289 3 connected
aa95cc1e617a173aba2a1839a9fcf03f1fa06a94 127.0.0.1:6387 myself,master - 0 0 1 connected
e70238d739f433b74d4e86c4f651ea97085e2306 127.0.0.1:6382 master - 0 1525825207596 0 connected
52a74656529a7af4bd10060038bc866b60e9bb92 127.0.0.1:6385 master - 0 1525825210432 4 connected
e00a19c26d02de645fa1bf493319a91952d49504 127.0.0.1:6386 master - 0 1525825209363 5 connected
前已经使这六个节点组成集群,但是现在还无法工作,因为集群节点还没有分配槽(slot)
3 分配槽
启动后的集群状态为fail,只有把所有槽位都分配给集群节点后状态才变为可用
可以看一下6379端口的槽个数
127.0.0.1:6387> cluster info
cluster_state:fail //状态为fail
cluster_slots_assigned:0 // 被分配槽的个数为0
cluster_slots_ok:0
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:0
cluster_current_epoch:5
cluster_my_epoch:1
cluster_stats_messages_sent:233
cluster_stats_messages_received:233
接下来为节点分配槽空间。通过cluster addslots命令。
16383个槽位必须全部分配玩,不同节点不能重复,一个槽位只能位于一个节点上
/usr/local/redis/src/redis-cli -h 127.0.0.1 -p 6387 cluster addslots {0..5461}
/usr/local/redis/src/redis-cli -h 127.0.0.1 -p 6382 cluster addslots {5462..10922}
/usr/local/redis/src/redis-cli -h 127.0.0.1 -p 6383 cluster addslots {10923..16383}
[root@hongquan1 redis]# /usr/local/redis/src/redis-cli -h 127.0.0.1 -p 6387 cluster addslots {0..5461}
OK
[root@hongquan1 redis]# /usr/local/redis/src/redis-cli -h 127.0.0.1 -p 6382 cluster addslots {5462..10922}
OK
[root@hongquan1 redis]# /usr/local/redis/src/redis-cli -h 127.0.0.1 -p 6383 cluster addslots {10923..16383}
OK
[root@hongquan1 redis]# /usr/local/redis/src/redis-cli -h 127.0.0.1 -p 6387
127.0.0.1:6387> cluster info
cluster_state:ok //分配后,状态为ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:5
cluster_my_epoch:1
cluster_stats_messages_sent:453
cluster_stats_messages_received:453
可以通过CLUSTER NODES来查看分配情况:
127.0.0.1:6387> cluster nodes
1b62871cebb802ebed82b7ce43d2a58a08168c35 127.0.0.1:6383 master - 0 1525825377690 2 connected 10923-16383
714ff9c0cf3c5c45c80bf093a17b290ed02415e9 127.0.0.1:6384 master - 0 1525825378752 3 connected
aa95cc1e617a173aba2a1839a9fcf03f1fa06a94 127.0.0.1:6387 myself,master - 0 0 1 connected 0-5461
e70238d739f433b74d4e86c4f651ea97085e2306 127.0.0.1:6382 master - 0 1525825377895 0 connected 5462-10922
52a74656529a7af4bd10060038bc866b60e9bb92 127.0.0.1:6385 master - 0 1525825375628 4 connected
e00a19c26d02de645fa1bf493319a91952d49504 127.0.0.1:6386 master - 0 1525825376647 5 connected
目前还有三个节点没有使用,作为一个完整的集群,每个负责处理槽的节点应该具有从节点,保证当主节点出现故障时,可以自动进行故障转移。
集群模式下,首次启动的节点和被分配槽的节点都是主节点,从节点负责复制主节点槽的信息和相关数据。
使用cluster replicate
127.0.0.1 6387 127.0.0.1 6384
127.0.0.1 6382 127.0.0.1 6385
127.0.0.1 6383 127.0.0.1 6386
/usr/local/redis/src/redis-cli -h 127.0.0.1 -p 6384 cluster replicate aa95cc1e617a173aba2a1839a9fcf03f1fa06a94
/usr/local/redis/src/redis-cli -h 127.0.0.1 -p 6385 cluster replicate e70238d739f433b74d4e86c4f651ea97085e2306
/usr/local/redis/src/redis-cli -h 127.0.0.1 -p 6386 cluster replicate 1b62871cebb802ebed82b7ce43d2a58a08168c35
127.0.0.1:6387> cluster nodes
1b62871cebb802ebed82b7ce43d2a58a08168c35 127.0.0.1:6383 master - 0 1525825628380 2 connected 10923-16383
714ff9c0cf3c5c45c80bf093a17b290ed02415e9 127.0.0.1:6384 slave aa95cc1e617a173aba2a1839a9fcf03f1fa06a94 0 1525825625343 3 connected
aa95cc1e617a173aba2a1839a9fcf03f1fa06a94 127.0.0.1:6387 myself,master - 0 0 1 connected 0-5461
e70238d739f433b74d4e86c4f651ea97085e2306 127.0.0.1:6382 master - 0 1525825628790 0 connected 5462-10922
52a74656529a7af4bd10060038bc866b60e9bb92 127.0.0.1:6385 slave e70238d739f433b74d4e86c4f651ea97085e2306 0 1525825627360 4 connected
e00a19c26d02de645fa1bf493319a91952d49504 127.0.0.1:6386 slave 1b62871cebb802ebed82b7ce43d2a58a08168c35 0 1525825626349 5 connected
这样就完成了一个3主3从的Redis集群搭建
127.0.0.1:6387> cluster slots
- (integer) 10923
(integer) 16383
- "127.0.0.1"
(integer) 6383
- "127.0.0.1"
(integer) 6386
- (integer) 0
(integer) 5461
- "127.0.0.1"
(integer) 6387
- "127.0.0.1"
(integer) 6384
- (integer) 5462
(integer) 10922
- "127.0.0.1"
(integer) 6382
- "127.0.0.1"
(integer) 6385