agentscope-ai / agentscope-ai/agentscope-java

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

Đang mở
#2,165 1 bình luận 0 reaction 0 người được giao Xem trên GitHub
area/extensions bug
Ngôn ngữ chính
Java
Star
5.6k
Fork
1.3k
Merge trung bình
4 ngày 12 giờ
Pull request đã merge (30 ngày)
77

Mô tả

### 🐞 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 + "}";
}
```

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.