MongoDB и NoSQL: когда это реально применимо
MongoDB 2.4 вышел в марте. Клиент хочет хранить данные датчиков в документной базе. Разбираем, что из этого выйдет, и куда NoSQL не стоит тащить.
MongoDB 2.4 вышел в марте 2013; NoSQL-базы активно обсуждаются как альтернатива реляционным СУБД.
В марте вышел MongoDB 2.4 - текстовый поиск, улучшенный геоиндекс, хеш-шардирование. Релиз был достаточно заметным, чтобы клиент, с которым мы работаем над интеграцией промышленных датчиков, пришёл с конкретным вопросом: «А давайте всё сложим в MongoDB?»
Мы не отказались сразу. Но сказали: давайте сначала разберёмся, что именно вы хотите хранить и как с этим работать.
Откуда данные
Несколько производственных объектов, на каждом - датчики температуры, давления, расхода. Каждый датчик пишет показания раз в секунду или чаще. Состав полей у разных моделей датчиков отличается: одни дают три поля, другие двадцать. Схема не фиксирована - при замене оборудования появляются новые поля, старые исчезают. Данные нужно хранить, уметь делать выборки по диапазону времени и строить агрегаты по объекту.
Звучит как хороший кейс для документной базы. Гибкая схема - как раз то, зачем люди идут в MongoDB.
Где NoSQL реально помогает
С документной моделью здесь несколько честных плюсов:
- Гибкая схема. Новая модель датчика добавляет поля - не надо делать ALTER TABLE и договариваться с DBA. Документ просто содержит то, что датчик прислал.
- Горизонтальное масштабирование. Шардирование в MongoDB устроено на уровне базы. При росте объёмов это работает проще, чем партиционирование в реляционной СУБД.
- Запись пачками. MongoDB хорошо держит high-throughput insert - как раз то, что нужно при потоке с датчиков.
- Встроенный TTL. Можно выставить время жизни документа прямо в индексе, и база сама выбросит устаревшие записи. Для хранения скользящего окна данных - удобно.
Для нашего случая первые два пункта закрывают главную боль клиента.
Где начинаются проблемы
Мы сразу предупредили: MongoDB в 2.4 не поддерживает транзакции в том смысле, в каком их понимают разработчики на PostgreSQL или SQL Server. Атомарность - только на уровне одного документа. Несколько документов одновременно - никаких гарантий.
Для сырых временных рядов датчиков это терпимо: если одна запись потеряется или задвоится, никто не умрёт. Но клиент в процессе обсуждения обронил: «А ещё мы хотим рядом хранить заявки на обслуживание - техник закрывает заявку, и должен списаться расход материалов со склада».
Вот тут мы остановились.
Списание со склада - это транзакция: либо всё прошло, либо ничего. MongoDB для этого не подходит. Не потому что плохая база, а потому что она не строилась под такую задачу. Тащить в одну документную базу и временные ряды с датчиков, и учётные операции - значит искать головную боль.
Второй момент - консистентность при чтении. MongoDB по умолчанию пишет в одну ноду и не гарантирует, что реплика видит актуальные данные в момент чтения. При мониторинге датчиков это некритично. При оперативных отчётах для диспетчера - может быть неприятно.
Архитектурное решение, к которому пришли
После разговора нарисовали такую схему:
- MongoDB - для сырых временных рядов датчиков. Гибкая схема, быстрая запись, TTL для старых данных.
- PostgreSQL - для заявок, учёта материалов, справочников. Транзакции там, где они нужны.
- Между ними - тонкая интеграционная прослойка: событие «показание вне нормы» из MongoDB триггерит создание заявки в PostgreSQL.
Клиент сначала удивился: «Зачем две базы?». Мы объяснили: не потому что мы любим усложнять, а потому что у двух частей системы принципиально разные требования к хранению. Пихать их в одну технологию - это либо ограничивать одну часть, либо терять гарантии в другой.
В итоге согласились. Работу по интеграции двух баз и потока данных с датчиков взяли на себя мы.
Что стоит помнить про NoSQL-хайп
Сейчас MongoDB обсуждают много - на конференциях, в блогах, в комментариях к вакансиям. Часто с формулировкой «выбросьте реляционные базы, берите NoSQL». Это не вредный совет, это просто неточный. NoSQL - не замена реляционным СУБД, а другой инструмент с другим профилем применимости.
MongoDB хорошо работает там, где:
- структура данных нестабильна или сильно варьируется от объекта к объекту,
- нужна высокая скорость записи без сложных связей,
- ACID-транзакции не нужны или ограничены одним документом,
- горизонтальное масштабирование важнее строгой консистентности.
Реляционная база выигрывает там, где важны транзакции, ссылочная целостность и сложные JOIN-запросы.
Для данных датчиков - MongoDB. Для учётных операций рядом - PostgreSQL. Это не компромисс, это правильный выбор инструмента под задачу.
- Hadoop на трёх виртуалках: честные впечатления · 28 февраля 2013
- SSD в серверной: первый опыт с enterprise-накопителями и подводными камнями · 31 января 2013