Redis оптимизация памяти - PullRequest
       6

Redis оптимизация памяти

8 голосов
/ 19 сентября 2011

Я пытаюсь закодировать некоторые данные (на самом деле очень большую строку) очень эффективным способом памяти на стороне 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.

Ответы [ 4 ]

6 голосов
/ 19 сентября 2011

На самом деле, наиболее эффективный способ хранения большой строки - это большая строка - все остальное добавляет накладных расходов. Упомянутые вами оптимизации предназначены для работы с множеством коротких строк, когда пустое пространство между строками может стать проблемой.

Производительность хранения большой строки может быть не такой хорошей, как для небольших строк, из-за необходимости находить более непрерывные блоки для ее хранения, но это вряд ли повлияет на что-либо.

4 голосов
/ 19 сентября 2011

Я попытался прочитать документы Redis о настройках, которые вы упоминаете, и это не так просто.Но мне не кажется, что твой план - хорошая идея.Хэширование, которое они описывают, предназначено для экономии памяти для небольших значений.Значения по-прежнему полностью хранятся в памяти.Мне кажется, что они уменьшают накладные расходы, когда они появляются много раз, например, когда строка добавляется во множество наборов.Ваша строка не соответствует этим критериям.Я сильно сомневаюсь, что вы сэкономите память, используя вашу схему.

Вы можете, конечно, сравнить ее, чтобы увидеть.

2 голосов
/ 19 сентября 2011

Попробуйте взглянуть на статью Использование памяти Redis , в которой можно найти хорошее сравнение различных типов данных и их потребления памяти.

0 голосов
/ 28 мая 2018

Когда вы сохраняете данные в хэше, вы просто пропускаете ~ 100 байт на каждое значение!

Таким образом, когда длина строки сопоставима, например, на 100-200 байт, вы можете сэкономить 30-50% памяти, а для целых чисел - в 10 раз меньше!

Вот пара ссылок:

Около 100 байт

Сравнительный анализ оптимизации памяти

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...