RedisClusterClient,一连接或一线程一连接

RedisClusterClient, one connection or one connection per thread

我正在尝试决定是跨多个线程使用多个有状态连接还是只重用一个。我正在使用 java.

尽管它说 StatefulRedisClusterConnectionImpl 连接对 Redis 集群是线程安全的,并且多个线程可以共享一个,但当每个线程使用一个连接时,我获得了更好的性能结果。

这是我的代码测试代码:

final int THREADS = 5;
List<RedisAdvancedClusterCommands<String, String>> cmdLIst = new LinkedList<>();
for (int j = 0; j < THREADS; j++) {
    cmdLIst.add(redisClient.connect().sync());
}
RedisAdvancedClusterCommands<String, String> cmd = redisClient.connect().sync();
HashMap<Integer, List<String>> keysPerNode = new HashMap<>();
for (int i = 0; i < THREADS; i++) {

    List<String> keys = generateKeys();
    keysPerNode.put(i, keys);
    Thread insertThread = new InsertClass(cmd, keys, startLatch, endLatch);
    //Thread insertThread = new InsertClass(cmdLIst.get(i), keys, startLatch, endLatch);
    insertThread.setName("Insert thread(" + i + ")");

    insertThread.start();
}

Thread.sleep(5000);

for (int j = 0; j < THREADS; j++) {
    startLatch.countDown();
}

long start = System.currentTimeMillis();
endLatch.await();
printElapsed((System.currentTimeMillis() - start) / 1000);
cmdLIst.forEach(RedisClusterCommands::close);
cmd.close();

InsertClass 扩展 Thread.
我在使用 cmd 和使用 cmdLIst 之间转换,其中我为所有线程重用连接,每个连接都使用它自己的连接。 我的设置是 4 个远程主机上的 4 个主机(代码不是 运行 在与 redis 集群相同的机器上)机器(+ 奴隶)。
每个线程对随机键执行 80k set 操作,对这些相同的键执行 80k get 操作。我也尝试做同样的事情,但是使用 1 个键(80k set 用于该键 + 80k get 用于相同键,所有线程都使用相同的键)。 结果总是一样的,当使用多个连接时(每个线程 1 个连接),我得到大约 20 秒的差异(95 秒对 115 秒)。

每个线程使用一个连接有什么缺点吗?或者一些我不知道的不良后果,因为在我看来,这将是使用此 API.

的首选方式

生菜连接 thread-safe。单个连接可以在多个线程之间共享。您不应该共享连接的唯一例外是当您使用事务(不适用于 Redis 集群)或阻止 Redis 命令(例如 BLPOPBRPOP)时。

一个 Redis 集群连接最多创建

1+(n*2)

永久 TCP 连接,其中 n 是 Redis 集群节点的数量。

如果您有一个小型集群并且每个应用程序实例有合理数量的线程,您可以应用每个线程连接模式。如果您的集群/应用程序规模达到您获得不合理数量的连接的大小,那么您可能被迫为每个应用程序实例使用一个连接。

通常,使用单个连接涉及的资源较少。一旦命令被调用,默认的流水线操作模式就会从调用线程发送命令——连接不会等到上一个命令完成。