agentscope-ai / agentscope-ai/agentscope-java

[Bug]:`ERR 'EVAL' command keys must in same slot` in Redis Cluster

未关闭
#2,165 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
area/extensions bug
主要语言
Java
星标
5.6k
派生
1.3k
平均合并
4 天 12 小时
30 天内合并 PR
77

描述

### 🐞 Bug Report: `ERR 'EVAL' command keys must in same slot` in Redis Cluster

**Describe the bug**
The `RedisStore` implementation fails when running against a Redis Cluster. The `put` operation executes a Lua script (`EVAL`) involving two keys: the item hash key and the namespace index key. Since these keys have different prefixes (`item:` vs `idx:`), they are hashed to different slots in the cluster, causing the `EVAL` command to fail with `ERR 'EVAL' command keys must in same slot`.

**To Reproduce**
1. Configure the application to connect to a Redis Cluster (not a standalone instance).
2. Initialize the `RedisStore` class.
3. Call the `put` method to store an item.
```java
store.put(Arrays.asList("test", "namespace"), "my-key", myValueMap);
```
4. See the error in the logs.

**Expected behavior**
The `put` operation should succeed. The item hash and the namespace index should be stored atomically. To support Redis Cluster, the keys used in the Lua script must belong to the same hash slot (typically achieved by using hash tags like `{...}` in the key names).

**Error messages**
```text
redis.clients.jedis.exceptions.JedisDataException: ERR 'EVAL' command keys must in same slot
at redis.clients.jedis.Protocol.processError(Protocol.java:110)
at redis.clients.jedis.Protocol.process(Protocol.java:158)
at redis.clients.jedis.Protocol.read(Protocol.java:221)
at redis.clients.jedis.Connection.protocolRead(Connection.java:384)
at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:397)
at redis.clients.jedis.Connection.getOne(Connection.java:370)
at redis.clients.jedis.Connection.executeCommand(Connection.java:175)
at redis.clients.jedis.executors.DefaultCommandExecutor.executeCommand(DefaultCommandExecutor.java:24)
at redis.clients.jedis.UnifiedJedis.executeCommand(UnifiedJedis.java:311)
at redis.clients.jedis.UnifiedJedis.eval(UnifiedJedis.java:3478)
at io.agentscope.extensions.redis.store.RedisStore.put(RedisStore.java:145)
...
```

**Environment (please complete the following information):**
- **AgentScope-Java Version:** [2.0.0]
- **Java Version:** [7]
- **OS:** [linux]
- **Redis Mode:** Cluster

**Additional context**
The issue lies in the `RedisStore.java` file. The `put` method calls:
```java
jedis.eval(PUT_SCRIPT, List.of(itemKey, idxKey), List.of(json, key));
```
The `itemKey` is generated as `prefix:item:\0` and `idxKey` as `prefix:idx:`.
Because the constant parts `item:` and `idx:` differ, `CRC16(itemKey) != CRC16(idxKey)`.

**Suggested Fix:**
Modify `itemKey` and `indexKey` methods to wrap the namespace part in curly braces `{}` to force them into the same slot.
```java
// Example Fix
private String itemKey(List namespace, String key) {
String nsPath = namespacePath(namespace);
// Use hash tag {nsPath} to ensure co-location
return keyPrefix + "item:{" + nsPath + "}" + NS_SEPARATOR + key;
}

private String indexKey(List namespace) {
String nsPath = namespacePath(namespace);
// Use hash tag {nsPath}
return keyPrefix + "idx:{" + nsPath + "}";
}
```

贡献指南

打开贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。