我试图决定是否在多个线程中使用多个有状态连接或仅重用一个。我正在使用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的首选方式。
答案 0 :(得分:3)
生菜连接是线程安全的。可以跨多个线程共享单个连接。您不应共享连接的唯一例外是您使用事务(不适用于Redis群集)或阻止Redis命令(例如BLPOP
,BRPOP
)。
Redis群集连接最多可创建
永久TCP连接,其中n
是Redis群集节点的数量。
如果每个应用程序实例都有一个小型集群和合理数量的线程,则可以为每个线程模式应用连接。如果您的群集/应用程序规模达到了获得不合理数量连接的大小,那么您可能会被迫使用每个应用程序实例的连接。
通常,使用单个连接涉及的资源更少。一旦调用该命令,默认的流水线操作模式就会从调用线程发送命令 - 连接不会等到上一个命令完成。