4

My Application uses ElastiCache on AWS for caching purposes. Our current set up uses a basic Redis Cluster with no sharding or failover. We need to now move to a Clustered Redis Elastic Cache with sharding, failover etc enabled. Creating a new cluster on AWS was the easy bit, but we are a bit lost on how to modify our java code to reads and write from the cluster.

Current Implementation - Initialize a JedisPool.

JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(100);
jedisPoolConfig.setMaxIdle(10);
jedisPoolConfig.setMaxWaitMillis(50);
jedisPoolConfig.setTestOnBorrow(true);

String host = "mycache.db8e1v.0001.usw2.cache.amazonaws.com";
int port = 6379;
int timeout = 50;

JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout)

A Jedis object is borrowed from the pool everytime we need to perform an operation

Jedis jedis = JedisPool.getResource();

The new implementation would be

JedisPoolConfig jedisPoolConfig = ...
HostAndPort hostAndPort = new HostAndPort(host, port);
jedisCluster = new JedisCluster(Collections.singleton(hostAndPort), jedisPoolConfig);

Question: The documentation says JedisCluster is to be used in place of Jedis (not JedisPool). Does this mean I need to create and destroy a JedisCluster object in each thread. Or can I re-use the same object and it will handle the thread safety? When do I exactly close the JedisCluster then? At the end of the application?

Pranav Kapoor
  • 1,171
  • 3
  • 13
  • 32
  • just a side comment, if you'll use https://redislabs.com/redis-enterprise/cloud/ instead you won't have to deal with different client code do to it proxy/endpoint – Guy Korland Dec 20 '18 at 04:34

2 Answers2

7

The JedisCluster holds internal JedisPools for each node in the cluster.

Does this mean I need to create and destroy a JedisCluster object in each thread. Or can I re-use the same object and it will handle the thread safety?

You can reuse the same object.

When do I exactly close the JedisCluster then? At the end of the application?

Yes.

Dale K
  • 25,246
  • 15
  • 42
  • 71
Guy Korland
  • 9,139
  • 14
  • 59
  • 106
0

Replacing all Jedis-calls with JedisCluster-calls is the best way to migrate.

But I wanted pipeline support which JedisCluster currently lacks. So one other idea is to extend JedisCluster to return the JedisPool>Jedis for a particular key:

protected Jedis getJedis(String key) {
    int slot = JedisClusterCRC16.getSlot(key);
    return connectionHandler.getConnectionFromSlot(slot);
}

The extended class has to be in namespace redis.clients.jedis to access getConnectionFromSlot.

Now a pipeline can be executed on the Jedis.

And you need a different Jedis for each key you want to operate on. Which makes sense - in cluster mode, each key can be on a different node.

Curtis Yallop
  • 6,696
  • 3
  • 46
  • 36
  • what happens if I grab Jedis providing key "X" and then use that Jedis to store key "Y" which falls into another redis instance in cluster? – ante.sabo Dec 20 '20 at 13:31
  • @ante.sabo That usage would be unsupported. As I mentioned, "you need a different Jedis for each key you want to operate on". This is more of a custom, modified solution than a foolproof Jedis-design for everyone. – Curtis Yallop Jan 19 '21 at 21:43