我试图决定是在多个线程之间使用多个有状态连接,还是只重用一个线程。我在用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 设置操作,对这些相同密钥执行超过80k get操作。我也试着做同样的事情,但是用一个键(80k 设置‘s表示那个键+ 80k get 's表示相同的键,相同的键用于所有线程)。结果总是一样的,当使用多个连接(每个线程一个连接)时,我得到大约20秒的差异(95秒vs11秒)。
当每个线程使用一个连接时,是否存在某种缺陷?或者一些我不知道的意外后果,因为在我看来,这将是使用此API的首选方式。
发布于 2017-05-26 10:26:03
生菜连接是线程安全的.可以在多个线程之间共享单个连接。唯一不应该共享连接的例外情况是使用事务(不适用于Redis集群)或阻塞Redis命令(如BLPOP、BRPOP)。
Redis群集连接创建的

永久的TCP连接,其中n是Redis群集节点的数量。
如果您有一个小集群和每个应用程序实例的合理线程数,则可以应用每个线程模式的连接。如果您的集群/application比例达到了一个不合理的连接数量,那么您可能被迫在每个应用程序实例中使用一个连接。
通常,使用单个连接需要较少的资源。默认的管道操作模式在调用命令时立即从调用线程中发送命令--连接不会等到前面的命令完成后再执行。
https://stackoverflow.com/questions/44198897
复制相似问题