Я пытаюсь закодировать некоторые данные (на самом деле очень большую строку) очень эффективным способом памяти на стороне Redis. Согласно документам Redis, утверждается, что «используют хэши, когда это возможно», и объявляет два параметра конфигурации:
"hash-max-zipmap-records", который, если я правильно понял, обозначает, сколько ключей должно быть у каждого ключа хеша (верно?).
"hash-max-zipmap-value", который обозначает максимальную длину значения. Это относится к полю или к значению, на самом деле? А длина в байтах, символах или как?
Моя мысль состоит в том, чтобы разбить строку (которая каким-то образом имеет фиксированную длину) в таких количествах, которые будут хорошо сочетаться с вышеуказанными параметрами, и сохранить их как значения. Поля должны быть просто порядковыми номерами, чтобы обеспечить согласованное декодирование.
РЕДАКТИРОВАТЬ : Я много тестировал, и кажется, что кодирование строки в хэш-памяти дает ~ 50% лучшее потребление памяти.
Вот мой сценарий бенчмаркинга:
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
и результаты на моей машине (32-битный экземпляр 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
Я спрашиваю, есть ли более эффективный способ сохранить строку в виде хэша, играя с упомянутыми мною параметрами. Итак, во-первых, я должен осознавать, что они имеют в виду .. Затем я снова проведу тестирование и посмотрю, есть ли еще выигрыш ..
EDIT2: Я идиот? Бенчмаркинг правильный, но он подтвержден для одной большой строки. Если я повторю для многих больших строк, то сохранение их в виде больших строк является определенным победителем ... Я думаю, что причина, по которой я получил эти результаты для одной строки, кроется во внутренних элементах Redis.