Redis
 sql >> Database >  >> NoSQL >> Redis

Quali sono le strutture dati sottostanti utilizzate per Redis?

Proverò a rispondere alla tua domanda, ma inizierò con qualcosa che all'inizio potrebbe sembrare strano:se non sei interessato agli interni di Redis non dovrebbe interessarti su come i tipi di dati vengono implementati internamente. Questo per un semplice motivo:per ogni operazione Redis troverai la complessità temporale nella documentazione e, se hai l'insieme delle operazioni e la complessità temporale, l'unica altra cosa di cui hai bisogno è qualche indizio sull'utilizzo della memoria (e perché facciamo molte ottimizzazioni che possono variare a seconda dei dati, il modo migliore per ottenere queste ultime cifre è fare alcuni banali test nel mondo reale).

Ma poiché l'hai chiesto, ecco l'implementazione sottostante di ogni tipo di dati Redis.

  • Corde sono implementati utilizzando una libreria di stringhe dinamiche C in modo da non pagare (in modo asintotico) le allocazioni nelle operazioni di accodamento. In questo modo abbiamo O(N) appendici, per esempio, invece di avere un comportamento quadratico.
  • Elenchi sono implementati con elenchi collegati.
  • Set e Hash sono implementati con tabelle hash.
  • Insiemi ordinati sono implementati con skip list (un particolare tipo di alberi bilanciati).

Ma quando elenchi, insiemi e insiemi ordinati sono piccoli per numero di elementi e dimensioni dei valori più grandi, viene utilizzata una codifica diversa e molto più compatta. Questa codifica differisce per i diversi tipi, ma ha la caratteristica di essere un blob compatto di dati che spesso forza una scansione O(N) per ogni operazione. Poiché utilizziamo questo formato solo per piccoli oggetti, questo non è un problema; la scansione di un piccolo BLOB O(N) è cache ignara quindi in pratica è molto veloce, e quando ci sono troppi elementi la codifica passa automaticamente alla codifica nativa (lista collegata, hash e così via).

Ma la tua domanda non riguardava solo gli interni, il tuo punto era Che tipo usare per ottenere cosa? .

Stringhe

Questo è il tipo base di tutti i tipi. È uno dei quattro tipi ma è anche il tipo base dei tipi complessi, perché un List è un elenco di stringhe, un Set è un insieme di stringhe e così via.

Una stringa Redis è una buona idea in tutti gli scenari ovvi in ​​cui si desidera memorizzare una pagina HTML, ma anche quando si desidera evitare di convertire i dati già codificati. Quindi, ad esempio, se hai JSON o MessagePack puoi semplicemente archiviare oggetti come stringhe. In Redis 2.6 puoi persino manipolare questo tipo di oggetti lato server usando gli script Lua.

Un altro uso interessante delle stringhe sono le bitmap e, in generale, gli array di byte ad accesso casuale, poiché Redis esporta i comandi per accedere a intervalli casuali di byte o anche a singoli bit. Ad esempio, controlla questo buon post sul blog:Metriche in tempo reale Fast Easy utilizzando Redis.

Elenchi

Gli elenchi sono utili quando è probabile che tocchi solo gli estremi dell'elenco:vicino alla coda o vicino alla testa. Gli elenchi non sono molto utili per impaginare le cose, perché l'accesso casuale è lento, O (N). Quindi i buoni usi degli elenchi sono code e stack semplici o l'elaborazione di elementi in un ciclo utilizzando RPOPLPUSH con la stessa origine e destinazione per "ruotare" un anello di articoli.

Gli elenchi sono utili anche quando vogliamo creare una raccolta limitata di N elementi dove solitamente accediamo solo agli elementi in alto o in basso, o quando N è piccolo.

Set

I set sono una raccolta di dati non ordinata, quindi sono utili ogni volta che si dispone di una raccolta di articoli ed è molto importante verificare l'esistenza o le dimensioni della raccolta in un modo molto veloce. Un'altra cosa interessante dei set è il supporto per sbirciare o far scoppiare elementi casuali (comandi SRANDMEMBER e SPOP).

I set sono utili anche per rappresentare relazioni, ad esempio "Cosa sono gli amici dell'utente X?" e così via. Ma altre buone strutture di dati per questo tipo di cose sono gli insiemi ordinati, come vedremo.

I set supportano operazioni complesse come intersezioni, unioni e così via, quindi questa è una buona struttura di dati per l'utilizzo di Redis in modo "computazionale", quando si dispone di dati e si desidera eseguire trasformazioni su tali dati per ottenere un output.

I piccoli set sono codificati in modo molto efficiente.

Hash

Gli hash sono la struttura dati perfetta per rappresentare oggetti, composti da campi e valori. I campi di hash possono anche essere incrementati atomicamente usando HINCRBY. Quando hai oggetti come utenti, post di blog o qualche altro tipo di elemento , gli hash sono probabilmente la strada da percorrere se non vuoi usare la tua codifica come JSON o simili.

Tuttavia, tieni presente che i piccoli hash sono codificati in modo molto efficiente da Redis e puoi chiedere a Redis di OTTENERE, IMPOSTARE atomicamente o incrementare i singoli campi in modo molto veloce.

Gli hash possono essere utilizzati anche per rappresentare strutture di dati collegate, utilizzando riferimenti. Ad esempio, controlla l'implementazione dei commenti di lamernews.com.

Set ordinati

Gli insiemi ordinati sono le unica altra struttura di dati, oltre agli elenchi, per mantenere gli elementi ordinati . Puoi fare una serie di cose interessanti con i set ordinati. Ad esempio, puoi avere tutti i tipi di Top Something elenchi nella tua applicazione web. Utenti migliori per punteggio, post migliori per visualizzazioni di pagina, qualsiasi cosa, ma una singola istanza Redis supporterà tonnellate di operazioni di inserimento e get-top-elements al secondo.

Gli insiemi ordinati, come gli insiemi regolari, possono essere usati per descrivere le relazioni, ma consentono anche di impaginare l'elenco degli elementi e di ricordare l'ordinamento. Ad esempio, se ricordo gli amici dell'utente X con un set ordinato, posso ricordarli facilmente in ordine di amicizia accettata.

I set ordinati vanno bene per le code prioritarie.

I set ordinati sono come elenchi più potenti in cui inserire, rimuovere o ottenere intervalli dal centro dell'elenco è sempre veloce. Ma usano più memoria e sono strutture dati O(log(N)).

Conclusione

Spero di aver fornito alcune informazioni in questo post, ma è molto meglio scaricare il codice sorgente di lamernews da http://github.com/antirez/lamernews e capire come funziona. Molte strutture di dati di Redis vengono utilizzate all'interno di Lamer News e ci sono molti indizi su cosa utilizzare per risolvere un determinato compito.

Scusate gli errori di battitura grammaticale, qui è mezzanotte e sono troppo stanco per rivedere il post;)