MongoDB и MySQL в Ruby и PHP

    imageНекоторое время назад довольно заинтересовался разработкой для MongoDB и провел некоторые бенчмарки в сравнении с MySQL.
    Изначально только в Ruby, но, когда результаты изумили (в худшую сторону), то и в PHP, для сравнения.
    Может быть, это кому-то сэкономит некоторое время.

    Исходные данные:
    • Система:$ uname -a<br/>Linux pavlin.ik 2.6.31-gentoo-r4 #1 SMP Sun Nov 1 18:21:31 MSK 2009 i686 Intel(R) Core(TM)2 Duo CPU T5450 @ 1.66GHz GenuineIntel GNU/Linux
    • MongoDB v. 1.0.1
    • Gems:
      • gem mongo (0.16)
      • gem mongo_ext (0.16)
      • gem mysql (2.8.1)
      Ruby:PHP 5.2.11-pl0-gentoo with Suhosin-Patch 0.9.7 (cli)
    Исходный код тестов есть тут: http://github.com/latrommi/benchmarking

    Собственно, результаты:
    image

    Вывод один: это не значит, что MongoDB хуже MySQL, это значит, что для нее ещё не написано нормального, быстрого драйвера для Ruby :)

    P.S. будет круто, если кто-то проведет аналогичные тесты для Python.
    P.P.S. пользуясь случаем, передаю привет TravisBickle ;)
    Метки:
    Поделиться публикацией
    Похожие публикации
    Комментарии 60
    • +4
      Спасибо за информацию.
      Не могли бы вы добавить график mysql-php?
      • 0
        Присоединяюсь к вопросу
      • +1
        Добавил.
        PHP, Ruby 1.8, Ruby 1.9, Ruby Enterprise.
        MySQL и MongoDB для каждого.
        • 0
          Спасибо
    • 0
      А чем рисовался график?
    • 0
      Ruby не знаю и могу ошибаться, но, вроде, тестировалась только запись в базу. Вы не погли бы протестировать также, но только на чтение?
      • +6
        Поддерживаю. На самом деле результаты на чтение даже более интересы, нежели insert.
        • 0
          Кому что. У меня была цель сначала протестировать именно insert и именно в реальных условиях (в противовес вставке нормализованных данных в реляционную БД) и только потом find.
          • 0
            Если ваше гипотетическое приложение будет использовать коллекцию в большей степени для записи, а не для чтения, то используйте Capped Collections в Mongo
      • НЛО прилетело и опубликовало эту надпись здесь
        • 0
          Имхо, глупость с выключением. О том что данные в Монго надо будет чинить сказано в документации. Вам это критично? Тогда не используйте. Лично у меня на сервере есть ИБП, чего и всем рекомендую :)
          • НЛО прилетело и опубликовало эту надпись здесь
            • 0
              mysql-myisam тоже не бд?
              mongodb использует mmap()
              • НЛО прилетело и опубликовало эту надпись здесь
              • 0
                > mysql-myisam тоже не бд?
                Да, это не БД. Это записная книжка с SQL-интерфейсом. Для серьезных проектов лучше использовать innodb.
                • 0
                  почему не bdb xtradb или NitroEDB или BrightHouse? :)
                  И если на сервере не журналируемая ФС, то innodb на этом севере тоже не бд?
                  • 0
                    Да все что угодно, хоть постгрес, только не маисам :)
                    • 0
                      это все предрассудки :) myisam хорошо выполняет предназначенные для него задачи — например, это может быть хорошая ферма slave-ов для запросов с беков — лучше чем innodb.
            • 0
              Я к тому, что это не неприятный сюрприз. А задокументированная особенность. Да, она не транзакционная. Да, использовать ее для важных данных не рекомендуют и сами разработчики. Но есть много приложений не столь критичных. Зато у Монго такиииие возможности шардинга, что уххх… И это только начало. Все зависит от того для чего использовать. И как сказал товарищ выше — там где MyISAM часто бывает удобней использовать Монго.
        • 0
          Максим, да, это было бы интересным, но, уже благодаря этому, первоначальному и примитивному исследованию я понял, что MongoDB рановато пока использовать и продолжать тестирование буду только тогда, когда он обновится.

          Во-первых, он пару раз просто упал во время тестов (в логах не было ничего, даже segmentation fault), а во вторых я заинтересован исключительно в Ruby, поэтому подожду, когда хотя-бы однопоточный уровень скорости записи будет соизмерим с PHP, на котором показано, что гипотетический драйвер MongoDB способен на большее.

          В любом случае, продолжение следует.
          • НЛО прилетело и опубликовало эту надпись здесь
            • 0
              Всё по TCP. Над причиной еще предстоит подумать :-)
              • НЛО прилетело и опубликовало эту надпись здесь
          • 0
            хотя-бы однопоточный уровень скорости записи будет соизмерим с PHP


            Я полагаю, что мы обсуждаем web-разработку, а в этом случае делать выводы на основе этого теста некорректно. Единственное, что он объективно показывает, что взаимодействие MongoDB с Ruby более медленное, чем взаимодействие с PHP. А нужно сравнивать поведение MySQL и MongoDB. Я уверен в том, что результат в реальных многопоточных условиях может быть другим. И если MongoDB будет быстрее MySQL, то какая разница в том, что в PHP он работает быстрее.
    • –4
      а напишите выводы по полученным результатам и графикам… как в лабораторной работе в институте, а то возникает ощущение незаконченности исследования
      • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Тест очень синтетический — идет последовательная запись в базу. Это объясняет, почему графики так примитивно выглядят (если ось абсцисс будет в обычной шкале, то мы получим прямые с разным коэффициентом наклона). Если рассматривать MongoDB как замену (дополнение) MySQL в web разработке, то тестироваться должны параллельные запись/чтение.
        • 0
          Все зависит от задачи. Делать выводы по одному этому исследованию некорректно. Можно ведь и жигули с суперкаром тестировать на бездорожье и сделать вывод о том, что разницы в принципе нет.
    • 0
      Было бы гораздо нагляднее предствить график «Mongo vs MySQL» в виде столбчатой диаграммы. То, что увеличение количества операций увеличивает время выполнения и ежу понятно.
      • 0
        При таком количестве рядов диаграмма просто замусорится, если сделать столбчатую диаграмму. В принципе и так все видно, надо не просто смотреть на график вдоль оси абсцисс, а просто сравнивать значения графиков в одной и той же точке (т.е. смотреть на изменение величины вдоль оси ординат).
        • 0
          Ничего подобного. Данные можно сгруппировать по языкам/версиям. Для осознания результатов достаточно только, к примеру 100000, остальное — информационный хлам. Если уж так хочется его использовать, нужно как-то обработать результаты и нормировать их по количеству операций. Графики показывают только динамику процесса. К примеру на 10000 совершенно не понятно чего лучше, а чего хуже.
          • 0
            Ага. Я так и сделал. Посмотри ниже. ;)
    • +1
      Вот есть еще тесты от самих разработчиков www.mongodb.org/display/DOCS/Performance+Testing.
      Но ваши лучше тем что есть исходники :)
    • +1
      Хм, а что если у меня скажем php 5.3 у которой уже типа свой драйвер под MySQL который с ним не плохо я вам скажу работает?
      • 0
        Вообще-то PHP тут притянут просто для сравнения, на его месте так же безопасно мог бы чувствовать себя, например, Python. В тестировании мне интересен исключительно Ruby.

        Если вам не безразличны бенчмарки среди движков PHP, вы можете проделать их сами.
        Я специально оставил исходники в распоряжении читателя :-)
    • +8
      Построил еще несколько графиков по приведенным данным. Извините, что картинки выводятся сразу, но они легковесные: по 8 Кб всего.

      1. Зависимость времени вставки от количества вставок.
      Free Image Hosting at www.ImageShack.us
      Зависимость линейная, как и предполагал shai_xylyd. Видно, что с MySQL у Ruby дела обстоят одинаково, независимо от версии, а вот с MongoDB у Ruby 1.8 самый низкий результат (максимальное время вставки). PHP, тем не менее, пока может дать фору Ruby в работе с базами (по крайней мере при последовательных вставках).

      2. Сравнение времени вставки 100k записей в MySQL и в MongoDB
      Free Image Hosting at www.ImageShack.us
      Ну тут, в принципе пояснять и нечего. Все и так понятно.

      3. Отношение времени, затраченного на вставку в MySQL к времени, ушедшему на вставку в MongoDB.
      Free Image Hosting at www.ImageShack.us
      Для Ruby все почти стабильно. А вот для PHP с ростом количества вставок это соотношение снижается. Может кто-нибудь объяснить почему?
      • 0
        Круто! Особенно последний график интересен.
      • 0
        Может потому, что при вставке многих обьектов возрастает и количество ключей их свойств? Оно ведь тоже растет. Рекомендуется использовать очень короткие ключи вроде «datePublished» → «dP».
    • 0
      Да, кстати, если уж замерять php, то неплохо было бы замерить php 5.3, там все-таки mysqlnd и это совсем не одно и то же как в 5.2.х
    • 0
      вы ос и mysql оптимизировали?

      Покажите db.collection().findone из монго, мне кажется там может быть проблема с типом.
      • 0
        Нет, всё из коробки. Правда для Gentoo понятие «из коробки» несколько растяжимое :)

        Покажите db.collection().findone из монго, мне кажется там может быть проблема с типом.

        > db.bmdb.findOne()
        {"_id": ObjectId( «4af78bb8eb470d23710952bd»), «stub»: «i am empty init doc»}
        • 0
          а count где?
          • 0
            Сорри, не глядя скопипастил инитовую запись.
            Вот, например, первая:

            > db.bmdb.find({«count»:1});
            {"_id": ObjectId( «4af78c6aeb470d23710952bf»), «text»: «i am any text», «count»: 1, «coords»: {«x»: 100, «y»: 200, «z»: 1}}
            • 0
              еще я смотрю в монго не safe insert используется, т.е. прием команды не ждет результат вставки.
              во время тестов где бутылочное горлышко для mongo и mysql
    • +1
      куда-то пропали исходники… nginx выдал not found
      но все же посмотреть успел

      графики вставки не так интересны, как графики выборки (или лучше даже вместе)
      можно написать вставку просто в текстовый файл — и будет заметно быстрее, но явно не есть преимуществом такого подхода

      а еще третий график в коментах плохо соответствует первому… пхп и руби ведут себя линейно в первом графике, а отношение — не очень… странно :)

      жду с нетерпением графика зависимости времени вставок и времени выборок от количества имеющихся в базе записей
      • 0
        это сам сервис github лагает.
        от количества записей скорость не зависит — сложность операций O(1) в обоих случаях.
        • 0
          я себе представлял такую ситуацию:
          от роста количества записей растут индексы, вставка нового индекса — это обычно O(log n)
          но если в многодб линейно, то что же с индексами?
          • 0
            ну не совсем так, b-tree в чистом виде мало кто использует, используется «буфферизированные» вставки для обычных индексов, в этом примере вообще только unique индексы, т.е. это по идее вообще аналог key-value бд. Для выборки сложностью все таки будет одинаковая, для записи она будет немного падать, но на фоне работы с жестким диском выглядит как линейная.

            По опыту — сначала у обоих всегда ложится винт если есть запись и сеть если нет, по расходу cpu mongo выигрывает. mysql пока лучше работает с сокетами и конкурентностью, но у них там планов на следующий год вагон.
    • 0
      У меня возникло подозрение, что Mongo — документоориентированная база данных, а значит Ваш тест не совсем корректен. Может быть cтоит тестировать при сохранении больших объектов?
    • +1
      Правильно ли я понял.
      Тестирование проводилось на одной машине?

      Если так, то это фигня а не тест.

      БД, неважно какая, поделила ресурсы с движком.
      Руби, особенно 1.8 ест побольше чем тот же пых. Соответственно базе осталось меньше. Вот она и сливает. И дрова тут не особо причем.
      • 0
        Драйвер это понятие из архитектуры самой mongo. сама субд там оперирует бинарными объектами, а интерфес для работы с этими бинарными объектами осуществляется в драйвере, в случае php это модуль .so
    • 0
      У MongoDB другой интерфйес же, больше пригодный для ORM, а для MySQL вам придется писать уродливую обертку, которая здорово подпортит производительность MySQL. То есть если вы планируете писать запросы рукми — MySQL конечно круче, а если юзаете ORM — то лучше бросайте это бесперспективное дело :)
    • 0
      Хороший топик, и некоторые комменты порадовали.
      Но вот в чем приколы (!):

      1. MongoDB не дает ответа insert/update/delete, просто глотает. Чтобы узнать успешна ли операция надо в тот же коннект запульнуть специальный запрос и получить ответ.

      2. На каждый коннект выделяется 1 тред, который по порядку выполняет операции приходящие в этот коннект. Поэтому, для нормального бенчмарка надо хотя сделать кол-во коннектов большим или равным 2*кол-во ядер.

      3. В MongoDB операция insert это фактически thread-safe изменение позиции вставки (чтоб два конкурентных инсерта не перезаписали одну и ту же позицию в файле) и собственно mmap. Ну и конечно задроченное заоптимизированное обновление индекса. Это происходит ну очень быстро, нет смысла сравнивать с MySQL и прочими «сложными» базами данных. Упрётесь в сеть/в диск, никак не в CPU и не в архитектурные блокировки.
      • 0
        MongoDB не дает ответа insert/update/delete, просто глотает.
        Если работать через драйвер Python — по умолчанию на insert даёт ответ.
        In [7]: mydb.users.insert({
           ...:     'username': 'test',
           ...:     'password': 'secret'})
        Out[7]: ObjectId('4affa006c8021f0a53000001')

        Разумеется это можно отключить, что даст нехилую прибавку в скорости. 150 000 простых объектов вставляется за 45 секунд. С опцией manipulate=False — за 30.
    • 0
      Я вроде бы не дальтоник, но графика с цветом, заявленном в легенде для mysql-ruby-18, не вижу (темно-синий). Что-то перепуталось :)
      • 0
        Он овпадает с бордовым.
        mysql-ruby-18 ~ mysql-ruby-ent
    • 0
      Про Mongo — будет на DEVCONF — фанаты Mongo — объединяйтесь…
      devconf.ru/phpconf/offers/50

    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.