jedis 正确管理连接

问题描述

我写了一个类,其中有连接池和流水线,使用这个类的方法类似于(我删除一个循环,但 setKey 会在循环中发生):

private Redis redis = new Redis();
redis.setKey(path,keyvalueOutput,3000);
redis.setKey(path,3000);
if (redis.getPipelineCount() > 200) {
   redis.syncKeys();
   System.out.println("200 items added");
}

因此,只要管道上的项目数量超过 200,我就会同步项目并清除管道并重新开始。问题是这种设置如何正确地将连接返回到池中。

public class Redis {
    private JedisPoolConfig poolConfig = new JedisPoolConfig();
    private JedisPool jedisPool = new JedisPool(poolConfig,"localhost",6379);
    private Jedis jedis = jedisPool.getResource();
    
    private Pipeline pipeline = jedis.pipelined();
    private int pipelineCount = 0;

    public void setKey(String path,Map<String,String> keyvalueOutput,int expireTime) {
        this.pipeline.hset(path,keyvalueOutput);
        this.pipeline.expire(path,expireTime);
        this.pipelineCount = this.pipelineCount + 1;
    }

    public void syncKeys() {
        this.pipeline.sync();
        this.pipelineCount = 0;
    }

    public int getPipelineCount() {
        return this.pipelineCount;
    }

    public void close() {
        this.jedis.close();
    }

}

据我所知,我必须将 jedisPool.getResource() 包装到 try 块中,但我无法思考如何将它与我的管道和计数器结合在一起。

        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            Pipeline p = jedis.pipelined();
            p.sync()
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }

解决方法

syncKeys() 方法将是执行此操作的正确位置。您可能需要某种锁定以确保安全。我以 synchronized 为例。

    public synchronized void syncKeys() {
        this.pipeline.sync();
        this.jedis.close();
        this.jedis = null;
        this.pipelineCount = 0;
    }

除此之外,您的应用程序是多线程的吗?如果没有,那么您不必要地使用 JedisPool。简单的 Jedis 就足够了。否则,您使用 Pool 是错误的。例如,您的 Redis 对象在特定时间最多只能使用一个 Jedis 对象。这将成为多线程场景中的瓶颈。