Содержание
Сегодня мы делимся результатами тестирования php скрипта с и без HHVM на скорость, а также сразу смотрим, как это внедряется, например на Fedora 20. Хотя об этом уже писали здесь, а здесь даже проводили нечто подобное, для верности напомним: HHVM PHP (hip-hop) — это открытая виртуальная машина спроектированная для выполнения программ написанных на PHP и HACK. Использует JIT компиляцию и была разработана в Facebook.
Тест: HHVM + NGINX + FASTCGI vs. PHP-FPM + NGINX
Тестовый скрипт представляет из себя много регулярок, арифметических действий и обращений к базе.
В идеале для тестирования hhvm на скорость в скрипте не должно быть обращений к базе, они присутствуют в тесте только из-за того что он был нужен для текущих дел.
Софт:
Fedora 20
HipHop VM 2.4.0 (rel)
nginx/1.4.4
PHP 5.5.12
Софт для теста: ab.
3000 запросов к скрипту в 10 потоков.
Чистый hhvm 13.665 seconds
Concurrency Level: 10
Time taken for tests: 13.665 seconds
Complete requests: 3000
Failed requests: 0
Total transferred: 2142000 bytes
HTML transferred: 1842000 bytes
Requests 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: 10
Time taken for tests: 31.406 seconds
Complete requests: 3000
Failed requests: 0
Total transferred: 2328000 bytes
HTML transferred: 1842000 bytes
Requests 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 в открытом доступе:
Github
Facebook
Сообщество
Тут можно почитать про технологию:
Википедия на английском
Википедия на русском