Twemproxy (schiaccianoci) Degradazione delle prestazioni con .NET ServiceStack.redis Client
-
21-12-2019 - |
Domanda
Setup Redis e schiaccianoci su Centos 6.4.e cercando di connettersi utilizzando il client ServiceStack.redis.Trovato importante problema di prestazione.
Per il test a sinistra solo 1 istanza di Redis
beta:
listen: 0.0.0.0:22122
hash: fnv1a_64
distribution: ketama
auto_eject_hosts: true
#timeout: 5000
#server_retry_timeout: 2000
#server_failure_limit: 3
redis: true
servers:
#- 127.0.0.1:6379:1
- 127.0.0.1:6380:1
.
Nel test dell'unità seguente sto cercando di inviare corde di 100k a Redis tramite Schiaccianoci.
[TestClass]
public class RedisProxyTest
{
public string host = "192.168.56.112";
//public int port = 6379;
public int port = 22122;
[TestMethod]
public void TestMethod1()
{
var key = "l2";
var count = 100000;
using (var redisClient = new RedisClient(host, port))
{
var list = new List<string>();
for (int i = 0; i < count; i++)
{
list.Add(Guid.NewGuid().ToString());
}
Utils.TimeLog("Remove", () => redisClient.Remove(key));
Utils.TimeLog("AddRangeToList", () => redisClient.AddRangeToList(key, list));
}
using (var redisClient = new RedisClient(host, port))
{
redisClient.GetListCount(key);
Utils.TimeLog("GetRangeFromList", () =>
{
var ret = redisClient.GetRangeFromList(key, count / 2, count - 1);
Console.WriteLine(ret.Count);
});
}
}
}
.
In prime poche corse dopo che la schiacciantatore riavviato addrengetolist funziona con 1-2 sec.Ma con le successive esecuzioni di addrangetolist performance diminuisce significativamente da pochi minuti anche più di 20 minuti (se non è stato configurato il timeout).Non riesco a riprodurmi lo stesso quando usi direttamente Redis.Non ho ancora provato ancora nessun altro cliente.Qualche idea Perché?
Quello che vedo in console dopo il test dell'unità:
Test Name: TestMethod1
Test Outcome: Passed
Remove: 0.0331171
AddRangeToList: 806.8219166
50000
GetRangeFromList: 1.741737
. Soluzione
Se la schiaccianoci è proxing diverse decine di migliaia di connessioni o invio di una richiesta Multi-Get con diverse migliaia di chiavi, è necessario utilizzare le dimensioni MBUF di 512
Il seguente collegamento parla su come interpretare le dimensioni MBUF? - https://github.com/twitter/twemproxy/issues/141 .
Ogni connessione client consuma almeno un MBUF. Per servire una richiesta abbiamo bisogno di due connessioni (una dal client al proxy e nell'altro dal proxy al server). Quindi avremmo bisogno di due mbufs.
Una richiesta frammentabile come 'Ottieni foo bar \ r \ n', che BTW si fa frammentare per "ottenere foo \ r \ n" e 'get bar \ r \ n' consumerà due mbuf per la richiesta e due mbuf per la risposta . Quindi una richiesta frammentabile con N Frammenti ha bisogno di N * 2 MBUFS
La cosa buona di MBUF è che la memoria proviene da un pool di riutilizzo. Una volta assegnato un MBUF, non è mai stato liberato ma appena rimesso nella piscina del riutilizzo. La cosa cattiva è che una volta che Mbuf è assegnata non è mai liberato, dal momento che un MBUF ha liberato sempre alla piscina del riutilizzo - https://github.com/twitter/twemproxy/blob/master/src/nc_mbuf.c#l23-L24 (questo può essere risolto mettendo a Parametro soglia sul pool di riutilizzo)
Quindi, se la schiacciatori sta maneggiando le connessioni client 1K e 100 connessioni del server, consumare (massimo (1000, 100) * 2 * MBUF-dimensione della dimensione) per MBUF. Se presupponiamo che i client stia inviando una richiesta non pipel-lined, quindi con la dimensione MBUF predefinita di 16K questo in totale consumano 32 m.
Inoltre, se in media ogni richiesta ha 10 frammenti, il consumo di memoria sarebbe di 320m. Invece di gestire connessioni client 1K, diciamo che stavi maneggiando 10k, il consumo di memoria sarebbe 3.2g. Ora invece di utilizzare una dimensione MBUF predefinita di 16k, hai utilizzato 512 byte, quindi il consumo di memoria per lo stesso scenario caderebbe a 1000 * 2 * 512 * 10= 10m
Questo è il motivo per cui per "numero elevato" di connessione che si desidera scegliere un piccolo valore per MBUF-dimensione come 512
Altri suggerimenti
Sembra che il problema sia correlato all'utilizzo di memoria elevata durante il trasferimento di tale quantità di dati.
di default SHUTACLACKER ALLOCA Dimensioni tampone 16K per ogni tasto.Nel mio caso sarà