Sto cercando di codificare alcuni dati (in realtà una stringa molto grande) in modo molto efficiente dalla memoria sul lato Redis. Secondo la documentazione Redis, si afferma che "l'uso di hash quando possibile", e dichiara due parametri di configurazione:Ottimizzazione della memoria di Redis
I "hash-max-zipmap-voci", che se ho capito bene denota come molte chiavi al massimo devono avere ogni chiave hash (ho ragione?).
Il valore "hash-max-zipmap", che indica la lunghezza massima per il valore. Si riferisce al campo o al valore, in realtà? E la lunghezza è in byte, caratteri o cosa?
Il mio pensiero è quello di dividere la stringa (che in qualche modo ha fissato la lunghezza) in quantità tali che giocherà bene con i parametri di cui sopra, e memorizzarli come valori. I campi devono essere numeri di sequenza soli, per garantire una decodifica coerente ..
EDIT: Ho benchmark ampiamente e sembra che codifica la stringa in un hash produce un consumo di memoria ~ 50% in più.
Ecco il mio script di benchmarking:
import redis, random, sys
def new_db():
db = redis.Redis(host='localhost', port=6666, db=0)
db.flushall()
return db
def db_info(db):
return " used memory %s " % db.info()["used_memory_human"]
def random_string(_len):
letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
return "".join([letters[random.randint(0,len(letters)-1)] for i in range(_len) ])
def chunk(astr, size):
while len(astr) > size:
yield astr[:size]
astr = astr[size:]
if len(astr):
yield astr
def encode_as_dict(astr, size):
dod={}
cnt = 0
for i in chunk(astr,size):
dod[cnt] = i
cnt+=1
return dod
db=new_db()
r = random_string(1000000)
print "size of string in bytes ", sys.getsizeof(r)
print "default Redis memory consumption", db_info(db)
dict_chunk = 10000
print "*"*100
print "BENCHMARKING \n"
db=new_db()
db.set("akey", r)
print "as string " , db_info(db)
print "*"*100
db=new_db()
db.hmset("akey", encode_as_dict(r,dict_chunk))
print "as dict and stored at value" , db_info(db)
print "*"*100
ed i risultati sulla mia macchina (32bit esempio Redis):
size of string in bytes 1000024
default Redis memory consumption used memory 534.52K
******************************************************************************************
BENCHMARKING
as string used memory 2.98M
******************************************************************************************
as dict and stored at value used memory 1.49M
chiedo se c'è un modo più efficiente per memorizzare la stringa come un hash, giocando con i parametri che ho citato. Quindi, per prima cosa, devo essere consapevole di cosa significano .. Poi mi occuperò di nuovo e vedrò se c'è più guadagno ..
EDIT2: Sono un idiota? Il benchmarking è corretto, ma è confermato per una grande stringa. Se ripeto per molti grandi archi, immagazzinarli come grandi stringhe è il vincitore definitivo .. Penso che il motivo per cui ho ottenuto quei risultati per una stringa risiede negli interni di Redis ..
Se si sta parlando di un hash crittografico, è impossibile decodificarli, poiché un numero infinito di stringhe diverse viene mappato su un determinato hash. – agf
Hash crittografico? Sto solo cercando di memorizzare una grande stringa in modo efficiente in un hash Redis, dividendola in blocchi di Ai, dove len (Ai) <"hash-max-zipmap-value". Quindi posso ripristinarlo usando chunk_sequence_number, che è il campo che contiene ogni Ai. – hymloth
Non so nulla di Redis, ma "hash" e "decodifica" spesso indicano che qualcuno non capisce come funzionano le funzioni hash. Non so se si applica o meno a questa situazione. – agf