一.这里我们需要对一致性哈希和哈希槽有一定了解;
一致性哈希:按照2^32次方进行哈希求模,我们把2^32次方大小想象为一个0到2^32-1的一个哈希环,
1.我们对Redis分布的当前机器按照IP或机器名以一致性哈希计算并定位所在哈希环的节点位置
2.我们对需要存储的数据key也按照一致性哈希计算并定位所在哈希环的位置,然后按照顺时针找到距离最近的节点机器位置,找到后将当前数据存储到这个节点上,依次类推进行存储,
3.当机器不多的时候,很可能出现几台机器在环上面贴的很近,不是在环上均匀分布,为了解决这个问题,可以引入“虚拟机器”的概念,也就是说:1台机器,我在环上面计算出多个位置。怎么弄呢? 假设用机器的ip来hash,我可以在ip后面加上几个编号, ip_1, ip_2, ip_3, .. 把1台物理机器生个多个虚拟机器的编号,数据首先映射到“虚拟机器上”,再从“虚拟机器”映射到物理机器上。因为虚拟机器可以很多,在环上面均匀分布,从而保证数据均匀分布到物理机器上面
4.一致性hash 和 hash slot 的算法和网络上介绍它们两的文章,都说一致性hash在删除节点or增加节点时和传统hash相比,所需要迁移的数据更少,这里没问题,hash slot面对删除节点or增加节点时,可以无缝迁移,到这我就不明白了,hash slot删除节点or增加节点的时候,对应的部分哈希槽不也得迁移到别的服务器节点上么,这和一致性hash面临的是同一个问题呀,怎么hash slot就变成了可以不影响客户端的访问,无缝切换:
二、Redis Cluster集群采用哈希槽进行处理,默认分配了2K内存空间(16384)hash槽被分配给不同节点,存放数据时,根据数据的key计算出所在的槽,再根据槽找到对应的机器,同时这2k的信息,通过Gossip协议,在结点之间传递
三、哈希槽策略相比一致性哈希
哈希槽:无损扩容,槽会在机器之间重新分配,同时被影响的数据会自动迁移,从而做到无损扩容
一致性哈希:有损扩容(影响比较小),需要同步处理新增/删除节点跟下个节点的数据同步
四、redis设计的原理:其实就是分库分表,去中心化
1、集群是如何判断是否有某个节点挂掉
首先要说的是,每一个节点都存有这个集群所有主节点以及从节点的信息。它们之间通过互相的ping-pong判断是否节点可以连接上。如果有一半以上的节点去ping一个节点的时候没有回应,集群就认为这个节点宕机了,然后去连接它的备用节点。
2、集群进入fail状态的必要条件
A、某个主节点和所有从节点全部挂掉,我们集群就进入faill状态。
B、如果集群超过半数以上master挂掉,无论是否有slave,集群进入fail状态.
C、如果集群任意master挂掉,且当前master没有slave.集群进入fail状态
3.redis集群去中心化(所有Master节点并发处理读写)
集群中原则每个Master节点都有一个或多个Slave节点。集群中所有的Master节点都可以进行读写数据,不分主次,记redis集群式去中心化的。每个Master节点与Slave节点间通过Goossip协议内部通信,异步复制。不用我们瞎操心(所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.),但是异步赋值会导致某些特定情况下的数据丢失,即,redis集群不能保证数据的强一致性
4.redis集群的分区规则:虚拟槽分区(槽:slot)
RedisCluster采用此分区,所有的键根据哈希函数(CRC16[key]&16383)映射到0-16383槽内,共16384个槽位,每个节点维护部分槽及槽所映射的键值数据
哈希函数: Hash()=CRC16[key]&16383 按位与
redis用虚拟槽分区原因:解耦数据与节点关系,节点自身维护槽映射关系,分布式存储
5. redisCluster的缺陷(虚拟槽分区的缺点)
a,键的批量操作支持有限,比如mset, mget,如果多个键映射在不同的槽,就不支持了
b,键事务支持有限,当多个key分布在不同节点时无法使用事务,同一节点是支持事务
c,键是数据分区的最小粒度,不能将一个很大的键值对映射到不同的节点
d,不支持多数据库,只有0,select 0
e,复制结构只支持单层结构,不支持树型结构。
6.客户端与redis集群交互方式
由于Cluster架构中无Proxy层,客户端是直接与集群中的任意可用节点直接交互的,【话是这么说,但是一个请求是怎么找到集群中的一个节点的呢,redis有多种策略,一般使用CRC16去hash(key)计算改请求要分配到具体的哪一个节点上。然后才是 客户端与节点的直接操作】对象保存到Redis之前先经过CRC16哈希到一个指定的Node上,