Redis集群
一、为什么要使用Redis集群
Redis是基于内存的数据库,机器的内存普遍在16~256G之间,如果我们的数据量有500G,这时必须使用Redis Cluster。
二、数据分区
我们在学习Redis集群之前我们先看看数据分区的概念,就是怎么将所有的数据合理的分配到不同的节点上。常有的分区方式有顺序分区和哈希分区。
2.1 顺序分区
就是将同一个范围内的数据存储到同一个Redis实例中,比如有一张用户表,我们将ID0-ID10000的,ID-10001-ID20000,以此类推,存储到同一个实例中。那么如果我们有些数据不好分区,比如有些ID是随机数,UUID等等,我们可以使用哈希分区
哈希分区跟范围分区相比一个明显的优点是哈希分区适合任何形式的key,而不像顺序分区一样有局限性,而且分区方法也很简单,一个公式就可以表达:id=hash(key)%nodes
2.2.1 节点取余分区
当我们Redis节点有三台,但是数据越来越多时,我们会考虑增加节点,这个时候我们建议使用多倍扩容,比如3台节点我们扩容到4台那么80%的数据会切换接点,比如从1到了2节点等现象,数据迁移变化太多,我们如果熙增到6台节点那么只有50%的数据会迁移。
2.2.2 一致性哈希分区
上边我们说到哈希取余方式如果增加节点对数据造成的迁移比较大,一致性哈希就是解决了这种问题。我们可以将Redis保存数据认为是一个环形,Hash值有32位,0~2 ^32,将节点的IP+算法确定唯一的哈希值,之后在内存中确定节点的位置,当保存数据时,根据key进行哈希运算,顺时针确定挂载到哪台节点上。
如果集群需要添加节点,比如在node2和node3之间添加一个node4,数据分布会变成下图
我们会发现,数据依然有迁移,本来在node3上的数据一部分迁移到了node4上,但是node1和node2没有受到影响。
这种分区方式在memCache(分布式缓存系统)中使用。
2.3 Redis哈希槽(redis的数据分区方式)
Redis内置了16384个槽,从0-16383。每个节点都维护一个范围的哈希槽,当有新的key需要添加时,会使用CRC16算法并且对16384取余,公式:CRC16(key) & 16384。得到一个值,去找Redis集群中的节点,看看这个槽是哪个节点维护的,就将key存储到哪个节点上。
如果Redis集群中要增加节点,即集群扩容:
通过相关配置即可完成,这个过程中也会造成相关数据的移动(但这个我们是可控制的)。我们在配置的时候是可以设置:
(1)需要多少个槽移动到新的节点上,自己设置
(2)是从所有节点的槽平均分配,还是具体从哪个节点移动具体多少个槽到新的节点上
三、集群搭建
执行命令:
redis-cli --cluster create 192.168.11.101:8000 192.168.11.101:8001 192.168.11.101:8002 192.168.11.101:8003 192.168.11.101:8004 192.168.11.101:8005 --cluster-replicas 1
系统自动设置8000,8001,8002为主节点,而8003,8004,8005为从节点。并自动将16384个槽平均分配给这三个主节点。
8000:0-5461
8001:5462-10922
8002:10923-16383
四、Redis 集群架构图
这里有5个Redis,搭建集群的时候系统会自动将16384个槽平均分配给这5个节点。他们之间是相互通信(会发送meet命令,回应PONG,相互检测是否正常)的,每个节点都知道对应的槽是哪个节点负责。下方的绿色客户端可以去操作Redis集群中可用(集群中也会有主从节点)的节点。客户端可以随便连接任意一个节点去操作。如果客户端要找的数据在该节点上就会返回数据,如果不在会响应客户端新的节点地址,做一个转发操作,去新的节点上获取数据。当节点多时,效率不高,需要智能客户端。
四、smart客户端
使用SpringBoot2.X操作Redis5.X集群,即通过JedisCluster对象操作Redis集群,可大大提高我们对Redis集群操作的性能。
原理:
1,从集群中选择一个可以运行的节点,使用Cluster slots初始化槽和节点映射
2,将这种映射关系存储到本地,为每一个节点创建一个Jedis Pool
3,之后直接连接到Redis节点上去执行命令
4,smart客户端将key发送到指定的节点上,如果成功就会得到响应
5,如果出现连接出错,随机找个活跃节点,向其发送命令,大概率会得到 moved 异常,然后重新初始化 slot 和 node 的映射关系,再向目标节点发送命令
6,如果这样的情况连续出现 5 次,报错:Too many cluster redirection!