Bene questo è previsto per una memorizzazione efficiente dei dati: le parole devono essere indicizzate in memoria in una struttura dati dinamica di celle collegate da puntatori. La dimensione dei metadati della struttura, dei puntatori e della frammentazione interna degli allocatori di memoria è la ragione per cui i dati richiedono molta più memoria di un file flat corrispondente.
Un set Redis è implementato come tabella hash. Questo include:
- un array di puntatori crescente geometricamente (potenze di due)
- una seconda matrice può essere necessaria quando rimaneggiamento incrementale è attiva
- celle dell'elenco singole-linked rappresentano le voci nella tabella hash (3 puntatori, 24 byte per voce)
- involucri oggetto Redis (uno per valore) (16 byte per voce)
- stessi dati reali (ognuno preceduto da 8 byte per dimensioni e portata)
01.235.164,106 mila
Tutte le dimensioni sopra indicate sono fornite per l'implementazione a 64 bit. Contabilizzando il sovraccarico dell'alloggiamento di memoria, risulta che Redis richiede almeno 64 byte per elemento impostato (in cima ai dati) per una versione recente di Redis utilizzando l'allocatore jemalloc (> = 2.4)
Redis fornisce memory optimizations per alcuni tipi di dati, ma non coprono set di stringhe. Se hai davvero bisogno di ottimizzare il consumo di memoria dei set, ci sono trucchi che puoi usare comunque. Non lo farei per soli 160 MB di RAM, ma se dovessi avere dati più grandi, ecco cosa puoi fare.
Se non sono necessarie le funzionalità unione, intersezione, differenza degli insiemi, è possibile memorizzare le parole in oggetti hash. Il vantaggio è che gli oggetti hash possono essere ottimizzati automaticamente da Redis usando zipmap se sono abbastanza piccoli. Il meccanismo zipmap è stato sostituito da ziplist in Redis> = 2.6, ma l'idea è la stessa: utilizzare una struttura di dati serializzata che può adattarsi alla cache della CPU per ottenere sia le prestazioni che un footprint di memoria compatto.
Per garantire che gli oggetti di hash siano sufficientemente piccoli, i dati potrebbero essere distribuiti secondo un meccanismo di hashing.Se c'è bisogno per memorizzare gli oggetti 1M, l'aggiunta di una parola potrebbe essere attuato nel modo seguente:
- hash modulo 10000 (fatto sul lato client)
- parole HMSET: [hashnum] [parola] 1
invece di memorizzare:
words => set{ hi, hello, greetings, howdy, bonjour, salut, ... }
è possibile memorizzare:
words:H1 => map{ hi:1, greetings:1, bonjour:1, ... }
words:H2 => map{ hello:1, howdy:1, salut:1, ... }
...
Per recuperare o verificare l'esistenza di una parola, è la stessa (cancellarla e utilizzare HGET o HESISTS).
Con questa strategia, significativo risparmio di memoria può essere fatto disponibile il modulo di hash è scelto in base alla configurazione zipmap (o ZipList per Redis> = 2.6):
# Hashes are encoded in a special way (much more memory efficient) when they
# have at max a given number of elements, and the biggest element does not
# exceed a given threshold. You can configure this limits with the following
# configuration directives.
hash-max-zipmap-entries 512
hash-max-zipmap-value 64
Attenzione: il nome questi parametri sono cambiati con Redis> = 2.6.
Qui, modulo 10000 per articoli 1M significa 100 articoli per oggetti hash, che garantiranno che tutti siano memorizzati come zipmap/elenchi di zip.
Risposta affascinante e dettagliata; Non lo sapevo. Grazie a @Didier! –
Va bene grazie mille sono abbastanza positivo che questo risolverà i miei problemi. E sì per 160mb è una multa, ma mi aspetto di lavorare con un massimo di 1gb di dati di parole semplici e non voglio che questo picco a 10 GB. Grazie ancora, apprezza la risposta dettagliata. – cwoebker
@Didier - Ottima risposta! Un paio di correzioni anche se a) Le voci di Hashtable sono una singola lista collegata, non doppia, l'overhead di 24 byte è corretta anche se b) Il wrapper degli oggetti di Redis non si applica a ciascuna voce di set/hash. Si applica solo alla coppia chiave/valore di livello superiore, in modo che l'overhead sia costante c) Si potrebbe voler indicare che zipmap è deprecato in 2.6/unstable e che la lista zip fa la cosa equivalente. –