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

时间:2021-09-05 00:36:21

I'm trying to decide whether or not to use multiple stateful connections across more than one thread or only reuse one. I'm using java.

我正在尝试决定是否在多个线程中使用多个有状态连接或仅重用一个。我正在使用java。

Even though it says for StatefulRedisClusterConnectionImpl that the connection is thread-safe to a Redis Cluster and that multiple threads may share one, I am getting better performance results when using one connection per thread.

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

This is my code testing code:

这是我的代码测试代码:

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 extends Thread.
I was shifting between using cmd where I reuse connection for all threads and using cmdLIst where every connection uses it's own connection. My setup is 4 masters on 4 remote (code is not running on the same machine as redis cluster) machines (+ slaves).
Every thread performs 80k set operations for random keys and than 80k get operations for these same keys. Also I tried to do that same thing, but with 1 key (80k set's for that one key + 80k get's for that same key, same key for all threads). Result is always the same, when using multiple connections (1 connection per thread), I get around 20 second difference (95 sec vs 115 sec).

InsertClass扩展了Thread。我正在使用cmd在我重用所有线程的连接和使用cmdLIst之间切换,其中每个连接使用它自己的连接。我的设置是4个遥控器上的4个主站(代码与redis群集在同一台机器上运行)机器(+从站)。每个线程对随机密钥执行80k设置操作,而对于这些相同的密钥,每个线程执行80k操作。此外,我尝试做同样的事情,但是有一把钥匙(一把钥匙为80k套装,同一把钥匙为80k,同一根钥匙为同一把钥匙)。结果总是相同的,当使用多个连接(每个线程1个连接)时,我得到大约20秒的差异(95秒对115秒)。

Is there some kind of drawback when using one connection per thread? Or some undesired consequences that I am not aware of, because it seems to me that this will be preferred way of using this API.

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

1 个解决方案

#1


2  

Lettuce connections are thread-safe. A single connection can be shared across multiple threads. The only exceptions where you should not share a connection is when you're using transactions (not applicable for Redis Cluster) or blocking Redis commands (such as BLPOP, BRPOP).

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

A Redis cluster connection creates up to

Redis群集连接最多可创建

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

permanent TCP connections where n is the number of Redis Cluster nodes.

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

If you have a small cluster and a reasonable number of threads per application instance, you can apply the connection per thread pattern. If your cluster /application scale reaches a size at which you get an unreasonable number of connections, then you might be forced to use a connection per app instance.

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

In general, using a single connection involves fewer resources. The default pipelining operation mode sends commands from invoking threads as soon as the command is invoked – the connection does not wait until a previous command is finished.

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

#1


2  

Lettuce connections are thread-safe. A single connection can be shared across multiple threads. The only exceptions where you should not share a connection is when you're using transactions (not applicable for Redis Cluster) or blocking Redis commands (such as BLPOP, BRPOP).

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

A Redis cluster connection creates up to

Redis群集连接最多可创建

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

permanent TCP connections where n is the number of Redis Cluster nodes.

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

If you have a small cluster and a reasonable number of threads per application instance, you can apply the connection per thread pattern. If your cluster /application scale reaches a size at which you get an unreasonable number of connections, then you might be forced to use a connection per app instance.

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

In general, using a single connection involves fewer resources. The default pipelining operation mode sends commands from invoking threads as soon as the command is invoked – the connection does not wait until a previous command is finished.

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