Redis strings vs Redis хэш для представления JSON: эффективность?
Я хочу сохранить полезную нагрузку JSON в redis. Я действительно могу сделать это двумя способами:
-
Один, используя простые строковые ключи и значения.
ключ: пользователь, значение: полезная нагрузка (весь блок JSON, который может составлять 100-200 КБ)
SET user:1 payload
-
Использование хешей
HSET user:1 username "someone"
HSET user:1 location "NY"
HSET user:1 bio "STRING WITH OVER 100 lines"
Имейте в виду, что если я использую хэш, длина значения не предсказуема. Они не все короткие, такие как био-пример выше.
Чем эффективнее память? Использование строковых ключей и значений или использование хеша?
Ответы
Ответ 1
Это зависит от того, как вы получаете доступ к данным:
Перейдите к Варианту 1:
- Если вы используете большинство полей на большинстве ваших обращений.
- Если существует дисперсия возможных клавиш
Перейдите к Варианту 2:
- Если вы используете только отдельные поля на большинстве ваших обращений.
- Если вы всегда знаете, какие поля доступны
P.S.: Как правило, большой палец, перейдите к опции, которая требует меньше запросов на большинстве ваших случаев использования.
Ответ 2
В этой статье можно найти много проницательности: http://redis.io/topics/memory-optimization
Существует множество способов хранения массива объектов в Redis ( spoiler: мне нравится вариант 1 для большинства случаев использования):
-
Храните весь объект в виде JSON-кодированной строки в одном ключе и отслеживайте все объекты с помощью набора (или списка, если это более подходит). Например:
INCR id:users
SET user:{id} '{"name":"Fred","age":25}'
SADD users {id}
Вообще говоря, это, вероятно, лучший метод в большинстве случаев. Если в объекте много полей, ваши объекты не вложены в другие объекты, и вы, как правило, имеете доступ только к небольшому подмножеству полей за раз, возможно, лучше перейти с опцией 2.
Преимущества: считается "хорошей практикой" . Каждый объект представляет собой полноразмерный код Redis. Разбор JSON выполняется быстро, особенно когда вам нужно получить доступ ко многим полям для этого объекта сразу. Недостатки: медленнее, когда вам нужно только получить доступ к одному полю.
-
Сохраните свойства каждого объекта в хеше Redis.
INCR id:users
HMSET user:{id} name "Fred" age 25
SADD users {id}
Преимущества: считается "хорошей практикой" . Каждый объект представляет собой полноразмерный код Redis. Не нужно разбирать строки JSON. Недостатки: возможно, медленнее, когда вам нужно получить доступ ко всем/большинству полей в объекте. Кроме того, вложенные объекты (объекты внутри объектов) не могут быть легко сохранены.
-
Храните каждый объект в виде строки JSON в хеше Redis.
INCR id:users
HMSET users {id} '{"name":"Fred","age":25}'
Это позволяет вам консолидировать бит и использовать только два ключа вместо большого количества ключей. Очевидным недостатком является то, что вы не можете установить TTL (и другие вещи) для каждого пользовательского объекта, поскольку это всего лишь поле в хэше Redis, а не полноразмерный код Redis.
Преимущества. Разбор JSON выполняется быстро, особенно если вам нужно сразу получить доступ ко многим полям для этого объекта. Меньше "загрязнение" основного пространства имен ключей. Недостатки. О том же использовании памяти, что и # 1, когда у вас много объектов. Медленно, чем # 2, когда вам нужно только получить доступ к одному полю. Вероятно, не считается "хорошей практикой" .
-
Хранить каждое свойство каждого объекта в выделенном ключе.
INCR id:users
SET user:{id}:name "Fred"
SET user:{id}:age 25
SADD users {id}
В соответствии с вышеприведенной статьей этот вариант почти никогда не бывает предпочтительным (если только свойство объекта не должно иметь конкретный TTL или что-то еще).
Преимущества: свойства объекта являются полноразмерными клавишами Redis, которые не могут быть переполнены для вашего приложения. Недостатки: медленный, использует больше памяти и не считается "лучшей практикой". Много загрязнений основного пространства имен ключевых слов.
Общее резюме
Вариант 4 обычно не является предпочтительным. Варианты 1 и 2 очень похожи, и они оба довольно распространены. Я предпочитаю вариант 1 (вообще говоря), потому что он позволяет хранить более сложные объекты (с несколькими слоями вложенности и т.д.). Вариант 3 используется, когда вы действительно заботитесь о том, чтобы не загрязнять пространство имен основного ключа (т.е. Вы не хотите там чтобы было много ключей в вашей базе данных, и вам не нравятся такие вещи, как TTL, очертание ключа или что-то еще).
Если у меня что-то не так, пожалуйста, подумайте о том, чтобы оставить комментарий и разрешить мне пересмотреть ответ перед тем, как спустить. Благодарю!:)