GeminiDB Redis集群版实例中,哪些命令需要使用hashtag
Hashtag简介及使用方法
相较于单机/主备单分片多key命令的使用,原生Cluster集群多key命令的使用需要遵循hashtag机制,将包含相同hashtag的key分配到相同的哈希槽上(hash slot),以确保多key命令操作的原子性和性能,否则会返回报错“CROSSSLOT Keys in request don't hash to the same slot”。Hashtag使用规则如下:
1. 基本格式
hashtag 用 {} 包裹:只有 {} 内的内容会参与哈希槽计算。
例如:{user:1000}.profile 和 {user:1000}.settings 的 hashtag 都是 user:1000,因此它们会被分配到同一个哈希槽。
2. 位置规则
{} 可以出现在键的任何位置:
例如:foo{user:1000}bar 的 hashtag 仍然是 user:1000。
只有第一个 {} 有效:
如果键中有多个 {},只有第一个 {} 的内容会被用作 hashtag。
例如:{user:1000}.{profile} 的 hashtag 是 user:1000,而 profile 会被忽略。
3. 使用场景
- 事务操作:在Redis集群中,事务(MULTI/EXEC)要求所有涉及的键必须在同一个节点上。通过 hashtag 可以确保这些键被分配到同一个哈希槽。
- Lua 脚本:Lua 脚本中的键也需要位于同一节点,hashtag 可以保证这一点。
- 多key操作:如String(mset、mget)、List(blpop、brpop、brpoplpush、rpoplpush)、Set(sdiff、sdiffstore、sinter、sinterstore、sintercard、sunion、sunionstore)、Zset(zinter、zinterstore、zintercard、zunion、zunionstore、zdiff、zdiffstore、zrangestore)、Key管理(del、exists、unlink、touch、rename、renamenx、sort)、Stream(xread、xreadgroup)、bitop等操作。
集群使用示例:
1. 字符串String: mset / mget
- 设置多个键(用户数据)
mset {user:1000}:name "Alice" {user:1000}:email "alice@example.com" {user:1000}:age 30
- 获取多个键
mget {user:1000}:name {user:1000}:email {user:1000}:age
2. 事务操作:MULTI/EXEC
- 开启事务
MULTI SET {order:1234}:status "processing" EXPIRE {order:1234}:status 3600 EXEC
3. Lua脚本:
- 脚本减少库存并记录日志
EVAL "redis.call('DECR', KEYS[1]); redis.call('SET', KEYS[2], 'updated')" 2 {product:100}:stock {product:100}:log
GeminiDB Redis Proxy集群支持的拆分命令
相较于原生Cluster集群,Proxy集群承担着命令转发、负载均衡和故障转移等职责,可以简化客户使用逻辑,无需过多关注分片管理,同时支持多DB等高级功能。Proxy集群兼容单机、哨兵、Cluster接入方式,推荐使用Proxy集群架构。
与原生Cluster集群相比,Proxy集群支持部分多key命令拆分,分配到不同的后端节点进行处理,完成后在Proxy上进行聚合再返回客户端,简化了多key命令使用逻辑。GeminiDB Redis Proxy集群支持拆分命令如下:
- Key管理相关:del、exists、unlink、touch
- String:mget、mset
- Set: sdiff、sdiffstore、sinter、sinterstore、sintercard、sunion、sunionstore
- Zset: zinter、zinterstore、zintercard、zunion、zunionstore、zdiff、zdiffstore、zrangestore
- 支持对事务中多个命令的拆分;如果事务中包含了不支持拆分的多 key 命令,这些命令涉及的 key 需要添加 hashtag。
其他命令则不支持拆分,推荐在集群中使用hashtag,以保证多key命令操作的原子性和性能。其中Key管理及string多key命令,相比Set和Zset更为轻量级,在shard执行后,在Proxy简单聚合即返回客户端;而Set和Zset的多key命令,需要将每个key读入到Proxy再进行相关的逻辑操作,大key场景会有内存增加、访问变慢的风险,不推荐使用。