2017-05-26 3 views
1

Ich versuche zu entscheiden, ob mehrere statusbehaftete Verbindungen über mehrere Threads hinweg verwendet werden oder nur eine wiederverwendet werden soll. Ich benutze Java.RedisClusterClient, eine Verbindung oder eine Verbindung pro Thread

Obwohl für StatefulRedisClusterConnectionImpl angegeben wird, dass die Verbindung zu einem Redis-Cluster threadsicher ist und mehrere Threads gemeinsam einen Thread verwenden, erziele ich bessere Leistungsergebnisse, wenn eine Verbindung pro Thread verwendet wird.

Dies ist mein Code Testcode:

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 erstreckt Thread.
Ich wechselte zwischen cmd, wo ich Verbindung für alle Threads wiederverwenden und cmdLIst verwenden, wo jede Verbindung ihre eigene Verbindung verwendet. Mein Setup ist 4 Master auf 4 remote (Code läuft nicht auf demselben Rechner wie Redis Cluster) Maschinen (+ Slaves).
Jeder Thread führt 80k Set Operationen für zufällige Schlüssel und als 80k erhalten Operationen für diese gleichen Schlüssel. Auch ich habe versucht, das gleiche zu tun, aber mit 1 Schlüssel (80k gesetzt 's für den einen Schlüssel + 80k bekommen' s für den gleichen Schlüssel, der gleiche Schlüssel für alle Threads). Ergebnis ist immer das gleiche, wenn ich mehrere Verbindungen benutze (1 Verbindung pro Thread), bekomme ich einen Unterschied von ca. 20 Sekunden (95 Sek. Vs 115 Sek.).

Gibt es einen Nachteil bei der Verwendung einer Verbindung pro Thread? Oder einige unerwünschte Folgen, die mir nicht bewusst sind, weil es mir scheint, dass dies die bevorzugte Art der Verwendung dieser API sein wird.

Antwort

2

Salatverbindungen sind fadensicher. Eine einzelne Verbindung kann über mehrere Threads hinweg gemeinsam genutzt werden. Die einzige Ausnahme, bei der Sie keine Verbindung freigeben sollten, ist die Verwendung von Transaktionen (nicht für Redis Cluster anwendbar) oder das Blockieren von Redis-Befehlen (z. B. BLPOP, BRPOP).

A Redis Clusterverbindung schafft zur

1+(n*2)

permanenten TCP-Verbindungen auf, wo n ist die Anzahl der Redis Cluster-Knoten.

Wenn Sie einen kleinen Cluster und eine angemessene Anzahl von Threads pro Anwendungsinstanz haben, können Sie die Verbindung pro Threadmuster anwenden. Wenn der Cluster/Anwendungsumfang eine Größe erreicht, bei der Sie eine unangemessen hohe Anzahl an Verbindungen erhalten, müssen Sie möglicherweise eine Verbindung pro App-Instanz verwenden.

Im Allgemeinen erfordert die Verwendung einer einzelnen Verbindung weniger Ressourcen. Der Standard-Pipelining-Betriebsmodus sendet Befehle vom Aufrufen von Threads, sobald der Befehl aufgerufen wird - die Verbindung wartet nicht, bis ein vorheriger Befehl beendet ist.

+0

Was halten Sie für einen "kleinen Cluster"? Wir haben 4 Maschinen mit dieser Konfiguration: 1: (M1 S2 S3 S4), 2: (M2 S1 S3 S4), 3: (M3), 4: (M4). Das sind 10 Rediserknotenknoten, die 21 TCP-Verbindungen nach Ihrer Formel bedeuten. –

+1

Klein und groß hängt hauptsächlich von der Wahrnehmung und Ressourcenverfügbarkeit ab. In Ihrem Cluster erstellt jede Redis Cluster-Verbindung bis zu 21 TCP-Verbindungen. Wenn Sie 10 gleichzeitige Threads mit einer threadgebundenen Verbindung haben, bei denen es sich um 210 TCP-Verbindungen in einer einzelnen JVM handelt.Wenn Sie dann 10 Anwendungsinstanzen ausführen, erhalten Sie insgesamt 2100 Verbindungen, was zu etwa 200 bis 210 TCP-Verbindungen auf jedem Redis-Clusterknoten führt. – mp911de

Verwandte Themen