Hi Neha,
I think I have fond solution.
We can use JedisCluster for processing simple operations to Redis Cluster (including splitting data by hash tags).
As far as we control distribution of keys on the same instance, for pipeline and transaction operations we can use SharedJedis.
By shardedJedis.getShard(key)we can get Jedis connection to appropriate instance.
It seems like it works, but I hope that someone from Jedis team could warn about pitfalls of this approach.
Simple snippet example:
Set<HostAndPort> hosts = new HashSet<>();
List<JedisShardInfo> list = new ArrayList<>();
for (int i = 1; i < 7; i++) {
hosts.add(new HostAndPort("localhost", Integer.parseInt("3000" + i)));
list.add(new JedisShardInfo("localhost", Integer.parseInt("3000" + i)));
}
try (JedisCluster jedisCluster = new JedisCluster(hosts);
ShardedJedis shardedJedis = new ShardedJedis(list)) {
jedisCluster.hset("wmap", "20","4");
Jedis jedis = shardedJedis.getShard("wmap");
Transaction t = jedis.multi();
t.hset("wmap","20","2");
t.exec();
Pipeline p = jedis.pipelined();
p.hset("wmap", "2", "5");
Response<String> r = p.hget("wmap","2");
p.sync();
String v2 = r.get();
jedis.close();
}
protected void initJedisNodeMap() {
try {
nodeMap = jedisCluster.getClusterNodes();
String anyHost = nodeMap.keySet().iterator().next();
slotHostMap = getSlotHostMap(anyHost);
}catch (JedisClusterException e){
logger.error(e.getMessage());
}
}
protected Jedis getJedis(String key) {
int slot = JedisClusterCRC16.getSlot(key);
Map.Entry<Long, String> entry = slotHostMap.lowerEntry(Long.valueOf(slot));
return nodeMap.get(entry.getValue()).getResource();
}
public static TreeMap<Long, String> getSlotHostMap(String anyHostAndPortStr) {
TreeMap<Long, String> tree = new TreeMap<>();
String parts[] = anyHostAndPortStr.split(":");
HostAndPort anyHostAndPort = new HostAndPort(parts[0], Integer.parseInt(parts[1]));
try (Jedis jedis = new Jedis(anyHostAndPort.getHost(), anyHostAndPort.getPort())) {
List<Object> list = jedis.clusterSlots();
for (Object object : list) {
List<Object> list1 = (List<Object>) object;
List<Object> master = (List<Object>) list1.get(2);
String hostAndPort = new String((byte[]) master.get(0)) + ":" + master.get(1);
tree.put((Long) list1.get(0), hostAndPort);
tree.put((Long) list1.get(1), hostAndPort);
}
}
return tree;
}