Search code examples
javaredispooljedis

Broken pipe while using Jedis Pool


I'm using Jedis to perform a lot of insertions/reads in Redis. The Redis server is using the default configuration. The problem appears when I start using a few threads and the exception is:

redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: Pipe quebrado (Write failed)

I've searched a lot about this problem but couldn't find the reason of it or it's solve. The code I'm using to perform these tests is below:

public class RedisFacade {

private static RedisFacade instancia = null;
// Initialize the Connection
final JedisPoolConfig poolConfig = buildPoolConfig();
JedisPool pool = new JedisPool(poolConfig, "localhost");
Jedis jedis;
int i = 0;

private RedisFacade() {
}

public static RedisFacade getInstancia() {
    if (instancia == null) {
        instancia = new RedisFacade();
    }
    return instancia;
}

// retorna um cliente jedis da pool
public Jedis getDB() {
    if (jedis == null) {
        jedis = pool.getResource();
    }
    return jedis;
}

//inserting
public void insert(Document d) {
    String key = i + d.getString("date") + d.getString("time");
    String value = d.toString();
    this.getDB().set(key, value);
    i++;
}

//reading
public void read(String date, String time) {
    Object doc = this.getDB().get(i + date + time);
    i++;
    System.out.println(doc);
}

public void destroyPool() {
    this.pool.destroy();
}

private JedisPoolConfig buildPoolConfig() {
    final JedisPoolConfig poolConfig = new JedisPoolConfig();
    poolConfig.setMaxTotal(1100);
    poolConfig.setMaxIdle(16);
    poolConfig.setMinIdle(16);
    poolConfig.setTestOnBorrow(true);
    poolConfig.setTestOnReturn(true);
    poolConfig.setTestWhileIdle(true);poolConfig.setMinEvictableIdleTimeMillis(Duration.ofSeconds(60).toMillis());
    poolConfig.setTimeBetweenEvictionRunsMillis(Duration.ofSeconds(30).toMillis());
    poolConfig.setNumTestsPerEvictionRun(3);
    poolConfig.setBlockWhenExhausted(true);
    return poolConfig;
}}

Solution

  • After trying to implement new constructors, new configurations for the pool and clients, I tried a simple way to fix the problem: close the resources I was getting from the pool. To do so, I've changed the following code:

    public Jedis getDB() {
        jedis = pool.getResource();
        return jedis;
    }
    
    //cria um _id pra ser usado novamente quando for buscar os documentos
    public void insert(Document d) {
        String key = "key" + i;
        String value = d.toString();
        Jedis jedis = this.getDB();
        jedis.set(key, value);
        jedis.close();
        i++;
    }
    
    //busca pelo _id
    public void read() {
        Jedis jedis = this.getDB();
        Object doc = jedis.get("key" + i);
        jedis.close();
        i++;
        System.out.println(doc);
    }
    

    After changing the code, the service started to work I was planning, so I'll accept this as a solution.