2013-04-22 20 views
8

Poiché Redis tenta di analizzare stringhe con numeri interi con segno a 64 bit, è una buona idea memorizzare la rappresentazione binaria del numero intero con segno a 32 bit invece delle stringhe integer di 10 bit?Modo memoria efficiente per memorizzare numero intero con segno a 32 bit in Redis

Nel nostro sistema abbiamo liste di molti ID di interi con segno a 32 bit.

I can store them like 
lpush mykey 102450 --> redis cast 102450 to 8 bytes long 

or store it like 
lpush mykey \x00\x01\x19\x32 ---> this is just 4 bytes 

risposta

17

Internamente, Redis memorizza le stringhe nel modo più efficiente. Forzare gli interi in stringhe di 10 righe effettivamente userà più memoria.

Ecco come negozi Redis Strings -

  1. interi inferiore a 10000 sono memorizzati in una memoria condivisa, e non hanno alcun spese generali di memoria. Se lo desideri, puoi aumentare questo limite modificando la costante REDIS_SHARED_INTEGERS in redis.h e ricompilando Redis.
  2. Numeri interi superiori a 10000 e all'interno di un intervallo di consumo di 8 byte.
  3. Le stringhe regolari accettano len (stringa) + 4 byte per la lunghezza + 4 byte per la marcatura dello spazio libero + 1 byte per il terminatore null + 8 byte per le spese generali malloc.

Nell'esempio che hai citato, è una domanda di 8 byte per un lungo v/s 21 byte per la stringa.

EDIT:

Quindi, se ho un insieme di numeri tutti a meno di 10.000 come fa Redis memorizza il mio set?

Dipende da quanti elementi hai.

Se nel set sono presenti meno di 512 elementi (vedere set-max-intset-entries), il set verrà memorizzato come IntSet. Un IntSet è un nome glorificato per una matrice di interi ordinati. Poiché i tuoi numeri sono inferiori a 10000, utilizzerebbero 16 bit per elemento. È (quasi) efficiente in termini di memoria come un array C.

Se si dispone di più di 512 elementi, il set diventa una HashTable. Ogni elemento dell'insieme è racchiuso in una struttura denominata robj, che ha un sovraccarico di 16 byte. La struttura robj ha un puntatore al pool condiviso di numeri interi, quindi non si paga nulla in più per il numero intero stesso. Infine, le istanze robj sono archiviate nella tabella hash e la tabella hashtable ha un overhead proporzionale alla dimensione del set.

Se si è interessati esattamente a quanta memoria un elemento consuma, eseguire redis-rdb-tools sul set di dati. Oppure puoi leggere il codice sorgente per la classe MemoryCallback, i commenti spiegano come è strutturata la memoria.

+0

Grazie per la risposta. Spiegherebbe solo un po 'di più sul pool di memoria condivisa. Quindi se ho una serie di numeri tutti meno di 10.000 come Redis memorizza il mio set? – Aresn

+0

@Aresn - Vedi gli aggiornamenti alla mia risposta. Se si memorizzano insiemi di numeri interi inferiori a 10000, Redis sarà molto efficiente in termini di memoria. –

+0

@ sripathi-krishnan non è possibile specificare quanti byte vengono utilizzati per memorizzare le chiavi stringa? "Len() + 4 + 4 + 1 + 8 byte" è applicato solo ai valori? Abbiamo bisogno di memorizzare un set di dati veramente grande di coppie string (43) => int e dobbiamo valutare il volume. Grazie comunque per le informazioni! –

1

stringhe vengono memorizzate con una lunghezza, in modo che non saranno soli 4 byte nel database - è probabilmente archiviato come 4 byte di dati + 4 byte di lunghezza + imbottitura, in modo da non guadagna nulla.

Problemi correlati