Как пары ключ/значение хранятся в Redis

Мы используем узел Elasticache Redis для хранения данных.

Все ключи имеют одинаковый формат:
- Ключ представляет собой хэш md5 - 128 бит (16 байт, 32 строковых символа байт).
- Значение представляет собой строку отметки времени - 19 байт.
Суммарный размер ключа составляет 32+19=51 bytes

У нас есть 84 917 361 миллиона ключей.
Я предполагаю, что общая память, потребляемая оболочкой Redis, близка к 84917361*51 = 4.03 gb.

На самом деле требуется 11.07 gb.
Вывод команды info: used_memory_human:11.07G

  1. На что тратится остаток памяти, 7 gb?
  2. Есть ли способ сохранить md5 как 16-байтовый хеш, а не строку с 32 символами?

Спасибо, любая помощь очень ценится.


person antonbormotov    schedule 22.01.2017    source источник
comment
Вам может быть интересна эта статья, особенно часть о влиянии ключей на память по сравнению с хешами.   -  person Kevin Christopher Henry    schedule 22.01.2017
comment
Спасибо @Kevin Christopher Henry, я реализую предложения.   -  person antonbormotov    schedule 23.01.2017


Ответы (1)


На что расходуется остальная память, 7 гб?

Краткий ответ: Redis НЕ хранит ключ и значение в виде необработанной строки.

Фактически,

  1. ключ заключен в структуру sdshdr (для последней версии это более компактная структура), которая имеет некоторые накладные расходы, например. длина строки.

  2. значение заключено в структуру redisObject, которая также имеет некоторые накладные расходы, например. кодировка объекта, счетчик ссылок.

  3. Есть и другие накладные расходы, когда Redis вставляет пару в словарь, например. указатель next и указатель key в структуре dictEntry.

Все эти накладные расходы потребляют остальную часть памяти.

Чтобы сделать его более эффективным с точки зрения памяти, вы можете обратиться к статье, о которой упоминал @Kevin Christopher Henry (небольшой хеш может сэкономить много redisObject накладных расходов и может использовать ziplist, чтобы сделать элементы более компактными в памяти).

Есть ли способ сохранить md5 как 16-байтовый хеш, а не строку с 32 символами?

Используйте хеш-функцию, например Murmurhash, для создания дайджеста для каждой строки md5.

Таким образом, вы можете получить дайджест размером 8 байт (64 бита). Однако вы не можете получить необработанную строку md5 из дайджеста Murmurhash. Поэтому, если вам НЕ не важно значение md5, вы можете использовать этот метод.

person for_stack    schedule 23.01.2017
comment
Спасибо @for_stack, это то, что я искал. Я попытаюсь использовать Murmurhash или crc32 в качестве хеш-значения. - person antonbormotov; 23.01.2017