2009-07-14 7 views
15

Memcached ha limitazioni di lunghezza per le chiavi (250?) E valori (1 MB premuroso), nonché alcune (a mia conoscenza) restrizioni di caratteri non ben definite per le chiavi. Qual è il modo migliore per aggirare quelli secondo te? Io uso il Perl API Cache :: Memcached.Come aggirare i limiti di chiave/valore di memcached?

Quello che faccio è attualmente memorizzare una stringa speciale per il valore della chiave principale se il valore originale era troppo grande ("parti: < numero>") e in tal caso, io memorizzare < numero> parti con chiavi denominate 1+ < chiave principale>, 2+ < chiave principale> ecc. Questo sembra "OK" (ma disordinato) per alcuni casi, non così buono per gli altri e ha il problema intrinseco che alcune parti potrebbero mancare in qualsiasi momento (così lo spazio è sprecato per mantenere gli altri e il tempo è sprecato per leggerli).

Per quanto riguarda le limitazioni chiave, si potrebbe probabilmente implementare l'hashing e memorizzare la chiave intera (per aggirare le collisioni) nel valore, ma non ho ancora avuto bisogno di farlo.

Qualcuno ha escogitato un modo più elegante o addirittura un'API Perl che gestisce in modo trasparente le dimensioni (ei valori chiave) dei dati arbitrari? Qualcuno ha hackerato il server memcached per supportare chiavi/valori arbitrari?

risposta

20

Il server non già consente di specificare qualsiasi dimensione che si desidera:

-I   Override the size of each slab page. Adjusts max item size 
       (default: 1mb, min: 1k, max: 128m) 

Tuttavia, la maggior parte del tempo, quando le persone sono desiderosi di memorizzare nella cache oggetti più grandi, che stanno facendo qualcosa di sbagliato. Hai davvero bisogno di così tanti dati nella chiave di cache una? Non compresso?

Se si dispone di attività sufficientemente grandi, il vantaggio dell'accesso a bassa latenza è ridotto al minimo dal tempo necessario per il trasferimento dei dati. Oppure scopri che buttare tutto nella stessa chiave significa che il tuo frontend finisce per fare un sacco di lavoro per deserializzare un po 'di dati che vogliono.

Dipende dai tuoi bisogni, e non posso dirti cosa è meglio per te senza sapere più di quello che stai facendo. Se davvero hai bisogno di qualcosa di più grande di 1 MB, è per questo che abbiamo aggiunto -I, però.

0

Per valori troppo grandi, invece di memorizzare un valore standard (che, quando decodificato, era sempre un dizionario) abbiamo memorizzato un elenco di chiavi. Abbiamo quindi letto i dati in ciascuna chiave e ripristinato il valore principale. Penso che abbiamo anche cancellato le chiavi quando erano troppo lunghe (cosa che potrebbe accadere nel nostro set di dati, ma estremamente raramente).

Abbiamo scritto tutto questo codice direttamente sopra il client memcached (stavamo usando Python), quindi a un livello superiore era tutto trasparente.

-2
$key=abs(crc32($long_key)) 

In questo modo si ottiene una chiave univoca per le query e altri tasti lunghi che possono avere modifiche oltre i 250 caratteri che Memcache vede.

+20

Possa la collisione essere con voi. –

+1

concordato. Un CRC32 ti darà un sacco di collisioni, almeno usare un hash MD5. –

9

$ key = abs (CRC32 ($ long_key))

In questo modo si ottiene chiave univoca per query e altre chiavi lunghe che possono avere modifiche oltre i 250 caratteri memcache vede.

Whoa ... attento. Un buon consiglio, ma senza un avvertimento importante. Ciò può causare collisioni.Certo è altamente improbabile, ma deve accadere solo una volta per causare un bug sconvolgente. Probabilmente vorrai comunque memorizzare la chiave lunga con memcached e controllare sempre le collisioni sulla chiave. Il modo migliore per gestirli sarebbe quello di memorizzare un semplice elenco di coppie long_key/value.

+0

Nella maggior parte degli scenari in cui si utilizza memcached per memorizzare dati persistenti altrove, la probabilità di una collisione annulla la preoccupazione per il programma attorno a questo. Semplicemente monitorando memcached per alte frequenze di collisione ti dirà se c'è un problema, e solo allora vale la pena spendere il tempo alla ricerca di chiavi che si sovrascrivono a vicenda. Se la strategia di caching è correttamente implementata e si memorizzano nella cache i dati che sono stati mantenuti, non ci saranno bug sconvolgenti, solo un peggioramento delle prestazioni. –

+3

Dipende da cosa si sta memorizzando nella cache. Se le informazioni memorizzate nella cache sono private per un utente, una collisione hash potrebbe significare la perdita di dati privati ​​(che io definirei un bug sconvolgente). Ammesso che ci siano hash che rendono nettamente la probabilità di collisione dell'hash, ma crc32 non è uno di questi. Ci vogliono solo poco più di 77000 valori per le probabilità che una collisione hash sia 1 su 2 (http://preshing.com/20110504/hash-collision-probabilities). L'utilizzo di una funzione di hash migliore per il tasto aiuta, ma ogni implementazione della tabella hash so di account per collisioni. Non è difficile; basta memorizzare e controllare la chiave. – peabody

-1

Non reale correlato alla domanda iniziale ma nel caso si pensi di passare a APC: il suo max. len per le chiavi è 9727 caratteri. (testato su PHP 5.3.2)

Problemi correlati