redis集群数据存储方式

为什么需要集群

随着业务的发展,用户的增多,越来越多的数据需要去查询数据库。为了提高性能,往往会在查询数据库前加入缓存。然而随着业务的发展,单节点面临的问题也越来越多。查询压力,单点故障等等,所以我们需要使用缓存集群。

欢迎关注个人公众号【好好学技术】交流学习

集群上的数据是怎么存储的

如何把数据均衡分布到集群各个节点呢?假设有三个节点。

轮询可以吗?

写入数据的时候可以轮询写入
redis集群数据存储方式_第1张图片

查询的时候也轮询查询,这时就会出现问题,极端情况下需要查询三次。
redis集群数据存储方式_第2张图片

hash可以吗?

如果我们对key取hash,然后对集群数量取模,那么就会得到一个key存储的机器位置。存和取的时候都可以去这台机器上查,时间复杂度就是O(1)了。

但是这种方式问题也是很严重的。
1.数据分布不均衡,有可能某个节点内存都满了,但是另外的节点内存压根没用多少。
2.增加集群节点数非常困难,因为增加节点之后,hash取模的值就变了,缓存命中率就会变低。更严重还可能导致缓存雪崩。

那么到底有没有什么办法能够保证数据存储均衡,也能够支持动态扩容呢?

hash solt

redis采用hash槽的方式来进行数据存储的。
redis定义了16384个虚拟的哈希槽,将这16384个槽分配带集群各个节点上,然后多key通过crc16算法得到一个值,然后对16384取模,得到0到16383之间的一个数字。然后就会将key存储到对应数字的节点上。
redis集群数据存储方式_第3张图片

当集群扩容时会从每个节点上取一部分槽放到新节点上
redis集群数据存储方式_第4张图片

如果节点从3扩容到4,那么影响的数据就是4分之一。

其实这种方式依赖的算法就是hash一致性算法。

hash一致性算法

一致性哈希算法在 1997 年由麻省理工学院提出,是一种特殊的哈希算法,目的是解决分布式缓存的问题。 在移除或者添加一个服务器时,能够尽可能小地改变已存在的服务请求与处理请求服务器之间的映射关系。一致性哈希解决了简单哈希算法在分布式哈希表( Distributed Hash Table,DHT) 中存在的动态伸缩等问题 。

hash环

hash环是一个虚拟的圆环,按照顺时针取值,范围为0到2的32次方减1.
redis集群数据存储方式_第5张图片

假设我们有四个节点,那么通过对节点的某个属性求hash,然后与环上的值进行配对,将节点配置到环上。
redis集群数据存储方式_第6张图片

此时如果有数据需要存储或者查询,那么只要算出key对应的hash值,然后确定hash在环上的位置,从此位置顺时针查找最近的一个节点即可。
redis集群数据存储方式_第7张图片

但是这只是我们理想情况下节点分布比较均衡的情况,假如算出来节点分布并不均衡,那么就会导致数据分布不均匀,每个节点承载的压力不均匀。
redis集群数据存储方式_第8张图片

新增节点时,则只有新增节点顺时针往前的那一个节点的数据受影响。
redis集群数据存储方式_第9张图片
为了解决这两个问题,因此引入了虚拟节点。
为了画图方便,我们假设每个节点有四个虚拟节点(实际情况中远不止四个,虚拟节点越多,数据分布不均衡),那么三个节点就总共有12个虚拟节点。
redis集群数据存储方式_第10张图片

新增节点的时候,也会生成相同数量的虚拟节点,均匀的分散在环上,对原有影响也更均衡。
redis集群数据存储方式_第11张图片

由此可以知道,如果集群中节点数量越多,虚拟节点也就越多,新增节点时,影响的数据量就越小。

总结

redis集群就是借鉴了hash一致性算法,16384个哈希槽,就是对应的16384个虚拟节点。新增节点时,就是对这些哈希槽重新分配,影响的数据量就为集群数量分之一。

你可能感兴趣的:(redis,redis,java,哈希算法)