Friday 21 September 2012

[Перевод] Почему я отказался от MongoDB

Не так давно я закончил миграцию одного из наших проектов с MongoDB на PostgreSQL. Я бы хотел поделится почему я принял такое решение.

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


Суть нашего проекта заключается в конвертации текстовых документов, таких как чеки или визитки, и сохранении их в базе данных с возможностью поиска. Так, нам показалось, что документоориентированная база данных (далее ДО БД) это именно то что нужно). Эх, забыв о математике в основе реляционной алгебры, я не смог разглядеть в какую ловушку я себя заманил - в ДО БД необыкновенно сложно использовать агрегационные функции, группировать данные и предоставлять осмысленную статистику на основании данных из пользовательских чеков, что, в свою очередь, является одним из основных преимуществ нашего продукта. Без мощных агрегационных функций, наличие которых принимается как должное в любых RDBMS, я постоянно боролся с громоздкими map-reduce конструкциями когда всё что я хотел, это выполнить простейший запрос SELECT SUM(amount) FROM receipts WHERE [foo] GROUP BY [bar]. Я даже контрибутил несколько патчей в mongoid-mapreduce, но весь мой опыт группировки данных с MongoDB был настолько ужасен, что я не мог более заставлять себя продолжать работу над развитием приложения.

Во-вторых. При работе с ДО БД теряется независимость вариантов получения данных. Люди не прекращают жаловаться на то, что при использовании JOIN усложняется возможность масштабирования данных. Но, обратное утверждение тоже верно - без JOIN ваши данные становятся непривлекательной кучей грязи. Рассмотрим такую простейшую вещь как логирование аудита. Обычно, в ДО БД это должен быть набор документов, встроенных в аудируемый объект. А теперь, представим что нам нужен список действий, совершенных конкретным пользователем. Бинго! Вы в ловушке. Вы должны загрузить каждый документ из ДО БД, извлечь из него лог аудита и отфильтровать их по указанному пользователю средствами своего приложения. Одной только мысли о том, как это загрузит моё железо, достаточно для того, чтобы отказаться от этой затеи. JOIN'ы клёвые! Угадайте, с какой проблемой вы вероятнее всего встретитесь - необходимостью JOIN'ов или масштабированием как у facebook?

В-третьих. MongoDB катастрофически не хватает различных возможностей, фич. Возможно, что-то изменилось в положительную сторону за последние несколько месяцев, но, когда я последний раз искал что-то простое, типа case-insensitive поиска - даже его не было. Рекомендованным решением было хранить нужный для поиска текст в нижнем регистре в отдельном поле. А это значит, что моя модель, которую я тщательно разработал, соблюдая Принцип Персональной Ответственности, должна иметь специальные колбеки или хуки чтобы иметь возможность сохранять данные в это поле при каждом обновлении. А что если я добавлю новое поле с данными для поиска? Настало время перезаписать все данные в поисковом поле. Единственный вывод, к которому я пришел, это то, что MongoDB это хорошо финансируемый и искусный тролль.

В-четвертых. То, что абсолютно взорвало мой мозг, - где-то в стеке из mongodb, mongoid и mongoid-map-reduce, где-то там, теряется информация о типе данных. Я то подумал что мы растем огромными скачками, когда за одну ночь у одного из наших пользователей появилось 1111 документов. Представьте моё удивление когда я понял, что это четыре единицы, сконкатенированных вместе. Они стали простыми строками где-то по пути. Да, в том случае, возможно, это была моя вина, но я не могу себе представить чтобы такое могло произойти в PostgreSQL. И, когда вы сложите все часы, проведенные за решением подобных раздражающих проблем, пр этом имея достаточно ограниченные возможности, то можно прийти только к простым и абсолютно очевидным выводам.

В-пятых. А что я получал, примиряясь со всеми этими недостатками? Веб-масштабирование не так уж сильно меня интересует. Наш продукт не такой уж большой и RDBMS доказала что предоставит нам стабильность работы при любом масштабировании, которого мы только можем достигнуть. Или я получал свободу от строгой схемы данных? Но, если подумать, схемы данных - это прекрасно. Они берут на себя ответственность хранения ограничений для данных в одном месте. Без них все проверки на валидность данных будут разбросаны по всему приложению. Документ, созданный месяц назад, и документ, созданный вчера, могут быть совершенно разными и я даже не узнаю об этом. Подобные модели данных, не требующие схем, способствуют появлению бездумного и недисциплинированного отношения к хранению данных.

Вчера я закончил миграцию на PostgreSQL. Я счастлив. Группировка прекрасна, поиск прекрасен. Мы сделали приятнейший поиск по тэгам и предоставили возможности управления. Об этом можно было бы забыть с MongoDB. PostgreSQL превращает ваше хранилище данных в то, чем оно должно быть - простой деталью в архитектуре вашего приложения, которая не заставляет вас подстраивать всю программу под его требования.

Итак, урок усвоен - будьте очень осмотрительны когда возвращаетесь  на 40 лет назад в прошлое компьютерной индустрии.

* Сверить перевод можно по этой  не нужнассылке.

No comments:

Post a Comment