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
.

È stato utile?

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à 16k * 100000= 1,5 GB .Ho visto circa 2 GB di picco durante la guardia del processo di schiaccianoci.Il mio centesimo OS VM è stato sovraccarico e non c'era abbastanza memoria per gestire quel picco.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top