Москва: проверенные б/у ноутбуки с гарантией и проверкой перед оплатой
+7 906 722-94-45

Главная → Статьи → Выбор хранилища: как решать, куда класть данные

Выбор хранилища: критерии, которые решают, а не маркетинг

Выбор базы данных: модель данных, профиль нагрузки, согласованность, стоимость эксплуатации и типичные ошибки выбора.

Прямой ответ

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

Пять критериев, которые определяют выбор:

1. Модель данных. Как связаны сущности и как к ним обращаются?

Характер данных Подходящая модель
Связи «один ко многим», транзакции, отчёты по строкам Реляционная
Глубокие обходы связей, поиск по графу Графовая
Самодостаточные записи с вложенностью Документная
Доступ по точному ключу, кэш, счётчики Key-value
Запросы по ключу с сортировкой внутри партиции Wide-column
Массовые агрегации по колонкам Колоночная

2. Профиль нагрузки. Соотношение чтения и записи, размер читаемого набора, требования к задержке. Операционные и аналитические нагрузки конфликтуют в одной системе — см. OLTP и OLAP.

3. Требования к согласованности. Нужна ли строгая согласованность после записи, допустима ли временная несогласованность, что происходит при сетевом разделении. Теоретические ограничения — в статье про CAP-теорему.

4. Объём и рост. Данные на одной машине или требуют распределения. Вертикальное масштабирование проще, пока не исчерпано.

5. Стоимость эксплуатации. Знакомство команды, зрелость инструментов, резервное копирование, мониторинг, найм. Этот критерий чаще всего недооценивают и именно он определяет итоговую стоимость владения.

Порядок вопросов при выборе:

  1. Какие запросы будут выполняться? Выпишите их с фильтрами, сортировкой и ожидаемым объёмом результата.
  2. Какие гарантии нужны для каждого типа данных? Платёж и счётчик просмотров требуют разного.
  3. Какой объём сейчас и через два года?
  4. Какая система уже есть в стеке и что она умеет?
  5. Что произойдёт при отказе хранилища и как восстанавливаться?

Практическое правило: начинайте с реляционной базы, если нет измеримой причины поступить иначе. PostgreSQL покрывает широкий спектр задач, включая JSON, полнотекстовый поиск, геопространственные данные и оконные функции.

Практика: как принимать решение

1. Проверяйте, достаточно ли основной базы. Прежде чем добавлять новую систему, убедитесь, что задача не решается средствами текущей: специализированные типы индексов, партиционирование, материализованные представления.

2. Добавляйте систему под конкретный класс запросов. Правильный повод — измеримая деградация конкретного сценария. Неправильный — «нам нужен Redis, потому что он быстрый».

3. Считайте стоимость согласованности между системами. Каждая дополнительная система добавляет задачу синхронизации: задержка, расхождения, поведение при сбое, мониторинг. Это постоянные расходы, а не разовые.

4. Прототипируйте на реальных данных. Оценка по документации ошибается в обе стороны. Прогон типовых запросов на копии данных занимает дни и снимает большую часть неопределённости.

5. Фиксируйте решение. Запись «выбрали X вместо Y, потому что измерили Z» экономит месяцы споров позже. О практике фиксации решений — в статье про документацию и ADR.

Типичные ошибки:

  1. Выбор по популярности. Технология, хорошо работающая в масштабе крупной компании, не обязательно подходит проекту с миллионом записей.
  2. Преждевременное распределение. Кластеризация до исчерпания возможностей одной машины добавляет сложность без выгоды.
  3. Полиглотная персистентность без необходимости. Пять систем хранения для одного сервиса — это пять резервных копий, пять мониторингов и пять способов потерять данные. О последствиях такого роста — в статье про технический долг.
  4. Игнорирование операции восстановления. Система, из которой нельзя восстановить данные за приемлемое время, не подходит независимо от скорости запросов.
  5. Отсутствие плана выхода. Если через год окажется, что выбор неверен, насколько дорого перенести данные обратно?

Рекомендации:

  1. Разделяйте данные по критичности. Платежи, пользовательские данные и телеметрия имеют разные требования; хранить их в одной системе с одинаковыми настройками — компромисс в обе стороны.
  2. Держите источник истины в одном месте. Дополнительные системы должны быть производными и восстанавливаемыми из источника.
  3. Измеряйте до и после. Без измерений невозможно понять, решило ли новое хранилище исходную проблему.
  4. Ограничьте число систем в стеке. Каждая новая технология должна заменять класс задач, а не добавляться к существующим.
  5. Проверяйте сценарий отказа. Отключение хранилища на десять минут — тест, который стоит провести до запуска, а не во время инцидента.

Практический сценарий: разбор стека из семи хранилищ

Контекст: за три года в сервисе накопились PostgreSQL, MongoDB, Redis, Elasticsearch, Cassandra, ClickHouse и очередь на Kafka. Команда тратила значительную часть времени на синхронизацию данных между ними.

  1. Аудит. Для каждой системы выписали: какие данные хранит, какие запросы обслуживает, можно ли восстановить данные из другой системы.
  2. Находка 1. MongoDB хранила 2,1 млн документов, из которых 94 % имели одинаковую структуру и использовались в запросах с соединениями. Данные перенесли в PostgreSQL, где соединения работали быстрее.
  3. Находка 2. Cassandra обслуживала один сценарий — чтение последних событий устройства. Запрос воспроизвели в PostgreSQL с партиционированием по времени; производительность оказалась приемлемой при текущем объёме.
  4. Находка 3. Redis использовался как кэш и как единственное хранилище для части данных о сессиях. Хранение привели к основному источнику, Redis оставили только в роли кэша.
  5. Что оставили. PostgreSQL как источник истины, Redis как кэш, Elasticsearch для поиска, ClickHouse для аналитики, Kafka для обмена событиями. Семь систем сократились до пяти, причём каждая имеет ясную роль.
  6. Результат. Число задач синхронизации сократилось с одиннадцати до четырёх, время восстановления системы после сбоя уменьшилось, число инцидентов с расхождением данных снизилось.

Вывод: каждая дополнительная система хранения — это постоянная работа по согласованию данных. Сокращение стека почти всегда даёт больший выигрыш, чем добавление очередной специализированной базы.

FAQ

С чего начинать новый проект? С реляционной базы, если нет измеримой причины иначе. Она покрывает транзакции, соединения, JSON, полнотекстовый поиск и геопространственные задачи, а её инструменты резервного копирования и мониторинга наиболее зрелые.

Когда точно нужна отдельная система? Когда есть измеримая деградация конкретного сценария, которая не устраняется настройкой текущей базы: глубокие обходы графа, полнотекстовый поиск с высокой нагрузкой, массовые аналитические агрегации, доступ по ключу с сотнями тысяч операций в секунду.

Что такое полиглотная персистентность? Подход, при котором разные данные хранятся в разных системах, подобранных под задачу. Он оправдан при наличии разных профилей нагрузки и становится проблемой, когда системы добавляются без ясной роли.

Как оценить готовность команды к новой технологии? Проверить, есть ли опыт эксплуатации: резервное копирование, обновление версий, восстановление после сбоя, мониторинг. Отсутствие ответов на эти вопросы означает, что технология будет эксплуатироваться в аварийном режиме.

Источники: PostgreSQL docs (index types), Redis docs (data types), Wikipedia (polyglot persistence) — ссылки в шапке.