Обзор MongoDB: преимущества и недостатки

Сегодня за 2 часа написал великолепнейшую RSS-читалку. На Ruby. Web-фреймворк - Sinatra. База данных - MongoDB.

О впечатлениях от Монги и хочу рассказать. Работать с этой СУБД невероятно приятно и легко. Никаких таблиц, схем и миграций. Пришел. Увидел. Закодил.

Например, вот как выводится список последних 100 новостей, отсортированных по времени:

get '/news' do
  news = db.collection('news').find.sort(:ts => :desc).limit(100)
 
  erb :news,
      :layout => :layout,
      :locals => {
        :title => 'Новости',
        :news => news
      }
end

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

Потом вдруг решил прогнать тесты на производительность. Тут вся эйфория и улетучилась. ab -c 100 -n 10000 показал всего 140 запросов в секунду. Это при том, что статика на этом же сервере выдается со скоростью 8300 запросов в секунду, а MySQL/PHP в похожих условиях выдает 3500 запросов в секунду. Но даже не это больше всего расстроило. Зацените потребление ресурсов. Напомню, это все тратится на "детскую" нагрузку в 140 страниц в секунду на компе с i5 и 4 Гб ОЗУ:

 2238 mongodb   20   0  509m  40m  11m S  96,0  1,1   3:07.02 mongod                                                                                                    
 8224 architec  20   0  111m  38m 2180 S  47,8  1,0   0:11.05 ruby                                                                                                      
 8216 architec  20   0  111m  38m 2216 S  43,5  1,0   0:10.64 ruby                                                                                                      
 8239 architec  20   0  113m  40m 2184 S  42,5  1,0   0:10.27 ruby                                                                                                      
 8207 architec  20   0  111m  38m 2196 S  41,2  1,0   0:10.95 ruby                                                                                                      
 7052 architec  20   0  175m  41m 2220 S  40,8  1,1   1:10.84 ruby                                                                                                      
 8232 architec  20   0  111m  38m 2240 S  40,5  1,0   0:10.60 ruby                                                                                                      
 6013 root      20   0  120m 6308 3268 S  17,6  0,2   0:37.84 PassengerHelper                                                                                           
 7296 www-data  20   0  362m 5192 1676 S   6,0  0,1   0:02.48 apache2                                                                                                   
 7997 www-data  20   0  362m 4984 1580 S   5,6  0,1   0:02.44 apache2                                                                                                   
 8078 www-data  20   0  426m 4972 1580 S   5,6  0,1   0:02.17 apache2    

Узкое место - Mongo. Что имеем:
1. MongoDB - прекраснейшая СУБД, программировать под которую одно удовольствие.
2. MongoDB не всегда годится на роль замены MySQL. Особенно, если ваш web-проект не предусматривает выделение под MongoDB двух и более отдельных серверов (есть мнение, что только в такой конфигурации начинает раскрываться весь вычислительный потенциал Монги).

Ваша оценка: Нет Средняя оценка: 5 (1 vote)
11
pomodor

И вообще, этот Монга какой-то стремный. Даже без нагрузки в top на первой строчке постоянно.

Ваша оценка: Нет
8
DJ_Baldey

PostgreSQL 9.4 документо-ориентированнее по объёму данных в одной записи (16 мб на запись в Монго и 1 Гбайт в Постгрес)... Ах...

Причём PostgreSQL позволяет организовать поиск по табличке с учётом вероятных фильтров в разрезе реляционных полей и добавить какие-то "не формализованные" документные данные в отдельное поле:

CREATE TABLE "test" 
(
   "id" serial NOT NULL PRIMARY KEY,
   "title" character varying(255) NOT NULL, 
   "filter_id" integer NOT NULL, 
   "detail" jsonb
);
CREATE INDEX "test_title" ON "test" ("title");
CREATE INDEX "test_title_like" ON "test" ("title" varchar_pattern_ops);
CREATE INDEX "test_filter_id" ON "test" ("filter_id");

Ну и хренакаем всё, что не так важно в быстром поиске в поле "detail"...
А потом:

SELECT * FROM "test"
WHERE "filter_id" BETWEEN 10000 AND 1000000
      AND "detail" @> '{"company": "Magnafone"}';
Ваша оценка: Нет
11
pomodor

Это что же такое нужно хранить, чтобы 16 Мб на документ не хватило? :) В документации к Монге сказано, что размер документа в коллекции не должен превышать примерно 200 Кб. Не потому, что Монга не выдержит, а потому, что превышение будет свидетельствовать о неправильном проектировании базы данных. То есть, по коллекциям надо разносить, а не стараться запихнуть все в одну.

А вот за наводку о JSON в Postgres спасибо! Востребованная фича. Надо только протестировать ее на скорость.

и 1 Гбайт в Постгрес

Представил себе такую «табличку». Двадцать записей и хостинг лег. :)

Ваша оценка: Нет
8
DJ_Baldey

Это что же такое нужно хранить, чтобы 16 Мб на документ не хватило?

Цена товара для каждого клиента от нескольких поставщиков, например: 100 поставщиков * 1000 клиентов — с длинными идентификаторами клиентов легко за 16 метров выйти. Такое нельзя организовать простой реляционкой — слишком долгий поиск по названию будет, если у каждого поставщика будет по 10000 товаров.

Вот пример плохой тяжёлой таблицы:

CREATE TABLE good (
 id serial NOT NULL,
 supplier_id integer NOT NULL,
 client_id integer NOT NULL,
 code varchar(50) NOT NULL,
 title varchar(255) NOT NULL,
 price numeric(10,2) NOT NULL DEFAULT 0,
)

А вот пример лёгкой таблицы:

CREATE TABLE good (
 id serial NOT NULL,
 supplier_id integer NOT NULL,
 code varchar(50) NOT NULL,
 title varchar(255) NOT NULL,
 prices jsonb NOT NULL DEFAULT '{}',
)

Представил себе такую «табличку». Двадцать записей и хостинг лег. :)

Понятное дело, что получать полностью такое поле не стоит, а только конкретные данные из него.

Ваша оценка: Нет
Отправить комментарий
КАПЧА
Вы человек? Подсказка: зарегистрируйтесь, чтобы этот вопрос больше никогда не возникал. Кстати, анонимные ссылки запрещены.
CAPTCHA на основе изображений
Enter the characters shown in the image.
Linux I класса
Linux II класса
Linux III класса
Счетчики
  • Самый популярный сайт о Linux и Windows 10
О Либератуме

Liberatum — это новости мира дистрибутивов Linux, обзоры, сборки, блоги, а также лучший сайт об Ubuntu*.