只要十分钟!带你了解Redis Cluster

概述

Redis3.0开始引入了去中心化分片集群Redis Cluster。

传统的Redis集群是基于主从复制+哨兵的方式来实现的。但是集群中都只有一个主节点提供写服务

Redis Cluster则采用多主多从的方式,支持开启多个主节点,每个主节点上可以挂载多个从节点。

Cluster会将数据进行分片,将数据分散到多个主节点上,而每个主节点都可以对外提供读写服务。这种做法使得Redis突破了单机内存大小限制,扩展了集群的存储容量。并且Redis Cluster也具备高可用性,因为每个主节点上都至少有一个从节点,当主节点挂掉时,Redis Cluster 的故障转移机制会将某个从节点切换为主节点。

Redis Cluster是一个去中心化的集群,每个节点都会与其他节点保持互连,使用gossip协议来交换彼此的信息,以及探测新加入的节点信息。并且Redis Cluster无需任何代理,客户端会直接与集群中的节点直连。

分片方式

方案1:哈希取模

这种方式就类似我们使用HashMap时选址的方式,只要hash计算出来的值够散列,那么每个key都可以均匀的分散到N个节点上。

但是它存在的问题就是,如果要扩容或缩容,会导致key重新计算存储位置,从而导致缓存失效。

方案2:一致性哈希

一致性哈希算法将整个哈希值空间组织成一个虚拟的圆环,其范围为0 ~ 2^32-1,如下图所示:

只要十分钟!带你了解Redis Cluster_第1张图片

一致性哈希算法的原理:

我们会先对Key计算它的hash值,从而确定它在环上的位置。然后从该位置沿着环顺指针地走,找到的第一个节点,便是这个Key应该存放的服务器节点的位置。

当我们向集群中增加或减少节点时,就无需像哈希取模算法那样,对整个集群Key的位置进行重新计算。一致性哈希算法将增减节点的影响限制在相邻的节点上,比如:我们在node2node4之间增加一个节点node5,则只有node4中的一部分数据会迁移到新增节点上;如果我们想要将node4节点置为下线状态,则node4节点的数据只会迁移到node3中,其他节点无影响。如下图所示:

只要十分钟!带你了解Redis Cluster_第2张图片

一致性哈希算法的缺点:

当节点比较少时,增删节点对单个节点的影响会很大,从而导致出现数据不均衡的情况。拿上图来举例,当我们删除任意一个节点,都会导致集群中的某一个节点的数据量由总数据的 1/4 变为 1/2

方案3:哈希槽

该方案在一致性哈希的理论基础上,引入了虚拟节点这一概念。原本是由实际节点来“抢占”哈希环的位置,现在则是将虚拟节点分配给实际节点,然后由虚拟节点来抢占。如下图所示:

只要十分钟!带你了解Redis Cluster_第3张图片

在引入了虚拟节点这一概念后,数据到实际节点的映射关系就变成了数据到虚拟节点,再由虚拟节点到实际节点了。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在哈希环上可以分布均匀,从而实现负载均衡。

搭建集群(3主3从)

由于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服务

只要十分钟!带你了解Redis Cluster_第4张图片

分配主从(--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

执行完毕结果如下所示:

只要十分钟!带你了解Redis Cluster_第5张图片

我们来登录6390,看看他在集群中的角色信息是什么

只要十分钟!带你了解Redis Cluster_第6张图片

我们在6390客户端中添加一条记录,我们发现,它根据key值确认了slot=12965,然后将数据存储到了6392这个节点上,并且客户端也切换为6392了

只要十分钟!带你了解Redis Cluster_第7张图片

部署过程中可能出现的异常

配置完集群后,可能会报如下错误,这说明16384个槽位没有分配完

只要十分钟!带你了解Redis Cluster_第8张图片

我们通过如下指令就可以进行检查和修复

redis-cli --cluster check 172.17.0.2:6379 redis-cli --cluster fix 172.17.0.2:6379 #官方修复功能

修复后的结果如下所示:

只要十分钟!带你了解Redis Cluster_第9张图片

今天的文章内容就这些了:

写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享 。

更多技术干货,欢迎大家关注公众号“爪哇缪斯” ~ \(^o^)/ ~ 「干货分享,每天更新」

你可能感兴趣的:(面试题详解,redis,java,leetcode,面试)