
# GeminiDB Redis集群版实例中，哪些命令需要使用hashtag
#### Hashtag简介及使用方法
相较于单机/主备单分片多key命令的使用，原生Cluster集群多key命令的使用需要遵循[hashtag机制](https://redis.io/docs/latest/operate/rc/databases/configuration/clustering/)，将包含相同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场景会有内存增加、访问变慢的风险，不推荐使用。
