Redis3.0开始引入了去中心化分片集群Redis Cluster。
传统的Redis集群是基于主从复制+哨兵的方式来实现的。但是集群中都只有一个主节点提供写服务。
Redis Cluster则采用多主多从的方式,支持开启多个主节点,每个主节点上可以挂载多个从节点。
Cluster会将数据进行分片,将数据分散到多个主节点上,而每个主节点都可以对外提供读写服务。这种做法使得Redis突破了单机内存大小限制,扩展了集群的存储容量。并且Redis Cluster也具备高可用性,因为每个主节点上都至少有一个从节点,当主节点挂掉时,Redis Cluster 的故障转移机制会将某个从节点切换为主节点。
Redis Cluster是一个去中心化的集群,每个节点都会与其他节点保持互连,使用gossip协议来交换彼此的信息,以及探测新加入的节点信息。并且Redis Cluster无需任何代理,客户端会直接与集群中的节点直连。
这种方式就类似我们使用HashMap时选址的方式,只要hash计算出来的值够散列,那么每个key都可以均匀的分散到N个节点上。
但是它存在的问题就是,如果要扩容或缩容,会导致key重新计算存储位置,从而导致缓存失效。
一致性哈希算法将整个哈希值空间组织成一个虚拟的圆环,其范围为0 ~ 2^32-1
,如下图所示:
一致性哈希算法的原理:
我们会先对Key计算它的hash值,从而确定它在环上的位置。然后从该位置沿着环顺指针地走,找到的第一个节点,便是这个Key应该存放的服务器节点的位置。
当我们向集群中增加或减少节点时,就无需像哈希取模算法那样,对整个集群Key的位置进行重新计算。一致性哈希算法将增减节点的影响限制在相邻的节点上,比如:我们在node2
与node4
之间增加一个节点node5
,则只有node4
中的一部分数据会迁移到新增节点上;如果我们想要将node4
节点置为下线状态,则node4
节点的数据只会迁移到node3
中,其他节点无影响。如下图所示:
一致性哈希算法的缺点:
当节点比较少时,增删节点对单个节点的影响会很大,从而导致出现数据不均衡的情况。拿上图来举例,当我们删除任意一个节点,都会导致集群中的某一个节点的数据量由总数据的
1/4
变为1/2
。
该方案在一致性哈希的理论基础上,引入了虚拟节点这一概念。原本是由实际节点来“抢占”哈希环的位置,现在则是将虚拟节点分配给实际节点,然后由虚拟节点来抢占。如下图所示:
在引入了虚拟节点这一概念后,数据到实际节点的映射关系就变成了数据到虚拟节点,再由虚拟节点到实际节点了。Redis 集群便是采用了这种方案。一个集群包含16384个哈希槽(hash slot)也就是16384个虚拟节点。譬如,我们的集群有三个节点,那么:
- Master1节点负责处理
0~5460
号slot- Master2节点负责处理
5461~10922
号slot- Master3节点负责处理
10923~16383
号slot
当我们在集群中新增了一个节点Master4
,那么集群只需要将Master1,Master2,Master3中负责的一部分hash slot分配给Master4节点就可以了;
如果要移除某一个节点,也只需要将该节点负责的hash slot分配给其他的节点即可。这样集群便实现了良好的可扩容性。同时,由于存在16384
个虚拟节点,那么这些hash slot在哈希环上可以分布均匀,从而实现负载均衡。
由于Redis Cluster要求必须要至少6个节点,所以我们就以配置3主3从为例:
修改redis-6390.conf~redis-6395.conf配置文件
# 配置集群节点对应的端口号(分别为6390,6391,6392,6393,6394,6395)
port 6390
# 守护进程开启
daemonize yes
# 关闭保护模式
protected-mode no
# 将集群开启
cluster-enabled yes
cluster-config-file nodes-6390.conf(分别为6390,6391,6392,6393,6394,6395)
启动集群中redis服务
分配主从(--cluster-replicas 1
表示创建一主一从)
./redis-cli --cluster create 127.0.0.1:6390 127.0.0.1:6391 127.0.0.1:6392 127.0.0.1:6393 127.0.0.1:6394 127.0.0.1:6395 --cluster-replicas 1
执行完毕结果如下所示:
我们来登录6390
,看看他在集群中的角色信息是什么
我们在6390客户端中添加一条记录,我们发现,它根据key值确认了slot=12965,然后将数据存储到了6392这个节点上,并且客户端也切换为6392了
配置完集群后,可能会报如下错误,这说明16384个槽位没有分配完
我们通过如下指令就可以进行检查和修复
redis-cli --cluster check 172.17.0.2:6379 redis-cli --cluster fix 172.17.0.2:6379 #官方修复功能
修复后的结果如下所示:
今天的文章内容就这些了:
写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享 。
更多技术干货,欢迎大家关注公众号“爪哇缪斯” ~ \(^o^)/ ~ 「干货分享,每天更新」