Redis: strumenti di benchmark
Chiudiamo la serie di articoli dedicati al database NoSQL Redis occupandoci di benchmarking.
Il benchmarking è una pratica importante quando si tratta di analizzare le prestazioni complessive di un server e nel nostro caso di un database.
Redis benchmark
Redis disponde di uno strumento da riga di comando, "redis-benchmark", grazie al quale possiamo simulare un numero arbitrario di client che si connettono contemporaneamente a Redis ed eseguono azioni su di esso, misurando il tempo necessario per completare le richieste.
Il risultato fornirà un'idea del numero medio di richieste che il tuo server Redis è in grado di gestire al secondo.
Queste sono alcune delle sue opzioni
-n: definisce il numero di richieste da effettuare. L'impostazione di default è 100000
-c: definisce il numero di connessioni parallele (client) da simulare. L'impostazione di default è 50
-p: è la porta usata da Redis. L'impostazione di default è 6379
-h: utilizzato per definire l'host. L'impostazione di default è localhost (127.0.0.1)
-a: utilizzato per richiedere una password se il server necessita di autenticazione
-q: indica la modalità "quite" cioè silenziosa, mostra solo la media delle richieste effettuate al secondo
-d: specifica la dimensione dei dati, in byte, per le operazioni di SET (salvare un dato) e GET (recuperare un dato). L'impostazione di default è 3 byte.
-t: utilizzato per specificare e/o combinare più test. Ad esempio, puoi usare "-t get" per ottenere le informazioni sulla sola operazione di SET, mentre "-t get,set" confronta le prestazioni dei comandi GET e SET.
-P: utilizzato per il pipelining, per migliorare le prestazioni (lo vedremo tra poco)
Ad esempio, se vogliamo controllare il numero medio di richieste al secondo che il tuo server Redis locale può gestire, puoi utilizzare:
# redis-benchmark -q
ed il risultato sarà una lista di informazioni simile a questa
PING_INLINE: 92165.90 requests per second
PING_BULK: 93196.65 requests per second
SET: 92764.38 requests per second
GET: 91743.12 requests per second
INCR: 91074.68 requests per second
LPUSH: 91491.30 requests per second
RPUSH: 91491.30 requests per second
LPOP: 92678.41 requests per second
RPOP: 92506.94 requests per second
SADD: 92764.38 requests per second
HSET: 91157.70 requests per second
SPOP: 92421.44 requests per second
LPUSH (needed to benchmark LRANGE): 91157.70 requests per second
LRANGE_100 (first 100 elements): 92421.44 requests per second
LRANGE_300 (first 300 elements): 93023.25 requests per second
LRANGE_500 (first 450 elements): 92421.44 requests per second
LRANGE_600 (first 600 elements): 92936.80 requests per second
MSET (10 keys): 93984.96 requests per second
Prestiamo attenzione all'ultima riga: MSET indica che (il nostro) Redis può gestire 93984 richieste al secondo.
LPUSH, RPUSH, LPOP, RPOP, LLEN, HSET, .... sono le possibili operazioni che possiamo fare con Redis, e ce ne occuperemo nella lezione successiva in cui vedremo esempi pratici di utilizzo di Redis.
In questo secondo esempio otteniamo le medie per i soli comandi GET e SET
# redis-benchmark -t set,get -q
Il nostro risultato è il seguente: abbiamo 93109 richieste al secondo per il comando SET e 92081 richieste per il comando GET.
SET: 93109.87 requests per second
GET: 92081.03 requests per second
Come detto, di default verranno eseguite 50 connessioni parallele per creare 100.000 richieste al server Redis.
Se ad esempio desideri aumentare il numero di connessioni parallele,da 50 a 1000, per simulare un picco di utilizzo, puoi utilizzare l'opzione -c come in questo esempio
# redis-benchmark -t set,get -q -c 1000
Il risultato dovrebbe essere un calo di performance perchp il server lavora di più.
Se volessimo modificare il numero di richieste, da 100.000 (default) a 1.000.000
# redis-benchmark -t set,get -q -c 1000 -n 1000000
Se volessimo delle informazioni più dettagliate sul nostro test, rimuoviamo l'opzione -q
# redis-benchmark -t set,get -c 1000 -n 1000000
Redis Pipelining
Per impostazione predefinita ogni client invia il comando successivo solo quando viene ricevuta la risposta da Redis del comando precedente.
Redis supporta il pipelining, cioè è possibile inviare più comandi contemporaneamente senza attendere le risposte e infine leggere le risposte in un unico passaggio.
Il pipelining è in grado di migliorare notevolmente il numero di operazioni (richieste) al secondo che un server può gestire.
Tra le opzioni di benchmark ne esiste una specifica per il pipeling: "-P".
Ad esempio se vogliamo inviare simultaneamente 8 comandi a Redis:
# redis-benchmark -t get,set -q -P 8
Latenza media
Se desideri una semplice misurazione del tempo medio impiegato da una richiesta per ricevere una risposta, puoi utilizzare il client Redis per verificare la latenza media del server.
La latenza è una misura del tempo impiegato da un comando ping per ricevere una risposta dal server.
L'opzione "latency" mostrerà le statistiche di latenza in tempo reale per il tuo server Redis:
# redis-cli --latency
La risposta mostrerà, all'aumento dei "ping" (indicato con il termine "samples"), una latenza media variabile:
min: 0, max: 1, avg: 0.18 (1265 samples)
Abbiamo una latenza media di 0.18 millisecondi.
Questo comando continuerà a funzionare indefinitamente. Per interromperlo: CTRL + C.
Se invece volessimo misurare la latenza in un certo periodo di tempo utilizziamo l'opzione "latency-history"
# redis-cli --latency-history
Otterremo le latenze medie in intervalli di tempo di 15 secondi, ad esempio queste
min: 0, max: 1, avg: 0.20 (1414 samples) -- 15.00 seconds range
min: 0, max: 1, avg: 0.20 (1413 samples) -- 15.00 seconds range
min: 0, max: 1, avg: 0.21 (1414 samples) -- 15.01 seconds range
min: 0, max: 1, avg: 0.21 (1413 samples) -- 15.01 seconds range
min: 0, max: 1, avg: 0.18 (1414 samples) -- 15.00 seconds range
min: 0, max: 1, avg: 0.18 (1415 samples) -- 15.01 seconds range
................................................................
Durante i nostri PING il server non sta eseguendo operazioni, per cui non c'è molta variazione tra le latenze medie. Se invece si verificasse un picco di utilizzo, dovrebbe aversi un aumento della latenza.
Latenza intrinseca
E' possibile verificare la "latenza intrinseca" con l'opzione "intrinsic-latency": in poche parole andiamo ad escludere dalla nostra verifica tutte le cause di latenza direttamente riferibili a fattori che non siano legati a Redis, come, ad esempio, hardware e kernel.
Il seguente comando verificherà la latenza intrinseca del sistema, eseguendo un test per 30 secondi
# redis-cli --intrinsic-latency 30
Il risultato sarà
Max latency so far: 2 microseconds.
Max latency so far: 17 microseconds.
Max latency so far: 21 microseconds.
Max latency so far: 22 microseconds.
Max latency so far: 23 microseconds.
Max latency so far: 29 microseconds.
Max latency so far: 35 microseconds.
Max latency so far: 51 microseconds.
Max latency so far: 52 microseconds.
Max latency so far: 63 microseconds.
22848788 total runs (avg latency: 1.3130 microseconds / 1312.98 nanoseconds per run).
Worst run took 48x longer than the average latency.
Confrontando i dati della latenza media e di quella intrinseca possiamo identificare eventuali colli di bottiglia dell'hardware o del sistema che potrebbero influire sulle prestazioni del server Redis.
Nel nostro esempio la latenza totale per una richiesta al nostro server ha una media di 0,18 millisecondi, ed una latenza intrinseca di 1,3130 microsecondi cioè 0,001313 millisecondi (1 microsecondo = 0,001 millisecondi).