LiveStreet и производительность

Статье про простую установку модулей посвящается ;)

Preface


Надо сказать, что если уж говорить серьезно и меряться мензурками, то опыт в сегодняшних frontend-backend системах у меня небольшой, всего полгода.

Начинал я в далеком 2000 году, когда мы в институте разрабатывали интранет-портал на ASP, уже тогда меня не отпускала мысль о том, что контент надо делить на динамический и статический. Но потом судьба распорядилась далеко от Веба, и начиная с 2001 года я стал разрабатывать исключительно приложения под Win32.

Примерно год назад я решил в домашних (ну, почти домашних) условиях попробовать FreeBSD для некоторых вещей и был приятно поражен производительностью (Wikipedia летала на машине с 128 Мб оперативной памяти), поэтому продолжил приятное знакомство.

Полгода назад мы с товарищами начали совместный проект, который вылился в очень интенсивное использование FreeBSD, поэтому я стал совсем фанатом этой системы для Веба, вернее, для связки Apache+MySQL+PHP (Perl, Python, кому как ;)

Приземление


Теперь давайте о LS. Понятная морковка, что это на сегодня самый модульный движок, Максим, спасибо тебе огромное от моего проекта еще раз. Однако давайте смотреть под капот.

В Win32 ты быстро привыкаешь к тому, что статичное связывание может быть в разы быстрее динамического. То есть, монолитное куда как быстрее модульного. И там, где есть динамическое подключение, неважно в каком виде, ты проигрываешь в скорости во имя удобства.

Это всегда так было, и всегда так будет. Еще Unix-way в рассказах серии Rootless root (ценители поймут ;) говорил о том, что нужно делать только одну вещь, но делать ее хорошо. Вот так и с движком.

Динамичность и есть проблема, которая может утянуть движок вниз. И сейчас я покажу, как это влияет, вернее, дам каждому инструмент, чтобы попробовать.

По ходу о .masterhost


Причиной копания в производительности движка стал, как ни странно, Мастерхост. С начала апреля они стали вводить ублюдскую (простите) систему ограничения нагрузки на процессор на вирт. хостинге. Ладно бы, если бы она работала нормально, угу. Она просто сделала из движка медленный газ, или хороший тормоз. Но если бы не она, то не было бы и этого исследования.

Теория


Как можно проверить скорость сайта? Мы все, кто админы под LS каждый день видим внизу табличку со временем выполнения. И при этом мы все, особенно у кого свой хостинг, радуемся, какое малое время там указано. Даю свое:

MySql/запросов: 12/время: 0,015

Cache/запросов: 36/set: 9 get: 26/время: 0,01114

PHP/загрузка модулей:0,03/общее время:0,104

Запустим Excel и немного посчитаем.
Если соотнести время выполнения отдельных кусков к общему, то мы получим следующее:
MySQL: 14% (0,015/0,104)
Cache: 11% (0,011/0,104)
Загрузка модулей PHP: 29% (0,03/0,104)

Окей, но куда же делось остальное время? Ведь если сложить 14+11+29, мы получим всего 54? Да проще простого. Это время выполнения. То есть, загрузка красивых модулей занимает почти треть времени выполнения, и примерно половину времени выполнения занимает само исполнение кода.

Много ли, мало ли, как оценить? Мы только начали, следите за балетом :)

Тесты


Ну давайте найдем, или попробуем найти некий аналог для сравнения. Я решил, что неплохим аналогом станет phpinfo();

Почему так неожиданно? Да все просто. phpinfo() занимается похожими вещами, что и движок LS, т.е оно читает конфигурационные файлы, проверяет загрузку модулей, опрашивает их, и т.д. То есть, я решил принебречь 25% (14+11 :) нагрузки на LS и решить, что phpinfo() и движок LS выполняют похожую работу и сравнить их производительность.

Но как это сделать? В любимой FreeBSD есть порт для замечательной утилиты siege, перевод названия которой с английского означает «осада».

Эта утилита умеет генерировать взрывную нагрузку на сервер, обеспечивая, к примеру, 5 запросов в секунду в течение 30 секунд, или как Вы захотите в настройке. Вкусно? Еще как!

siege


(эта секция подразумевает наличие VPS/VDS-хостинга или своего сервера под FreeBSD 7+, поэтому будьте осторожны)
Права рута у нас должны быть, поэтому идем в порты:
cd /usr/ports/benchmarks/siege


Конфигурировать там нечего, поэтому сразу:
make && make install


Когда пушки отгремят, мы должны попровать вот так:
siege


На моей машине я в ответ вижу примерно такое:
Error: unable to open file: /usr/local/etc/urls.txt: No such file or directory
SIEGE 2.66
Usage: siege [options]
       siege [options] URL
       siege -g URL
Options:
  -V, --version           VERSION, prints version number to screen.
  -h, --help              HELP, prints this section.
  -C, --config            CONFIGURATION, show the current configuration.
  -v, --verbose           VERBOSE, prints notification to screen.
  -g, --get               GET, pull down headers from the server and display HTTP


Ну и так далее. Значит, оно поставилось. Можно начинать насилие :)

Сами тесты


Вообще, настоятельно рекомендую проводить тесты локально, дабы исключить вопросы производительности сети.

В консоли пишем:
siege -c 5 "http://127.0.0.1/" -b -t30s


Теперь рассказываю по порядку:
-c 5 — имитировать одновременно по 5 пользователей. В зависимости от извращенности можно больше :)
"http://127.0.0.1/"
— адрес сайта. Не пытайтесь устраивать так DDoS атаки, оно быстро режется.
-b — режим нагрузки, т.е. пихать 5 пользователей не по одному, а всех сразу.
-t30s — продолжать запросы в течение 30 секунд.

На моей LS 0.2 с выключенным открытым доступом (define('SITE_CLOSE_MODE',true)), т.е. когда левому пользователю, коим без сомнения станет наш siege, я получаю следующие результаты:

> siege -c 5 "http://127.0.0.1/" -b -t30s

Transactions: 1525 hits
Availability: 100.00 %
Elapsed time: 29.78 secs
Data transferred: 2.30 MB
Response time: 0.10 secs
Transaction rate: 51.21 trans/sec
Throughput: 0.08 MB/sec
Concurrency: 4.99
Successful transactions: 1525
Failed transactions: 0
Longest transaction: 0.27
Shortest transaction: 0.05

То есть, сервер успел отдать 51.21 страницу за секунду. И это учитывая, что у меня поднята конфигурация с nginx, т.е. статический контент у меня отдает nginx, apache работает только тогда, когда это и правда надо.

Пока это значение кажется нормальным? Подождите :)

Lifting the server siege… done.
Transactions: 1112 hits
Availability: 100.00 %
Elapsed time: 29.71 secs
Data transferred: 1.00 MB
Response time: 0.13 secs
Transaction rate: 37.43 trans/sec
Throughput: 0.03 MB/sec
Concurrency: 5.00
Successful transactions: 227
Failed transactions: 0
Longest transaction: 5.53
Shortest transaction: 0.02

Вот такую унылую картину я наблюдаю на своем виртуальном хостинге в .masterhost.

Готовы к большему? Давайте же попробуем phpinfo();

Создаем файл с простым кодом <?php phpinfo(); ?>, сохраняем его в качестве phpinfo.php и пробуем натравить на него siege.

Lifting the server siege… done.
Transactions: 9249 hits
Availability: 100.00 %
Elapsed time: 30.31 secs
Data transferred: 80.33 MB
Response time: 0.02 secs
Transaction rate: 305.12 trans/sec
Throughput: 2.65 MB/sec
Concurrency: 4.73
Successful transactions: 9249
Failed transactions: 0
Longest transaction: 5.01
Shortest transaction: 0.00

Втормненоги, простите, то есть, очень быстро. Однако.

Давайте для облегчения совести попробуем прогнать на IIS 7 главную страницу сайта с 5 SQL запросами и ASP.NET 2.0? (Я там руковожу разработкой)

Lifting the server siege… done.
Transactions: 4087 hits
Availability: 100.00 %
Elapsed time: 29.72 secs
Data transferred: 58.71 MB
Response time: 0.03 secs
Transaction rate: 137.52 trans/sec
Throughput: 1.98 MB/sec
Concurrency: 4.75
Successful transactions: 4087
Failed transactions: 0
Longest transaction: 5.02
Shortest transaction: 0.01

Не идеально, но больше чем LS почти в три раза. Почему? Да там нет модулей, там просто монолитный код ;) Поверьте, ASP.NET не может быть быстрее PHP.

И конфигурация серверов у нас везде стандартная, т.е. это P4 Core Duo, 4 GB RAM, x32, как FreeBSD, так и Windows Server 2008.

Выводы


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

В конце концов, настоящие мужчины сами пишут драйвера под свою архитектуру, не так ли?

Всем спасибо за внимание.

С любовью,
maniaque

24 комментария

avatar
Вопросам производительности будет уделено значительное внимание при подготовке следующей версии 0.4. Не могу не отметить некорректность сравнения движка LS и функции phpinfo(), что дезавуирует результаты теста.
avatar
Это, несомненно, смелое утверждение, про версию 0.4, учитывая, что 0.3 еще не вылезла из беты. В моем понимании, оптимизировать не рано никогда, и что-то можно было бы сделать уже сейчас.

Теперь по поводу корректности сравнения. SITE_CLOSE_MODE, как Вы понимаете, делает работу для LiveStreet чрезвычайно простой — нужно всего лишь загрузить конфиг и показать шаблон.

Поэтому не надо говорить о дезавуировании результатов заранее.
avatar
коннект к БД проходит в любом случаи
по поводу загрузки модулей, это обычный инклуд php файла, создание объекта и выполнение метода Init() и только в том случаи если этот модуль необходим. Т.е. это обыкновенное разделение разного кода по файлам — не писать же весь код в одном файле? :)
Так же считаю не корректным сравнение с phpinfo(), ведь это по сути монолитный код зашитый в сам php, написанный на C или на чем то похожем — выполняется в разы быстрее.
Предлагаю привести сравнение с какой нибудь другой CMS.
avatar
Я думаю, нет смысла сравнивать с другими CMS — я, например, все равно пересаживаться не буду. А вот выяснить причину таких скоростей надо бы.

Если у меня будет время, то я попробую Callgrind прикрутить и глянуть. Что-то говорит мне, что самое дорогое с точки зрения производительности — наследование и создание объектов ;)
avatar
в реальном проекте всё рано или поздно упрется в БД, а нагрузку php+Apache можно расширять через балансер до бесконечности.
avatar
Неее, Максим, я тут не согласен. Уже сейчас 50% времени — выполнение PHP, в то время как SQL — 14%, поэтому думаю важнее было бы вылизать именно PHP.

Я сейчас не говорю о больших системах, поскольку все равно, если строить движок под 10000+ посещений, то архитектура PHP не подходит, там надо делать серванты и пр. пр. пр.

Мне кажется, что если сейчас сделать более гибкой загрузку, т.е. не грузит ненужные модули, если они не нужны для выполнения страницы, дало бы неплохой прирост. Личное мнение, конечно.
avatar
т.е. не грузит ненужные модули, если они не нужны для выполнения страницы
сейчас так и есть
avatar
Тогда зачем коннект к БД, если у меня выставлено SITE_CLOSE_MODE?
avatar
это исключение :)
avatar
Exception? :))))
avatar
Мне кажется, что если сейчас сделать более гибкой загрузку, т.е. не грузит ненужные модули, если они не нужны для выполнения страницы, дало бы неплохой прирост. Личное мнение, конечно.

Дык они сейчас так и грузятся… По-дефолту грузится всё из config/config.module.php

А дальше автолоад.
14 процентов это с пятью запросами?)

Хотя касательно

$sCmd='$result=$oModule->'.$aName[1].'('.$sArgs.');';	eval($sCmd);						

Я до сих пор не понял, почему не пользоваться обычными классами и дефолтным автолоадером…

По производительности не совсем понятно чего с ним…
avatar
Производительность eval, как мне кажется, отдыхает, если сравнивать с include.
avatar
исторически сложилось
было два варианта на выбор — этот и статические классы, перевесил первый, наверно из-за моей не любви к статическим :)
avatar
Объясните простому пользователю — сейчас ЛС быстрый движок или нет? Мне на пальцах пожалуйста!
avatar
Быстрый, быстрый. Спите спокойно.
avatar
ну тогда нормально всё :)
просто я тут единсвенный живой человек, который пишет то что думает :)
avatar
который пишет не думая, ага?
avatar
ну это если грубо сказать :) должен ведь кто то быть живой тут ;)
avatar
ASP.NET не может быть быстрее PHP

что за наглое вранье? как раз быстрее может быть и есть, потому что когда мы работаем с ASP.NET мы имеем КОМПИЛИРОВАННЫЙ код, а когда работаем с PHP — ИНТЕРПРЕТИРУЕМЫЙ.

Сколько времени вы работаете с ASP.NET?
avatar
Ох, только не надо тут мне рассказывать :) И обвинять в наглом вранье :)

ASP медленный по одной простой (и тупой) причине — IIS. Если бы не это архитектурное убожище, все уже давно было бы под ASP.

Как показывают тесты (я повторю, тесты, а не логика JIT-компилятора или анализ сборок), FreeBSD демонстрирует превосходство над Windows Server 2008 в одинаковых конфигурациях железа на x32.

В итоге, ASP.NET проигрывает в тех местах, где начинает проверять полномочия вызывающего кода, и т.д., короче, во всем том, чем славится managed код.

PHP, пусть и интерпретируемый, он unmanaged, потому гораздо быстрее. Пока быстрее.
avatar
1) ASP <> ASP.NET. ASP действительно убогая технология по сравнению с PHP.
2) то что Windows Server 2008+IIS требует больше ресурсов чем Apache+nix, об этом я не спорю — это правда. Но учитывая оборудование хостеров вы вряд ли когда-нибудь заметите эту разницу.
3) все и так уже постепенно переходят на ASP.NET — я говорю о крупных проектах. Потому что именно в крупных проектах PHP начинает проигрывать. И одна из причин та, что он интерпретируемый.
4) так что если мы будем сравнивать именно PHP и ASP.NET, то нужно их сравнивать на одной и той же платформе. Я тестировал на Windows + IIS и могу точно сказать, что PHP проигрывает в разы. На nix можно попробовать потестировать Mono. Хотя если уж есть требования использовать nix, то в качестве платформы для веб-разработки я бы выбрал Java (JSP).

P.S. и давайте закончим на этом, к LS это имеет слабое отношение, разве что сделать порт на ASP.NET…
avatar
Кстати, могу попробовать сделать ASP.NET вариант, если конечно автор не против :)
avatar
Уж лучше на Ruby делать или Python)
avatar
комменты про asp.net жгут сразу видно что к чему
  • it_
  • 0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.