HHVM (hip-hop): Сравнительное тестирование и настройка

imageСегодня мы делимся результатами тестирования 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 раза.

Замеры фрагментов кода внутри скрипта:

image

image

Графики построены по средним показателям за 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 image

Конечно, применить 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Сообщество

Тут можно почитать про технологию: Википедия на английскомВикипедия на русском

© Habrahabr.ru