java - Jedis 管道异常

标签 java redis jedis

当我使用 jedis 时,如下面的代码:

public class JedisTest extends Sync {
    private static final String _SET_KEY_1 = "test1";
    private static final String _SET_KEY_2 = "test2";

    public void process() throws SQLException {
        Set<String> appSet = getAllUserableAppkey();
        final ShardedJedis jedis = RedisHelper.getJedis();
        final ShardedJedisPipeline pipeline = jedis.pipelined();

        for (String key : appSet) {
            Set<String> result = jedis.smembers(_SET_KEY_1);
            Set<String> result2 = jedis.smembers(_SET_KEY_2);
            String rangName = String.format("%s::%s", "test", key);
            for (int i = 0; i < 10; i++) {
                pipeline.sadd(rangName, String.valueOf(i));
            }
        }
        pipeline.sync();
    }

    public Set<String> getAllUserableAppkey() {

    }

    public static void main(String[] args) throws Exception {
        DbHelper.init();
        RedisHelper.init();
        JedisTest jedisTest = new JedisTest();
        try {
            jedisTest.process();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

它抛出这样的异常:

Exception in thread "main" java.lang.ClassCastException: java.lang.Long cannot be cast to java.util.List
    at redis.clients.jedis.Connection.getBinaryMultiBulkReply(Connection.java:224)
    at redis.clients.jedis.Connection.getMultiBulkReply(Connection.java:217)
    at redis.clients.jedis.Jedis.smembers(Jedis.java:1055)
    at redis.clients.jedis.ShardedJedis.smembers(ShardedJedis.java:339)
    at com.snda.sync.impl.test.JedisTest.process(JedisTest.java:29)
    at com.snda.sync.impl.test.JedisTest.main(JedisTest.java:58)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

我可以修改代码来纠正:

public void process() throws SQLException {
    Set<String> appSet = getAllUserableAppkey();
    final ShardedJedis jedis = RedisHelper.getJedis();
    for (String key : appSet) {
        final ShardedJedisPipeline pipeline = jedis.pipelined();
        Set<String> result = jedis.smembers(_SET_KEY_1);
        Set<String> result2 = jedis.smembers(_SET_KEY_2);
        //log.warn("result1 :{},result2:{}",result,result2);
        String rangName = String.format("%s::%s", "test", key);
        for (int i = 0; i < 10; i++) {
            pipeline.sadd(rangName, String.valueOf(i));
        }
        pipeline.sync();
    }
}

但我不知道为什么会抛出异常,pipline.sadd()jedis.smembers冲突吗? 谢谢你回答我!

绝地武士最新:2.7.2

最佳答案

您不应该在管道化时直接使用 Jedis 实例。

Pipeline 使用 Jedis 实例的流(而不是初始化新流),并且由于正常操作会立即读取响应,而 Pipeline 会稍后读取整个响应,因此混合两种用法会给 Jedis 带来麻烦。

P -- 流水线/N -- 正常

请求 --> P(1) P(2) N(3) N(4) P(5)

Redis 响应 --> P(1) P(2) N(3) N(4) P(5)

匹配的请求-响应 --> N(1 : 应该是 3) N(2 : 应该是 4) P(3 : 应该是 1) P(4 : 应该是 2) P(5)

您可以看到响应很容易有缺陷。

关于java - Jedis 管道异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31182303/

相关文章:

java - Redis/Jedis - 按模式删除?

java - Docker 编写 Redis 和 Spring boot 应用程序 : java.net.ConnectException : Connection refused (Connection refused)",

java - 是否可以通过 Java 程序使用 Chrome/Firefox 扩展/插件?

java - 结合 JavaFX 3D 形状看起来透明

java - 从 JAVA 中的 MAP 打印

java - 无法使用 Lettuce 连接到本地 Redis 集群

node.js - 在 Node.js/Express 中的路由中传递 Redis 键值对

java - 约翰逊特罗特算法

r - 通过R在redis中存储大数据帧

java - 带有对象池的 Jediscluster