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 摘要。