-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Commit
…3331) * Obtain multiple pipelines concurrently. high performance improvement Signed-off-by: c00603587 <[email protected]> * execute countDown regardless of whether the above program is abnormal, otherwise the await cannot be released Signed-off-by: c00603587 <[email protected]> * Update src/main/java/redis/clients/jedis/MultiNodePipelineBase.java Co-authored-by: M Sazzadul Hoque <[email protected]> * set default sync workers to 3 Signed-off-by: c00603587 <[email protected]> * remove unused import package Signed-off-by: c00603587 <[email protected]> * modify the muti node pipeline sync workers --------- Signed-off-by: c00603587 <[email protected]> Co-authored-by: c00603587 <[email protected]> Co-authored-by: M Sazzadul Hoque <[email protected]>
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,10 @@ | |
import java.util.Map; | ||
import java.util.Queue; | ||
import java.util.Set; | ||
import java.util.concurrent.CountDownLatch; | ||
import java.util.concurrent.ExecutorService; | ||
import java.util.concurrent.Executors; | ||
|
||
import org.json.JSONArray; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
@@ -40,13 +44,22 @@ public abstract class MultiNodePipelineBase implements PipelineCommands, Pipelin | |
|
||
private final Logger log = LoggerFactory.getLogger(getClass()); | ||
|
||
/** | ||
* default number of processes for sync, if you got enough cores for client | ||
* or your cluster nodes more than 3 nodes, you may increase this workers number. | ||
* suggest <= cluster nodes | ||
*/ | ||
public static volatile int MULTI_NODE_PIPELINE_SYNC_WORKERS = 3; | ||
|
||
private final Map<HostAndPort, Queue<Response<?>>> pipelinedResponses; | ||
private final Map<HostAndPort, Connection> connections; | ||
private volatile boolean syncing = false; | ||
|
||
private final CommandObjects commandObjects; | ||
private GraphCommandObjects graphCommandObjects; | ||
|
||
private final ExecutorService executorService = Executors.newFixedThreadPool(MULTI_NODE_PIPELINE_SYNC_WORKERS); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
sazzad16
Author
Collaborator
|
||
|
||
public MultiNodePipelineBase(CommandObjects commandObjects) { | ||
pipelinedResponses = new LinkedHashMap<>(); | ||
connections = new LinkedHashMap<>(); | ||
|
@@ -106,25 +119,36 @@ public final void sync() { | |
} | ||
syncing = true; | ||
|
||
CountDownLatch countDownLatch = new CountDownLatch(pipelinedResponses.size()); | ||
Iterator<Map.Entry<HostAndPort, Queue<Response<?>>>> pipelinedResponsesIterator | ||
= pipelinedResponses.entrySet().iterator(); | ||
while (pipelinedResponsesIterator.hasNext()) { | ||
Map.Entry<HostAndPort, Queue<Response<?>>> entry = pipelinedResponsesIterator.next(); | ||
HostAndPort nodeKey = entry.getKey(); | ||
Queue<Response<?>> queue = entry.getValue(); | ||
Connection connection = connections.get(nodeKey); | ||
try { | ||
List<Object> unformatted = connection.getMany(queue.size()); | ||
for (Object o : unformatted) { | ||
queue.poll().set(o); | ||
executorService.submit(() -> { | ||
try { | ||
List<Object> unformatted = connection.getMany(queue.size()); | ||
for (Object o : unformatted) { | ||
queue.poll().set(o); | ||
} | ||
} catch (JedisConnectionException jce) { | ||
log.error("Error with connection to " + nodeKey, jce); | ||
// cleanup the connection | ||
pipelinedResponsesIterator.remove(); | ||
connections.remove(nodeKey); | ||
IOUtils.closeQuietly(connection); | ||
} finally { | ||
countDownLatch.countDown(); | ||
} | ||
} catch (JedisConnectionException jce) { | ||
log.error("Error with connection to " + nodeKey, jce); | ||
// cleanup the connection | ||
pipelinedResponsesIterator.remove(); | ||
connections.remove(nodeKey); | ||
IOUtils.closeQuietly(connection); | ||
} | ||
}); | ||
} | ||
|
||
try { | ||
countDownLatch.await(); | ||
} catch (InterruptedException e) { | ||
log.error("Thread is interrupted during sync.", e); | ||
} | ||
|
||
syncing = false; | ||
|
This code is problematic for a couple of reasons:
This can be easily be reproduced by doing the following:
Running the above code will leave the process running.