部分摘自:Redis Cluster 有哪些优势和限制? - zbs666 - 博客园,并作修改
1.Cluster概述
Redis Cluster 是 Redis 原生的数据分片实现,可以自动在多个节点上分布数据,不需要依赖任何外部的工具。
Redis Cluster 中所有 key 会被分派到 16384
个 slot
(hash 槽)中,这些 slot 又会被指派到多个 Redis 节点上。
一个 key 会映射到某个 slot,算法:
HASH_SLOT = CRC16(key) mod 16384
2. 限制
2.1 只支持一个数据库
不像单机Redis,Redis Cluster 只支持一个数据库(database 0),select
命令就不能用了,但实际也很少有人使用多数据库,所以这个限制并没什么影响。
2.2 Multi-Key 操作受限
Multi-Key 即 多key。
某些情况是多 key 的操作,例如:
- SUNION,这类命令会操作多个key: Redis Sunion 命令 | 菜鸟教程
- 事务,会在一个事务中操作多个key:Redis 事务 | 菜鸟教程
- LUA脚本,也会操作多个key:Redis 脚本 | 菜鸟教程
- mget类的命令
这类情况都需要特别注意,因为:Redis Cluster 要求,只有这些 key 都在同一个 slot 时才能执行。
例如,有2个key,key1 和 key2。
key1 是映射到 5500 这个 slot 上,存储在 Node A。
key2 是映射到 5501 这个 slot 上,存储在 Node B。
那么就不能对 key1 和 key2 做事务操作。
3. Multi-Key 限制的解决方法
对于多key场景,需要做好数据空间的设计,Redis Cluster 提供了一个 hash tag
的机制,可以让我们把一组 key 映射到同一个 slot。
例如:user1000.following
这个 key 保存用户 user1000 关注的用户;user1000.followers
保存用户 user1000 的粉丝。
这两个 key 有一个共同的部分 user1000
,可以指定对这个共同的部分做 slot 映射计算,这样他们就可以在同一个槽中了。
使用方式:
{user1000}.following 和 {user1000}.followers
就是把共同的部分使用 { }
包起来,计算 slot 值时,如果发现了花括号,就会只对其中的部分进行计算:
Hash Tags 【注意:位置任意,例如user:{user1}:ids和user:{user1}:tweets】
HashTag机制可以影响key被分配到的slot,从而可以使用那些被限制在slot中操作。
HashTag即是用
{}
包裹key的一个子串,如{user:}1
,{user:}2
。在设置了HashTag的情况下,集群会根据HashTag决定key分配到的slot, 两个key拥有相同的HashTag:
{user:}
, 它们会被分配到同一个slot,允许我们使用MGET命令。通常情况下,HashTag不支持嵌套,即将第一个{和第一个}中间的内容作为HashTag。若花括号中不包含任何内容则会对整个key进行散列,如
{}user:
。HashTag可能会使过多的key分配到同一个slot中,造成数据倾斜影响系统的吞吐量,务必谨慎使用。
4. 小结
Multi-Key 这一点是 Redis Cluster 对于我们日常使用中最大的限制,一定要注意,如果多key不在同一个 slot 中就会报错,例如:
(error) CROSSSLOT Keys in request don't hash to the same slot
需要使用 hash tag
设计好 key 的空间。