
常见的Redis集群架构是三主三从的结构,为了保证数据分片,redis采用了Hash槽的概念,即:
常见的三主三从结构,将solt平均分到三个节点上
如果存入一个值,按照redis cluster哈希槽的 算法 : CRC16('key')384 = 6782。 那么就会把这个key 的存储分配到 B 上了。同样,当我连接(A,B,C)任何一个节点想获取'key'这个key时,也会这样的算法,然后内部跳转到B节点上获取数据
新增一个节点D,redis cluster的这种做法是从各个节点的前面各拿取一部分slot到D上,会变成这样:
同样删除一个节点也是类似,移动完成后就可以删除这个节点了。
Redis的Hash槽分配不是 一致性Hash ,一致性Hash是成一个hash环,当节点加入或者失效的时候,在环上顺时针找到对应节点。而Redis集群属于手动分配 线性Hash槽 ,需要手动指定,并且尽量做到各个节点solt平均分配。
而至于为什么Redis没有采用一致性Hash,因为如果一个节点失效,把数据转移到下一个节点,容易造成缓存雪崩,而采用hash槽+副本节点失效的时候从节点自动接替,不易造成雪崩。
twitter的 twemproxy 是一个Redis的代理服务程序,能够实现key的分片。分片能使key均匀地分布到集群的机器上去,能保证数据的一致性,有着众多的优点。
但从Redis单实例切换到twemproxy集群时,还是有些需要注意的地方:
不支持的方法:
KEYS,MIGRATE,SCAN等
支持但需特殊处理的方法:
MSET,SINTERSTORE,SUNIONSTORE,ZINTERSTORE,ZUNIONSTORE等
全部请查看 Redis命令列表
对于不支持的方法,在使用时需要寻找替代方案。本文主要解决一下需特殊处理的方法。
单实例上的MSET是一个原子性(atomic) *** 作,所有给定 key 都会在同一时间内被设置,某些给定 key 被更新而另一些给定 key 没有改变的情况,不可能发生。
而集群上虽然也支持同时设置多个key,但不再是原子性 *** 作。会存在某些给定 key 被更新而另外一些给定 key 没有改变的情况。其原因是需要设置的多个key可能分配到不同的机器上。
这四个命令属于同一类型。它们的共同之处是都需要对一组key进行运算或 *** 作,但要求这些key都被分配到相同机器上。
这就是分片技术的矛盾之处:
即要求key尽可能地分散到不同机器,又要求某些相关联的key分配到相同机器。
解铃还需系铃人。解决方法还是从分片技术的原理上找。
分片,就是一个hash的过程:对key做md5,sha1等hash算法,根据hash值分配到不同的机器上。
为了实现将key分到相同机器,就需要相同的hash值,即相同的key(改变hash算法也行,但不简单)。
但key相同是不现实的,因为key都有不同的用途。例如user:user1:ids保存用户的tweets ID,user:user1:tweets保存tweet的具体内容,两个key不可能同名。
仔细观察user:user1:ids和user:user1:tweets,两个key其实有相同的地方,即user1。能不能拿这一部分去计算hash呢?
这就是 Hash Tag 。允许用key的部分字符串来计算hash。
当一个key包含 {} 的时候,就不对整个key做hash,而仅对 {} 包括的字符串做hash。
假设hash算法为sha1。对user:{user1}:ids和user:{user1}:tweets,其hash值都等同于sha1(user1)。
Hash Tag是用于hash的部分字符串开始和结束的标记,例如"{}"、"$$"等。
配置时,只需更改hash_tag字段即可
博客链接: >
以上就是关于Redis - 集群Hash槽分配全部的内容,包括:Redis - 集群Hash槽分配、Redis技巧:分片技术和Hash Tag、等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)