Redis中Key中为什么要使用{}

时间:2024-01-24 08:58:35

一、Redis集群介绍

Redis集群是一个提供在多个Redis间节点间共享数据的程序集,Redis集群能够实现key的分片,分片能使key均匀地分布到集群的机器上去,能保证数据的一致性。

二、使用Redis集群需要注意的点

从Redis单实例切换到twemproxy集群时,有些需要注意的地方。
1、不支持的方法:
KEYS、MIGRATE、SCAN等

2、支持但需特殊处理的方法:
MSET、SINTERSTORE、SUNIONSTORE、ZINTERSTORE、ZUNIONSTORE等

对于不支持的方法,在使用时需要寻找替代方案。

三、Redis集群的数据分片

Redis集群没有使用一致性hash,而是引入了哈希槽的概念。

Redis集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽。集群的每个节点负责一部分hash槽,举个例子,比如当前集群有3个节点,那么:

节点 A 包含 0 到 5500号哈希槽。
节点 B 包含5501 到 11000 号哈希槽。
节点 C 包含11001 到 16384号哈希槽。

这种结构很容易添加或者删除节点。比如如果我想新添加个节点D, 我需要从将节点 A、B、C中的部分槽到D上。如果我想移除节点A,需要将A中的槽移到B和C节点上,然后将没有任何槽的A节点从集群中移除即可。 由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态。

四、MSET

单实例上的MSET是一个原子性(atomic)操作,所有给定key都会在同一时间内被设置,某些给定key被更新而另一些给定key没有改变的情况,不可能发生。

而集群上虽然也支持同时设置多个key,但不再是原子性操作。会存在某些给定 key 被更新而另外一些给定key没有改变的情况。其原因是需要设置的多个key可能分配到不同的机器上。

SINTERSTORE、SUNIONSTORE、ZINTERSTORE、ZUNIONSTORE

这四个命令属于同一类型。它们的共同之处是都需要对一组key进行运算或操作,但要求这些key都被分配到相同机器上。这就是分片技术的矛盾之处:即要求key尽可能地分散到不同机器,又要求某些相关联的key分配到相同机器。

五、Hash Tags

解铃还需系铃人,解决方法还是从分片技术的原理上找。

分片,就是一个hash的过程:对key做md5,sha1等hash算法,根据hash值分配到不同的机器上。为了实现将key分到相同机器,就需要相同的hash值,即相同的key(改变hash算法也行,但不简单)。但key相同是不现实的,因为key都有不同的用途。例如user:user1:ids保存用户的tweets ID,user:user1:tweets保存tweet的具体内容,两个key不可能同名。

仔细观察user:user1:idsuser:user1:tweets,两个key其实有相同的地方,即user1。能不能拿这一部分去计算hash呢?

这就是Hash Tag,允许用key的部分字符串来计算hash。当一个key包含{} 的时候,就不对整个key做hash,而仅对{} 包括的字符串做hash。假设hash算法为sha1。对user:{user1}:idsuser:{user1}:tweets,其hash值都等同于sha1(user1)。

HashTag可能会使过多的key分配到同一个slot中,造成数据倾斜影响系统的吞吐量,务必谨慎使用。