Estoy tratando de codificar algunos datos (una cadena muy grande en realidad) de una manera muy eficiente con la memoria en el lado de Redis. Según los docs Redis, se afirma que "el uso hashes cuando sea posible", y se declara dos parámetros de configuración:Optimización de la memoria Redis
Los "hash max-zipmap-entradas", que si he entendido bien denota cómo muchas teclas como máximo cada tecla hash debe tener (¿estoy en lo cierto?).
El "hash-max-zipmap-value", que denota la longitud máxima del valor. ¿Se refiere al campo o al valor, en realidad? Y la longitud es en bytes, caracteres o qué?
Mi idea es dividir la cadena (que de alguna manera ha longitud fija) en cantidades tales que juega bien con los parámetros anteriores, y guardarlas como valores. Los campos deben ser sólo los números de secuencia, para garantizar una decodificación coherente ..
EDITAR: he referenciado ampliamente y parece que codifica la cadena en un hash produce un consumo de memoria ~ 50% mejor.
Aquí es mi guión evaluación comparativa:
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
y los resultados en mi máquina (32 bits ejemplo 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
estoy preguntando si hay una manera más eficiente para almacenar la cadena como un hash, jugando con los parámetros que mencioné. Entonces, en primer lugar, debo ser consciente de lo que significan. Luego haré un benchmark de nuevo y veré si hay más ganancia ...
EDIT2: ¿Soy un idiota? La evaluación comparativa es correcta, pero está confirmada para una cadena grande. Si repito para muchas cadenas grandes, almacenarlas como cadenas grandes es el ganador definitivo ... Creo que la razón por la que obtuve esos resultados para una cadena yace en las internas de Redis.
Si está hablando de un hash criptográfico, es imposible decodificarlos, ya que un infinito número de cadenas diferentes se asigna a un hash determinado. – agf
hash criptográfico? Solo intento almacenar una cadena grande de manera eficiente en un hash Redis, dividiéndola en fragmentos Ai, donde len (Ai) <"hash-max-zipmap-value". Luego puedo restaurarlo usando chunk_sequence_number, que es el campo que contiene cada Ai. – hymloth
No sé nada sobre Redis, pero "hash" y "decodificación" a menudo significan que alguien no comprende cómo funcionan las funciones hash. No sé si se aplica o no a esta situación. – agf