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

时间:2017-05-26 10:09:26

标签: java multithreading lettuce

我试图决定是否在多个线程中使用多个有状态连接或仅重用一个。我正在使用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 操作。我也尝试做同样的事情,但是用一把钥匙(80k 设置&#39; s为那一把钥匙+ 80k 得到&#39; s密钥,所有线程的相同密钥)。 结果始终相同,当使用多个连接(每个线程1个连接)时,我得到大约20秒的差异(95秒对115秒)。

每个线程使用一个连接时是否存在某种缺点?或者一些我不知道的不良后果,因为在我看来这将是使用这个API的首选方式。

1 个答案:

答案 0 :(得分:3)

生菜连接是线程安全的。可以跨多个线程共享单个连接。您不应共享连接的唯一例外是您使用事务(不适用于Redis群集)或阻止Redis命令(例如BLPOPBRPOP)。

Redis群集连接最多可创建

1+(n*2)

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

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

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