Løsning 1:
Fundet en løsning til at identificere det slot, som nøglerne skal gå ind i. JedisCluster har nogle API'er til at få det.
int slotNum = JedisClusterCRC16.getSlot(key);
- Giver nøglens slotnummer.
Set<HostAndPort> redisClusterNode = new HashSet<HostAndPort>();
redisClusterNode.add(new HostAndPort(hostItem, port));
JedisSlotBasedConnectionHandler connHandler = new
JedisSlotBasedConnectionHandler(redisClusterNode, poolConfig, 60);
Jedis jedis = connHandler.getConnectionFromSlot(slotNum);
Dette giver jedis-objektet (fra Jedispool internt) for den specifikke node i klyngen.
Nu med ovenstående jedis-objekt kan alle kommandoer nemt pipelineres til den specifikke node (i klyngen)
Pipeline pipeline = jedis.pipelined();
pipeline.multi();
for(Entry<String, Map<String, String>> kvf : kvfs.entrySet()) {
pipeline.hmset(kvf.getKey(), kvf.getValue());
}
pipeline.exec();
På trods af at denne tilgang (med JedisCluster) gav den passende node, som nøglerne går til, gav dette mig ikke den forventede ydeevne, tror jeg, det skyldes den procedure, der er involveret i at kende slotnummer og node (af slot).
Ovenstående procedure ser ud til at etablere en fysisk forbindelse til noden (i klyngen) hver gang vi forsøger at få den faktiske node (jedis), der indeholder slotnummeret. Så dette hæmmer ydeevnen, hvis vi har millioner af nøgler.
Så en anden tilgang (nedenfor) ved at bruge salatpakken hjalp mig med at overkomme dette.
Løsning 2:
Brugt salatpakke, der understøtter afsendelse af batch af kommandoer i klyngetilstand.
<groupId>biz.paluch.redis</groupId>
<artifactId>lettuce</artifactId>
<version>4.4.3.Final</version>
Kodestykke:
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()]));
Ref:https://github.com/lettuce-io/lettuce-core/wiki/Pipelining-and-command-flushing