Giải pháp 1:
Đã tìm ra giải pháp để xác định vị trí mà các phím sẽ đi vào. JedisCluster có một số API để lấy nó.
int slotNum = JedisClusterCRC16.getSlot(key);
- Cung cấp số vị trí của khóa.
Set<HostAndPort> redisClusterNode = new HashSet<HostAndPort>();
redisClusterNode.add(new HostAndPort(hostItem, port));
JedisSlotBasedConnectionHandler connHandler = new
JedisSlotBasedConnectionHandler(redisClusterNode, poolConfig, 60);
Jedis jedis = connHandler.getConnectionFromSlot(slotNum);
Điều này cung cấp đối tượng jedis (từ Jedispool nội bộ) cho nút cụ thể trong cụm.
Bây giờ với đối tượng jedis ở trên, tất cả các lệnh có thể dễ dàng xoay vòng cho nút cụ thể (trong cụm)
Pipeline pipeline = jedis.pipelined();
pipeline.multi();
for(Entry<String, Map<String, String>> kvf : kvfs.entrySet()) {
pipeline.hmset(kvf.getKey(), kvf.getValue());
}
pipeline.exec();
Mặc dù cách tiếp cận này (với JedisCluster) đã đưa ra nút thích hợp mà các khóa đi đến điều này không mang lại cho tôi hiệu suất như mong đợi, tôi nghĩ đó là do thủ tục liên quan đến việc biết số vị trí và nút (của vị trí).
Thủ tục trên dường như thiết lập một kết nối vật lý đến nút (trong cụm) mỗi khi chúng ta cố gắng lấy nút thực (jedis) có chứa số vị trí. Vì vậy, điều này cản trở hiệu suất trong trường hợp chúng tôi có hàng triệu khóa.
Vì vậy, một cách tiếp cận khác (bên dưới) bằng cách sử dụng gói Diếp cá đã giúp tôi giải quyết vấn đề này.
Giải pháp 2:
Gói Diếp cá được sử dụng hỗ trợ gửi hàng loạt lệnh ở chế độ cụm.
<groupId>biz.paluch.redis</groupId>
<artifactId>lettuce</artifactId>
<version>4.4.3.Final</version>
Đoạn mã:
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()]));
Tham khảo:https://github.com/lettuce-io/lettuce-core/wiki/Pipelining-and-command-flushing