HHVM (hip-hop): Сравнительное тестирование и настройка
Сегодня мы делимся результатами тестирования php скрипта с и без HHVM на скорость, а также сразу смотрим, как это внедряется, например на Fedora 20. Хотя об этом уже писали здесь, а здесь даже проводили нечто подобное, для верности напомним: HHVM PHP (hip-hop) — это открытая виртуальная машина спроектированная для выполнения программ написанных на PHP и HACK. Использует JIT компиляцию и была разработана в Facebook.
Тест: HHVM + NGINX + FASTCGI vs. PHP-FPM + NGINXТестовый скрипт представляет из себя много регулярок, арифметических действий и обращений к базе.
В идеале для тестирования hhvm на скорость в скрипте не должно быть обращений к базе, они присутствуют в тесте только из-за того что он был нужен для текущих дел.
Софт: Fedora 20HipHop VM 2.4.0 (rel)nginx/1.4.4PHP 5.5.12
Софт для теста: ab.3000 запросов к скрипту в 10 потоков.
Чистый hhvm 13.665 seconds
Concurrency Level: 10Time taken for tests: 13.665 secondsComplete requests: 3000Failed requests: 0Total transferred: 2142000 bytesHTML transferred: 1842000 bytesRequests per second: 219.54 [#/sec] (mean)Time per request: 45.549 [ms] (mean)Time per request: 4.555 [ms] (mean, across all concurrent requests)Transfer rate: 153.08 [Kbytes/sec] received
nginx-fastcgi-php 31.406 seconds
Concurrency Level: 10Time taken for tests: 31.406 secondsComplete requests: 3000Failed requests: 0Total transferred: 2328000 bytesHTML transferred: 1842000 bytesRequests per second: 95.52 [#/sec] (mean)Time per request: 104.688 [ms] (mean)Time per request: 10.469 [ms] (mean, across all concurrent requests)Transfer rate: 72.39 [Kbytes/sec] received
Вывод: hhvm быстрее в 2.29 раза.
Замеры фрагментов кода внутри скрипта:
Графики построены по средним показателям за 1000 замеров.
По итогам замеров фрагментов кода видно что HHVM быстрее в 2,77 раза чем NGINX-FASTCGI-PHP.На графике синим отмечен наиболее ускоренный участок кода (масса регулярок), он был ускорен в 113 раз!
Практическое применение Задача: У нас есть проект, который обрабатывает очень много запросов. По этому проекту — около 10 серверов. Нужно в несколько раз сократить ресурс — либо меньше серверов, либо меньше данных.
Решение: Виртуальная машина для ускорения производительности HHVM устанавливается на сервер и через неё можно прогонять выполнение php скриптов. Результат: необходимое ускорение.
Подобный способ решения тем больше подходит, чем больше масштаб: если это большой проект в масштабах Facebook (создатели HHVM), в котором задействованы десятки тысяч серверов — сокращение их в два-три раза даёт ощутимый результат. По результатам нашего тестирования — на некоторых участках кода можно разогнать его в 113 раз –, но об этом позже.
Конечно, у всего есть свои плюсы и минусы, HHVM не исключение, поэтому целесообразно сразу их обозначить:
Плюсы: • ускорение выполнения PHP (в моём тесте на крупном блоке регулярок было ускорение в 113 раз, в целом же тестовый скрипт был ускорен в ~2 раза по причине большего количества обращений к бд.).
Минусы: • не поддерживает php-mysqli (нужно использовать mysql или PDO)• наблюдались падения сервера с PHP ошибкой о неожиданной встрече конца файла (после перезапуска сервера он продолжал работу).
Внедрение: Установка и настройка HHVM PHP (hip-hop) на Fedora 20
Конечно, применить HHVM для ускорения PHP — штука довольно очевидная и наверняка кто-то это уже делал, даже для Fedora. Но в русских источниках по этой теме информации значительно меньше, чем хотелось бы, поэтому делюсь сегодня небольшим, но вполне самодостаточным tutorial, от начала и до конца, как установить это на Fedora и проверить работу.
Я использовал Fedora 20, однако настройка для других ОС в принципе похожа, а ссылку на англоязычный источник для них можно найти в конце поста. Удобно то, что сейчас готовые пакеты ставятся одной командой — их не надо собирать в ручную. «На заре» HHVM открытые исходники было сложно устанавливать, но сейчас это, к счастью, уже в прошлом: теперь, если действовать по мануалу, можно установить всё и проверить, в принципе, за час. Настройка и установка укладывается в 6 последовательных шагов.
Шаг 1: Добавление репозитория в систему Первым делом, добавляем репозиторий в нашу систему. Для этого создадим и откроем файл на редактирование /etc/yum.repos.d/hhvm.repo
Это можно сделать например так: vi /etc/yum.repos.d/hhvm.repo
Запишем в него следующие строки:
[hhvm] name=HHVM for Fedora $releasever — $basearch baseurl=http://dl.hhvm.com/fedora/$releasever/$basearch/ Если вы пользуетесь редактором vi то после открытия файла нажмите «i» затем введите строки, далее нажмите Esc и после нажмите Shift+z+z.
Затем устанавливаем HHVM: rpm --import http://dl.hhvm.com/conf/hhvm.gpg.key yum install hhvm
Во во время установки возникнет диалог о инсталляции требуемых компонентов (Is this ok [y/d/N]:). Отвечаем — «да», командой: y
После этого мы видим список установленных компонентов и в конце строку «Complete!».
Далее идём править конфиг — /etc/hhvm/config.hdf.
Например так:
vi /etc/hhvm/config.hdf
Вот пример рабочего конфига (скорей всего в нём вам нужно будет изменить только корневой путь):
Log { Level = Error UseLogFile = true File = /var/log/hhvm-error.log Access { * { File = /var/log/hhvm-access.log Format = %h %l %u %t \»%r\» %>s %b } } } MySQL { TypedResults = false } Server { Port = 4849 #порт на котором будет работать hhvm SourceRoot = /home/www/site/public_html #путь к корню ваших php файлов Type = fastcgi #ThreadCount = 50 } Eval { # set to true to enable JIT compiler # If hhvm crashes you can turn this off to see if the problem # is in the JIT. Jit = true } Заменяем конфиг по умолчанию на тот, что предложен выше, и правим корневой путь.
Шаг 2: запуск HHVM Теперь мы можем запустить HHVM. Здесь у нас два варианта — запуск в моде сервера или в моде демона.
Запуск в моде сервера — будет вывод прямо в консоль ошибок и прочего: hhvm -m server -c /etc/hhvm/config.hfd
Запуск в моде демона — фоновая работа: hhvm -m daemon -c /etc/hhvm/config.hfd
Если вы в конфиге hhvm закомментируете — Type = fastcgi (#Type = fastcgi), то можно прям сейчас проверить его работу. После правки конфига нужно перезапустить hhvm.
Чтобы перезапустить hhvm в режиме демона вводим: netstat -lnp
Видим список программ и их pid, находим hhvm, копируем его pid, вводим команду. kill pid В этой команде pid заменяем на найденный в списке номер процесса. Вводим повторно netstat -lnp для того чтобы убедится в смерти процесса. Далее запускаем hhvm в любом из модов.
Чтобы перезапустить hhvm в режиме сервера просто нажимаем Ctrl+c и далее запускаем hhvm в любом из модов.
Шаг 3: Добавляем PHP скрипт После этих манипуляций положим любой php скрипт в корневой каталог указанный в конфиге hhvm.
Обращаемся к нему следующим образом: http://поменяй_на_свой_домен:4849/имя_php_скрипта.php
Если обработанного php скрипта не видим то смотрим лог ошибок в консоли (в случае hhvm -m server), либо в файле лога ошибок командой tail /var/log/hhvm-error.log (в случае hhvm -m daemon).
Далее, если вы тестировали hhvm и закомментировали Type = fastcgi в конфиге, то раскомментируем его и перезагружаем hhvm. Если вы этого не делали то оставляем всё как есть и идём дальше.
Шаг 4: Настройка NGINX Настроим nginx для проброса fastcgi в hhvm. Для этого модифицируем конфиг nginx, он тут /etc/nginx/nginx.conf. Там должна появиться следующая запись:
location ~ \.php$ { #Не забудьте поправить пути на ваши (/home/www/site/public_html). root /home/www/site/public_html; fastcgi_pass 127.0.0.1:4849; # проброс запроса к hhvm fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /home/www/site/public_html$fastcgi_script_name; include fastcgi_params; } Остальные настройки nginx по вкусу (главное чтобы он слушал 80 порт — server {listen 80;}). После этого перезагружаем nginx командой: nginx -s reload
Теперь мы имеем связку nginx — впереди на 80 порту, hhvm — позади на 4849 порту.
Шаг 5: Проверка работы HHVM + NGINX + FASTCGI Запрашиваем адрес: поменяй_на_свой_домен/имя_php_скрипта.phpДолжны увидеть обработанный php скрипт.Не забываем что nginx и hhvm должны быть включены.Если скрипта не видим идём смотреть лог ошибок. В случае hhvm -m server, прям в консоли, в случае hhvm -m daemon в файле лога ошибок например так: tail /var/log/hhvm-error.log
Вот на всякий случай рабочий конфиг nginx для связки c hhvm:
user apache; worker_processes 10; events { worker_connections 1000; } worker_rlimit_nofile 50000; http { include mime.types; default_type application/octet-stream; log_format my_combined '$remote_addr — $remote_user [$time_local] ' '»$request» $status $body_bytes_sent ' '»$http_referer» »$http_user_agent» ' '$upstream_response_time »$host»' sendfile on; keepalive_timeout 10; limit_zone lconn $binary_remote_addr 10m;
server { client_max_body_size 1000k; fastcgi_read_timeout 1m; listen 8080; listen 80; server_name site.ru; #меняем на свой домен access_log /var/log/nginx/site.ru-access_log my_combined; #меняем на свой домен error_log /var/log/nginx/site.ru-error_log; #меняем на свой домен limit_conn lconn 100; root /home/www/site/public_html; #меняем путь на свой index index.php index.html index.htm; error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } location ~ \.php$ { root /home/www/site/public_html; #меняем путь на свой fastcgi_pass 127.0.0.1:4849; fastcgi_index index.php; #меняем путь на свой fastcgi_param SCRIPT_FILENAME /home/www/site/public_html$fastcgi_script_name; include fastcgi_params; } } } Шаг 6: Добавление HHVM в автозагрузку Если вы будете использовать hhvm постоянно вам нужно будет добавить его в автозагрузку.
Открываем файл — /etc/init.d/hhvm на редактирование например так:
vi /etc/init.d/hhvm
Заменяем всё его содержимое на следующее:
#! /bin/sh # # hhvm Daemon for HHVM # # chkconfig: 2345 20 20 # # description: HHVM is an open-source virtual machine designed for executing programs written in Hack and PHP
test -x /usr/bin/hhvm || exit 0
case »$1» in start) /usr/bin/hhvm --config /etc/hhvm/config.hdf --mode daemon ;; stop) start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/hhvm/pid ;;
reload|force-reload|restart|try-restart) $0 stop $0 start ;;
status) echo «No status» ;;
*) echo «Usage: /etc/init.d/hhvm {start|stop|restart|status}» exit 1 esac
exit 0
Сохраняем.Затем вводим команду: chkconfig hhvm on
Готово! Демон hhvm будет запускаться при старте системы.
Конечно, у каждого свой путь — как конкретно это интегрировать, каждый решает сам. Тем не менее здесь всё работает именно так и собралось за минимальное количество времени — думаю, вполне можно исппользовать в живых условиях, когда нужно неплохо так сэкономить на количестве серверов, тем более если сделать это можно на основе решения с открытым кодом.
Тут об этом уже писали ранее: ОбзорУстановка HHVM на NginxТест: сравнение HHVM с нативным интерпретатором
Тут можно взять HHVM в открытом доступе: GithubFacebookСообщество
Тут можно почитать про технологию: Википедия на английскомВикипедия на русском