Solution 1 :
Trouvé une solution pour identifier l'emplacement dans lequel les clés iraient. JedisCluster a quelques API pour l'obtenir.
int slotNum = JedisClusterCRC16.getSlot(key);
- Fournit le numéro d'emplacement de la clé.
Set<HostAndPort> redisClusterNode = new HashSet<HostAndPort>();
redisClusterNode.add(new HostAndPort(hostItem, port));
JedisSlotBasedConnectionHandler connHandler = new
JedisSlotBasedConnectionHandler(redisClusterNode, poolConfig, 60);
Jedis jedis = connHandler.getConnectionFromSlot(slotNum);
Cela fournit l'objet jedis (depuis Jedispool en interne) pour le nœud spécifique du cluster.
Maintenant, avec l'objet jedis ci-dessus, toutes les commandes peuvent être facilement canalisées pour le nœud spécifique (dans le cluster)
Pipeline pipeline = jedis.pipelined();
pipeline.multi();
for(Entry<String, Map<String, String>> kvf : kvfs.entrySet()) {
pipeline.hmset(kvf.getKey(), kvf.getValue());
}
pipeline.exec();
Bien que cette approche (avec JedisCluster) ait donné le nœud approprié auquel les clés vont, cela ne m'a pas fourni les performances attendues, je pense que cela est dû à la procédure impliquée pour connaître le numéro de slot et le nœud (du slot).
La procédure ci-dessus semble établir une connexion physique au nœud (en cluster) chaque fois que nous essayons d'obtenir le nœud réel (jedis) qui contient le numéro d'emplacement. Donc, cela entrave les performances au cas où nous aurions des millions de clés.
Ainsi, une autre approche (ci-dessous) utilisant le package Lettuce m'a aidé à surmonter cela.
Solution 2 :
Package Lettuce utilisé qui prend en charge l'envoi de lots de commandes en mode cluster.
<groupId>biz.paluch.redis</groupId>
<artifactId>lettuce</artifactId>
<version>4.4.3.Final</version>
Extrait de code :
RedisClusterClient client = RedisClusterClient.create(RedisURI.create("hostname", "port"));
StatefulRedisClusterConnection<String, String> connection = client.connect();
RedisAdvancedClusterAsyncCommands<String, String> commands = connection.async();
// Disabling auto-flushing
commands.setAutoFlushCommands(false);
List<RedisFuture<?>> futures = new ArrayList<>();
// kvf is of type Map<String, Map<String, String>>
for (Entry<> e : kvf.entrySet())
{
futures.add(commands.hmset( (String) e.getKey(), (Map<String, String>) e.getValue()));
}
// write all commands to the transport layer
commands.flushCommands();
// synchronization example: Wait until all futures complete
LettuceFutures.awaitAll(10, TimeUnit.SECONDS,
futures.toArray(new RedisFuture[futures.size()]));
Réf :https://github.com/lettuce-io/lettuce-core/wiki/Pipelining-and-command-flushing