agentscope-ai / agentscope-ai/agentscope-java

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

オープン
#2,165 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る
area/extensions bug
主要言語
Java
スター
5.6k
フォーク
1.3k
平均マージ
4日 12時間
マージ済み PR(30日)
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 を短くまとめたダイジェスト。