2013-12-11 11 views
6

Sto usando Redis in un'applicazione Java, dove sto leggendo i file di registro, memorizzando/recuperando alcune informazioni in Redis per ogni registro. Le chiavi sono indirizzi IP nel mio file di registro, il che significa che sono sempre le chiavi delle notizie in arrivo, anche se le stesse appaiono regolarmente.Quanto è lento il rosso quando è pieno e sfratto le chiavi? (Algoritmo LRU)

A un certo punto, Redis raggiunge la dimensione massima (3 GB nel mio caso) e inizia a rimuovere alcune chiavi. Io uso le impostazioni "allkeys-lru" perché voglio mantenere le chiavi più giovani.

L'intera applicazione rallenta molto, prendendo 5 volte più a lungo rispetto all'inizio. Quindi ho tre domande:

  • è normale avere un rallentamento così drammatico (5 volte più lungo)? Qualcuno ha avuto un tale rallentamento? In caso contrario, potrei avere un altro problema nel mio codice (improbabile come il rallentamento appare esattamente quando Redis raggiunge il limite)
  • posso migliorare la mia configurazione? Ho provato a cambiare l'impostazione di maxmemory-samples senza molto successo
  • dovrei considerare un'alternativa per il mio particolare problema? Esiste un DB in memoria in grado di gestire le chiavi di sfratto con prestazioni migliori? Potrei considerare un oggetto Java puro (HashMap ...), anche se non sembra un buon progetto.

Edit 1: usiamo 2 DB in Redis

Edit 2: Usiamo Redis 2.2.12 (Ubuntu 12.04 LTS). Ulteriori indagini hanno spiegato il problema: stiamo usando db0 e db1 in redis. db1 è usato molto meno di db0, e le chiavi sono totalmente differenti. Quando Redis raggiunge la memoria massima (e LRU algo inizia a espellere le chiavi), redis rimuove quasi tutte le chiavi db1, che rallenta drasticamente tutte le chiamate. Questo è un comportamento strano, probabilmente insolito e forse collegato alla nostra applicazione. Abbiamo risolto il problema spostandoci su un altro (migliore) meccanismo di memoria per le chiavi che sono state caricate in db1.

grazie!

risposta

8

Non sono convinto che Redis sia l'opzione migliore per il vostro caso d'uso.

Redis "LRU" è solo un algoritmo best effort (cioè piuttosto lontano da una LRU esatta). Redis tiene traccia delle allocazioni di memoria e sa quando deve liberare della memoria. Questo è controllato prima dell'esecuzione di ogni comando. Il meccanismo per rimuovere una chiave nella modalità "allkeys-lru" consiste nel scegliere i tasti casuali di campioni maxmemory, confrontando il loro tempo di inattività e selezionare la chiave più idle. Redis ripete queste operazioni finché la memoria utilizzata non si trova al di sotto di maxmemory.

I campioni maxmemory più elevati, maggiore è il consumo della CPU, ma il risultato più accurato.

A condizione che non si utilizzi esplicitamente il comando EXPIRE, non è possibile associare altro overhead allo sfratto della chiave.

Esecuzione di un test breve con riferimento Redis sulle macchina risulta in un volume di:

  • 145 Kops/s quando nessuno sgombero verifica
  • 125 Kops/s quando si ottiene il 50% sgombero (cioè 1 chiave oltre 2 è sfrattato).

Non riesco a riprodurre il fattore 5 volte riscontrato.

L'ovvia raccomandazione di ridurre l'overhead dello sfratto è di ridurre i campioni di memoria massima, ma significa anche una drastica riduzione dell'accuratezza.

Il mio suggerimento sarebbe quello di dare una prova memcached. Il meccanismo LRU è diverso. Non è ancora esatto (si applica solo su base per lastra), ma probabilmente darà risultati migliori che Redis in questo caso d'uso.

+0

Grazie Didier. Stiamo ancora esaminando il problema, ma sembra che ci sia qualcos'altro che causa questo rallentamento. In realtà usiamo 2 DB in redis e sembra che ci sia uno strano comportamento quando viene raggiunta la memoria massima. Pubblicherò maggiori dettagli quando lo avremo. Aspetterò altre possibili risposte e convaliderò la tua risposta. – Pixou

+0

@Pixou, eventuali aggiornamenti su questo? – Ashish

+3

@Ashish Di conseguenza, abbiamo scoperto che il meccanismo LRU funziona su entrambi i database, in modo che se si dispone di un database di grandi dimensioni e di uno piccolo, il piccolo viene "risucchiato" abbastanza rapidamente dall'LRU. Ad esempio, quando il campione di mamemory è 3, l'LRU sembra ricevere 2 campioni dal grande DB, 1 da quello piccolo, anche se è 10000 volte più piccolo. Quindi, di nuovo, abbiamo risolto questo problema con un solo database nella nostra istanza di redis. – Pixou

0

Quale versione di Redis stai usando? La versione 2.8 (abbastanza recente) ha migliorato l'algoritmo di scadenza e se si utilizza 2.6 si potrebbe fare un tentativo.

http://download.redis.io/redis-stable/00-RELEASENOTES

+0

È molto vero, ma tieni presente che la scadenza e lo sfratto delle chiavi sono due cose diverse. –

+0

hai perfettamente ragione –