Mongo DB - документо-ориентированная база данных и MySQL

Одним из основных принципов разработки масштабируемых и эффективных приложений является выбор подходящих технологий для решения той или иной задачи. Многие современные РСУБД представляют из себя решения универсальные, но во многих случаях в них просто нет необходимости.
Одним из альтернативных решений для хранения и обработки данных является СУБД Mongo DB (”humongous” - огромный, невероятный).
Что такое Mongo DB?
Mongo DB - высокопроизводительная документо-ориентированная база данных. Особенности этой СУБД:
- Документное хранилище, не требующее создания схем (таблиц)
- Запросы в стиле JSON (очень удобно)
- Широкий набор (атомарных) операций над данными (условный поиск, сложная вставка/обновление и т.п.)
- Разные типы данных (поддержка массивов)
- Поддержка индексов (B-Tree)
- Автовосстановление, шардинг и репликация в коробке
- Профилирование, хранение больших объектов, административный интерфейс, серверные функции, Map/Reduce и многое другое
Mongo DB и MySQL
Многое из вышеперечисленного есть и в решениях более знакомых, таких, как MySQL. Давайте сравнивать:
| MongoDB | MySQL | |
|---|---|---|
| Модель данных | Документная | Реляционная |
| Типы | string, int, double, boolean, date, bytearray, object, array | Типы MysQL |
| Большие объекты | Да | Да |
| Репликация | Master-slave | Master-slave |
| Хранилище наборов данных | Коллекции | Таблицы |
| Метод запросов | объектный язык запросов | SQL |
| Дополнительные индексы | Да | Да |
| Атомарность | Документ | Расширенная |
| Манипулирование наборами данных на сервере | Map/Reduce, серверный javascript | SQL |
| Платформа | C++ | C |
| Контроль конкурентности (Concurrency Control) | Update in Place | MVCC |
Итак преимущества Mongo:
- Объектный язык запросов (который намного легче SQL, что является важным преимуществом для большинства задач, не требующих сложных выборок)
- Поддержка Map/Reduce для распределенных операций над данным
- Документы, не требующие определения схемы. Одно из самых важных преимуществ. Преимущество заключается в том, что у Вас нет нужды хранить пустые ячейки данных в каждом документе.
- Поддержка сложных массивов. Каждый элемент массива может представлять из себя объект
- Поддержка шардинга на уровне платформы
Производительность
Для тестирования возьмем таблицу в MySQL (messages) с простой структурой (таблица личных сообщений пользователей одного из моих проектов). Количество записей в ней - около 200 тыс. Все данные скопированны в mongo с соотв. индексами.
Для тестирования будем использовать следующий скрипт:
<?php
$m = new Mongo();
$col = $m->messages->threads;
$s = microtime(true);
for ( $i = 0; $i < 5000; $i++ )
$cursor = $col->find( array('user_id' => $i) );
$t = microtime(true) - $s;
echo "Mongo: " . $t . "\n\n";
mysql_connect('localhost');
mysql_select_db('messages');
$s = microtime(true);
for ( $i = 0; $i < 5000; $i++ )
mysql_query('SELECT id FROM messages WHERE mailed_by = ' . $i);
$t = microtime(true) - $s;
echo 'MySQL: ' . $t . "\n\n";
Как видно из скрипта, мы сделали по 5000 выборок из обеих СУБД. Поля, по которым проходила выборка являются индексными. Ниже приведены результаты второго запуска скрипта (в первый раз значения были гораздо большими, т.к. таблицы не были подтянуты в память):
Mongo: 0.010502815246582 MySQL: 0.27930092811584
Как видим MySQL справился с однотипной задачей на порядок медленее. Для тестирования были использованы стандартные конфигурации обоих платформ, поэтому настройка может внести изменения в эти результаты.
Когда выбирать Mongo DB, а когда MySQL?
Mongo представляет из себя очень функциональное решение, тем не менее обладает рядом ограничений. Например, возможность сделать JOIN (а нужен ли он?). Также язык запросов Mongo конечно устапает SQL в гибкосте и возможностях. Но нужна ли Вам эта гибкость в Ваших задачах? Одним словом, Mongo подходит почти под любой класс задач, не требующих сложных выборок.
Что же касается MySQL (или родственных продуктов), то он остается решением для задач требующих нетривиальных выборок (например, статистические или аналитически запросы).
Личное впечатление
После первого знакомства с Mongo DB, этот продукт оставил очень хорошее впечатление и заставил вернуться к нему еще раз. Помимо прочих преимуществ:
- Очень легкий и интуитивно понятный
- Простая установка, все заработало с первого раза
- Отличная документация, хорошее сообщество
- Множество клиентских разработок, в т.ч. под PHP
При детальном рассмотрении, выяснилось, что сам продукт обладает очень обширным функционалом (например, полнотекстовый поиск). Кажущийся простым на поверхности, MongoDB представляет из себя очень мощную платформу для работы с данными.
Совсем недавно мы переписали несколько фукнциональных частей проекта на Mongo. В процессе работы проблем почти не возникало, за исключением некоторых:
- Mongo строго типизирован и не приводит типы автоматически (такой возможности впринципе нет, учитывая отсуствие каких-либо метаданных о коллекциях и документах). Поэтому в динамически типизированном PHP приходится приводить данные к нужным типам (например, когда они приходят из формы).
- Не хватило возможностей для работы с массивами, что немного сбило с толку. С одной стороны - вложенные массивы - очень удобная вещь, с другой стороны - нет таких штук, как их фильтрация или сортировка. Надеюсь все это будет вскоре, хотя сейчас есть возможность реализовать это с помощью серверных функций.
Интересно узнать мнение и опыт читателей, кто использовал или знаком с MongoDB.


> Количество записей в ней - около 200000 тыс.
Хотелось бы для ясности уточнить: около 200,000 или 200,000,000?
@Vladimir
Спасибо, ошибся. 200 тыс.
а как себя ведет MongoDB при высоких нагрузках ? скажем 100 запросов в секунду при выборке из таблиц в 2 миллиона записей и размером таблицы в 4-5 гб.
@Joka
Практических данных пока нет, но в первом приближении это маленькие объемы для подобного продукта (т.е. проблем быть не должно). Присоединяйтесь к тестированию, будем проверять
Спасибо очень интересный пост, в свете того что тоже планируем внедрять MongoDB.
Для high availability у них есть интересный режим работы Replica Pairs (http://www.mongodb.org/display/DOCS/Replica+Pairs).
В данном режиме два сервера связанны отношение Master-Slave. Однако если с мастером чтото случилось, то слейв самостоятельно становится мастером.
Вы не пробовали этот режим на практике?
Используем успешно. Храним там активность пользователей. Используем нестабильную ветку 1.3.3. Пока только одна странность не дает на спать, съедает всю память (12гб) и ядро убивает процесс. Пока не разобрались почему.
Господа ни у кого не возникает ситуации на продакшене, когда Монго выжирает всю память (12-16 гб) и начинает свопиться и в итоге крэшится? Клиент - pecl-овский экстеншен - mongo.
Ничего не имею против обоих рассматриваемых хранилищ (каждое решение существует под свои задачи), однако при более серьезной нагрузке в продакшене, где требуется транзакционность, синхронизация данных, оба эти решения прийдется пилить большим напильником с большими затратами.
Если нужно надежное стабильное решения для хранения данных под большие нагрузки, то вариантов не много - Oracle, DB2, MSSQL (хотя к последнему лично я не тяготею).
Забыл указать, что еще используем обертку Morph (http://code.google.com/p/mongodb-morph/).
Скажите, пожалуйста, что такое Update in Place, MVCC и чем они отличаются. В гугле я не смог найти, к сожалению.
@Стас Агарков
1. Хороший подбор про MVCC и реализацию в различных СУБД: http://stackoverflow.com/questions/27499/database-what-is-multiversion-concurrency-control-mvcc-and-who-supports-it
2. Update-in-place - это подход Mongo к вставке/обновлению, подробнее тут: http://blog.mongodb.org/post/248614779/fast-updates-with-mongodb-update-in-place
Есть замечание по тесту. В случае с mysql_query() результат выполнения буфферизируется внутри mysql екстеншна php (точнее, внутри libmysql), т.е, по сути, передается клиенту. В случае с mongo возвращается только курсор, а не сами данные, т.е. нет их фактического чтения в клиент. Если переписать тест на вычитывание записи, которая выбирается, то условия будут равными для mongo и для mysql. Это будет более честный тест.
Спасибо большое! Ценное замечание. Не поделитесь своими результатами теста?
Не пойму это тоже, что и ключ=>значение о которых вы недавно писали, или это БД другого круга?
@Андрей
Нет, это не ключ=значение. Это полнофункциональная СУБД с поддержкой списков, индексов, поиска по тексту и серверных функций.
Следует учесть, что хотя Mongo и обладает лучшими показателями производительности, чем, например, MySQL - на большИх нагрузках проблемы возникают не из-за (не)эффективности платформы, а из-за неправильной структуры БД.