среда, 8 сентября 2010 г.

Подробнее про MongoDB

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

Поначалу, когда начинаешь читать основные ресурсы про монгу, перестаешь понимать, почему люди до сих пор используют всякие реляционные базы данных, да и вообще все другие базы кроме монги. Ведь она идеальна!
Ресурсы, которые ведут к такому впечатлению:

1. книга MongoDB in Action (традиционно, какую книгу маннинга не начинаю читать - сразу руки чешутся применить технологию): книга еще в процессе написания, но первая свободно доступная глава оттуда создает впечатление, что монгу следует использовать как можно чаще и везде.

2. показательный хэппи случай использования монги вместо мускула

3. конечно же сам сайт монги, читаешь и восхищаешься

4. презентация с советами по оптимизации монги, добавляющая уверенности в успехе

Однако, еще до достижения необходимого уровня экстаза для начала использования монги, удалось нагуглить и другие мнения.

1. критика и обвинения монги (там есть ссылка на самую первую статью автора, затем на якобы-ответ-от-монговцев ну и дальше уже следует читать основную статью)

2. еще один сочный бугурт от попытки реального применения старой версии монги, имеется и небольшое продолжение.

3. здоровенная статья критика монги от девелопера ... CouchDB! здесь имеется закешированный вариант с комментами, в том числе и от разработчиков монги

На десерт более менее объективная (как говорится, не biased) статья о том, как сделать монгу надежнее.

Что же остается сказать от себя. Судя по тому, что я прочитал, монга представляет собой быструю базу данных с отсутствием схемы. Ради этих двух преимуществ жертвуется надежность данных (как при аппаратном сбое так и при нормальном функционировании). Уровень достигаемого компромисса всячески настраивается, в следующем релизе 1.8 обещают некоторый уровень надежности на одиночном сервере. Кроме того, требуется достаточно большой объем оперативной памяти и 64битность сервера для того. чтобы монга могла проявить себя с лучшей стороны.

Толстая база данных

Стоит задача хранить большое количество сообщений приходящих постоянно с транспортных средств. Сообщения содержат параметры в весьма разнообразной форме (имеется несколько типов сообщений, в будущем не исключена возможность динамической, а не фиксированной структуры). Эти параметры в последствии используются для построения разнообразных отчетов.
Конкретно по объему приходящих сообщений: в рабочее время держится уровень 15-20 сообщений в секунду, ночью значительно меньше, но сообщения идут круглосуточно. Хотелось бы обеспечить хранение для средней скорости поступления 100 сообщений в секунду.

1. Первая попытка была для реляционной базы данных.
Так как структура сообщений разнится, то я решил выделить параметры сообщения в отдельную таблицу (связывая строки-параметры с сообщением через foreign key). На каждое сообщение приходится примерно 10-15 параметров в среднем. Но тогда получается, что в секунду у меня в среднем будет создаваться 100 * 15 = 1500 строк-параметров. Сколько это в месяц? 1500 * 3600 * 24 * 30 = ...3888000000 . Кхе-кхе-кхе. Я разделю пробелами: 3 888 000 000. Почти 4 миллиарда! Такой объем просто неподъемен для операций джойна (мне надо будет выбирать сообщения для одного транспортного средства и к ним джойнить все соответствующие параметры). Кроме того - сколько это займет на жестком диске? Возможные варианты оптимизации в таком случае - разбиение таблицы (поддерживается постгресом).

2. Альтернативный вариант для реляционной БД - не выделять параметры в отдельную таблицу. Но тогда придется создать пригодную для всех структур сообщений схему. Скорее всего это будет большое число колонок, которые будут заполняться частично в зависимости от сообщения. Решение такое не гибкое и не позволяет детально описывать значения параметров, однако избавляет нас от джойна и излишне большого числа строк. В таком сценарии мы будем ограничены 200-300 миллионами записей в месяц. Неприятно но, думаю, возможно.

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

3. Кардинальная альтернатива - использование дивных зверей из лагеря NoSQL. По крайней мере среди них есть два кандидата, предлагающие решение проблемы разнящейся структуры сообщений. Это MongoDB и CouchDB, так называемые schema-less базы данных. Записи в них грубо говоря имеют JSON вид и ничто не мешает нам добавлять произвольные аттрибуты в произвольную запись. Запросы по атрибутам имеются, что выгодно отличает эти две базы данных от простых key/value баз данных. Однако, произвольность аттрибутов, говорят, ведет к обильному пожиранию дискового пространства. Вобщем тут тоже не без проблем.

На данный момент склоняюсь ко второму варианту. Он хоть архитектурно и не красив, но по крайней мере выглядит наиболее жизнеспособным для реальных боевых условий.