Получить доступ

Key-value хранилища

Простейшая модель доступа по ключу, типичные применения, Redis против DynamoDB, партиционирование и ограничения.

Модель ключ-значение

Key-value — простейшая модель: словарь «ключ → значение» в масштабе кластера. Доступ по ключу близок к O(1), значение для хранилища обычно непрозрачно (просто байты/blob).

Из простоты следуют и сила, и ограничение: чтения и записи по ключу очень быстрые и легко шардируются, но искать по содержимому значения нельзя — нет ad-hoc запросов и вторичных индексов «из коробки» (хотя некоторые системы их добавляют).

Типичные применения

Кэш (см. отдельный урок про Redis), пользовательские сессии, feature flags, rate limiting и счётчики, корзины, очереди задач, лидерборды — всё, где доступ идёт по понятному ключу.

Паттерн ключа продумывают заранее: ключ кодирует то, как данные будут запрашиваться (user:42:cart), потому что других способов найти данные нет.

Дизайн ключей и структуры данных

Раз найти данные можно только по ключу, схема ключей И ЕСТЬ схема данных. Практика — иерархическое пространство имён с разделителем: домен:идентификатор:сущность (user:42:cart, session:ab12, ratelimit:ip:10.0.0.1:minute:42). Так ключи читаемы, не конфликтуют между сервисами и допускают версионирование при смене формата.

Сразу закладывают и срок жизни: у эфемерных данных (сессии, лимиты, кэш) TTL ставят при записи, иначе хранилище со временем забивается мусором, который никто не решится удалить.

Redis отличается тем, что значение не обязано быть непрозрачным blob'ом — у него есть типы, и операции над ними атомарны. Счётчик через INCR не требует read-modify-write и потому не теряет инкременты при гонке. Sorted set держит элементы упорядоченными по score, давая лидерборд без сортировки на клиенте. Hash позволяет обновить одно поле объекта, не перезаписывая его целиком.

Отсюда практическое правило: прежде чем читать значение в приложение, менять и писать обратно, проверьте, нет ли атомарной команды, делающей это на стороне хранилища. Это и быстрее (один round-trip), и безопаснее при конкуренции.

# счётчик запросов с окном в минуту: атомарно, без read-modify-write
INCR ratelimit:ip:10.0.0.1:minute:42
EXPIRE ratelimit:ip:10.0.0.1:minute:42 60

# лидерборд на sorted set: порядок поддерживает само хранилище
ZADD leaderboard 1500 user:42
ZREVRANGE leaderboard 0 9 WITHSCORES   # топ-10

# объект в hash: обновляем одно поле, а не весь документ
HSET user:42 name "Ann" city "Berlin"
HINCRBY user:42 visits 1

Redis против DynamoDB

Redis — in-memory: предельно быстрый, с богатыми структурами (strings, hashes, lists, sets, sorted sets, streams), но объём ограничен памятью, а долговечность настраивается (RDB-снимки, AOF-журнал). Часто используется как кэш и быстрый стор эфемерных данных.

DynamoDB — управляемый дисковый key-value/wide-column стор с предсказуемой задержкой на любом масштабе, настраиваемой согласованностью (eventual/strong чтения) и моделью на основе partition key + sort key. Это персистентный источник данных, а не кэш.

Партиционирование по ключу

Данные распределяются по узлам по хэшу ключа (часто consistent hashing, чтобы добавление/удаление узла перемещало минимум данных). Поэтому равномерность ключей напрямую определяет равномерность нагрузки.

Горячий ключ (один популярный товар, один tenant) ломает эту идиллию: вся нагрузка летит в одну партицию. Лечат шардированием ключа, репликами на чтение или локальным кэшем.

Ограничения и согласованность

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

Согласованность зависит от системы: Redis-реплики асинхронны (возможна потеря последних записей при failover), DynamoDB предлагает выбор между eventual и strongly consistent чтением (второе дороже).

Как отвечать на собеседовании

Сильный ответ: подчеркните доступ только по ключу (отсюда дизайн ключей под запросы), отличие in-memory Redis от персистентного DynamoDB и проблему горячего ключа при партиционировании.

Разверните первый тезис так: раз других способов найти данные нет, схема ключей проектируется ОТ ЗАПРОСОВ — сначала список сценариев доступа, потом пространство имён вида user:42:cart. Это тот же принцип query-first, что в Cassandra, и его полезно назвать явно.

Разницу Redis и DynamoDB давайте через роль в системе, а не через список фич: Redis — in-memory, ограничен памятью, долговечность настраивается (RDB/AOF), поэтому его типичное место — кэш и эфемерные данные; DynamoDB — персистентный managed-стор с предсказуемой задержкой и выбором между eventual и strongly consistent чтением, то есть полноценный источник истины.

Про горячий ключ говорите с решением: вся нагрузка летит в одну партицию, лечится шардированием ключа (добавляем суффикс и разносим по N партициям), репликами на чтение или локальным кэшем перед хранилищем.

Завершите границей применимости — нет джойнов, нет произвольных запросов, ограниченные транзакции. Если задаче нужны связи и отчёты, key-value не годится как основное хранилище. Умение назвать, когда технология НЕ подходит, ценится выше умения её хвалить.

Вопросы по теме

Читайте также

Закрытая бета

Знать тему — половина дела

На живом собеседовании sotto слышит вопрос интервьюера и показывает короткий ответ и план. Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем