Каждый день нагрузки на социальные сети возрастают. И если за заре их создания перед разработчиками не стояла задача столь экстремальной производительности, то сейчас времена изменились. Необходимо решить две крупных задачи: адекватно трансформировать ту кодовую часть проектов, которая была написана на PHP, и сохранить текущие наработки общей совместимости. Фактически, необходим компромисс, который бы позволил существенно увеличить производительность PHP, при этом сохранив всю накопленную кодовую базу.
Итак, рассмотрим хронологию создания и принципы HipHop (Facebook) — системы трансляции PHP-кода в бинарные приложения. В качестве бонуса мы сравним ее с новоиспеченным kPHP от ВКонтакте и совсем немного посплетничаем...
Исторически решение этой задачи по оптимизации было многошаговым. Но первым, самым важным и инициирующим весь процесс шагом было создание собственного транслятора исходного кода PHP, который чуть позже был сделан полностью открытым для интернет-сообщества проектом. По сути HipHop (а точнее, его компилятор — HPHPc) получает на вход дерево исходников обычной PHP-программы. В процессе своей работы он программно анализирует и транслирует весь исходный PHP-код в функционально эквивалентный и оптимизированный исходный код на C++.
В качестве второй, уже чисто сервисной функции HPHPc компилирует сгенерированные им исходники с помощью компилятора g++ в полноценные бинарные и исполняемые файлы.
Общий алгоритм работы HiHop:
И хотя мы перечислили все логические шаги по трансформации программы, следует дополнительно отметить, что HipHop, на самом деле, нечто большее — это скорее самодостаточная экосистема, чем просто обычный кросс-транслятор. Кроме собственного веб-сервера и среды исполнения (HipHop server), сюда также входит набор популярных расширений используемых в мире PHP, которые были заранее переписаны на «чистом Си», при этом сохранив стандартные старые API-интерфейсы, а значит, и совместимость.
В HPHPc обеспечена не эталонная 100-процентная поддержка оригинального PHP: некоторые динамические возможности PHP (например, оператор eval()
) просто игнорируются и не включаются в транслируемый код.
Как сразу вытекает из разобранного базового алгоритма, важный недостаток HPHPc в том, что после каждого изменения исходной PHP-программы требуется полная повторная перекомпиляция всей среды. Это достаточно неудобная и ресурсоемкая операция для больших приложений, особенно находящихся в стадии постоянной интенсивной разработки.
Как реакция на эту проблему, в рамках HipHop for PHP вскоре появился специальный подпроект — HPHPi. Это почти «интерактивная версия» HipHop, которая в значительной мере автоматизирует цикл перекомпиляции, выполняя ее избирательно и в фоновом режиме. Существенным недостатком именно этого решения стало то, что поведение HPHPi несколько отличается от поведения стандартного HPHPc. Модифицированный алгоритм работы иногда приводит к тому, что некоторые ошибки, которые отсутствовали на стадии тестирования на серверах разработчиков с установленным там в целях удобства отладки HPHPi, неожиданно всплывали на промышленных серверах с HPHPc. Кроме того, очевидно требовалось параллельное совместное использование этих двух разных движков, что еще больше раздувало инфраструктуру и лишало ее унификации.
Продолжая анализировать и упорно совершенствовать уже упомянутые инструменты своего проекта, Facebook в итоге пришла к достаточно неожиданному и радикальному новому решению — HHVM (HipHop virtual machine). Теперь эта виртуальная машина, которая в чем-то похожа на оригинальный PHP-интерпретатор, в режиме реального времени компилирует PHP-скрипты в байткод, запуская последний в виртуальном машинном окружении. Здесь читатель может вполне справедливо удивиться: зачем был пройден столь длинный эволюционный путь, чтобы в итоге получить по устройству нечто похожее на исходный вариант?
Ответ скрыт в интересных особенностях нового JIT-компилятора, который был создан полностью с нуля силами Facebook, и который снимает упомянутые сложности с промежуточным решением HPHPi, при этом еще больше ускоряя запуск PHP-скриптов по сравнению с HPHPc. Если абстрагироваться от многочисленных деталей и мелких улучшений, главная суть сводится к трем главным новшествам:
Тем, кто ознакомился с этим довольно длинным и сложным эволюционным путем, в качестве десерта предлагаю некоторые цифры и факты, которые более ярко характеризуют эти такие разные 3 инкарнации проекта HipHop for PHP:
Как логичный результат этого поступательного развития, уже в текущей сборке HipHop for PHP ее наиболее проблемная составляющая HPHPi помечена как «нежелательная к использованию» (она будет отключена в ближайших релизах). В связи со ставкой на HHVM еще в 2012 году было анонсировано, что основная на тот момент подсистема HPHPc также постепенно будет переведена в статус «не рекомендовано для использования».
И вот историческое для Facebook событие — в мае-июне текущего 2013 года серверы Facebook полностью перешли с HPHPc на HHVM. В связи с этим на Github был выложен исходный код виртуальной машины, а также уже собранные пакеты для Ubuntu 12.04, Debian 7 (wheezy) и Centos 6.4 (в самое ближайшее время будет добавлен пакет и для FreeBSD 9).
Показательно, что вместе с бурной эволюцией HipHop for PHP разительно менялось даже само определение проекта на его странице.
После беглого обзора всех стадий развития будет уместно привести текущее и наиболее точное (последнее на данный момент) определение этого проекта: HipHop for PHP — это набор разных движков исполнения для PHP-приложений, предназначенных для ускорения исполнения PHP-приложений, расширения их возможностей и качества разработки.
И вот на последней составляющей из этого определения, которой большинство интернет-разработчиков не уделяет никакого внимания в рамках среды HipHop (мы тоже пока были сосредоточены именно на технологиях ускорения запуска PHP-скриптов), предлагаю остановиться отдельно.
Для начала маленькое терминологическое пояснение, о чем пойдет речь в этом пункте.
Как известно, статический анализ — это разновидность анализа ПО проводимая без реального выполнения (запуска) исследуемых программ (обратное понятие — динамический анализ кода). Практически любой компилятор проводит простейший статанализ исходного кода программы в том или ином виде (большая часть так называемых «warnings» — это следствие работы именно этого типа анализа), для более серьёзного исследования применяется специализированный класс продуктов — статистические анализаторы.
В случае же с HipHop при полной трансляции исходного кода из одного языка программирования в другой, выполняется неизбежный глубокий статический анализ исходного кода, что автоматически превращает HipHop в продвинутый статический анализатор для языка PHP. Согласно слов Расмуса Лердорфа (создателя PHP) на последней конференции Devconf:
«статический анализатор встроенный в HipHop способен сделать в 10 раз больше полезных вещей, чем обычный синтаксический парсер РНР».
Переходя к практической части этого пункта, сообщим, что воспользоваться напрямую низкоуровневыми возможностями HipHop для подобного анализа своего PHP-кода относительно не сложно. Но ниже я бы хотел рассмотреть иной, более комфортный способ — сделать это на базе специализированной командной оболочки к анализатору HipHop — HPHPa. Она очень легко инсталлируется через систему управления классами PEAR (необходимы права root-пользователя):
pear config-set auto_discover 1 pear install http://pear.phpunit.de/get/hphpa-1.2.2.tgz
Сразу после установки, вы найдете этот PEAR-пакет в стандартном каталоге для библиотек PHP-классов, в большинстве случаев для гипотетического пользователя testusr
это будет папка /usr/lib/php/testusr/HPHPA
.
Приведу пример его простейшего запуска:
$ hphpa /usr/local/src/code-coverage/PHP hphpa 1.2.2 by Sebastian Bergmann. Using ruleset /usr/share/pear/data/hphpa/ruleset.xml /usr/local/src/code-coverage/PHP/CodeCoverage/Filter.php 206 TooManyArgument: $this->addFileToWhitelist($file, FALSE)
В данном случае в соответствии со списком правил заданных в ruleset.xml анализатором был проверен единственный файл Filter.php, и в результате в 206 строке заданного скрипта была обнаружена ошибка «TooManyArgument». Кроме того на выходе был сгенерирован файл hphpa.xml со списком всех обнаруженных ошибок.
В завершении отмечу, что генерация XML-логфайла может быть настроена в соответствии с заданными вами правилами, что позволит применять ныне популярную практику «Непрерывная интеграция» (Continuous Integration).
Крупнейшая российская социальная сеть ВКонтакте, которая также растет буквально на дрожжах, аналогично работает на PHP, поэтому столкнулась в процессе роста с сопоставимыми по сложности проблемами. В том же мае-июне 2013 г., одновременно с Facebook, она осуществила миграцию на собственный вариант PHP-ускорителя — kPHP. Для искушенной webdev-публики таинственный незнакомец kPHP стал во многом тем же HipHop’ом, только намертво сращенным с APC (с которым HipHop с недавних пор также идет в одном комплекте). В чём же тогда отличия и новизна kPHP, с дурным скепсисом вопрошают отечественные люди-разработчики?
Собщается, что kPHP поддерживает большинство стандартов обычного PHP, но работает якобы быстрее своего американского аналога и предоставляет дополнительные возможности оптимизации. Позже, как клятвенно пообещал Дуров, ВКонтакте предоставит код kPHP в открытый и свободный доступ для всех разработчиков мира.
На изображениях ниже можно оценить замеры-изменения по скорости работы соцсети ВКонтакте до и после ее перехода с чистого PHP на kPHP:
Что же касается многочисленных сравнений с HipHop, то вот как сам Вождь нескромно поясняет эту деликатную тему:
На всех тестах было неудобно за PHP HipHop. Либо Facebook дал в общий доступ сильно испорченную версию, либо мы разработали нечто принципиально лучшее. Это касается не только скорости работы скомпилированного кода, но, в первую очередь, скорости компиляции.
И тут время ясно сформулировать главный приоритет и глубинную причину клонирования HipHop создания kPHP — это максимально возможное увеличение скорости выполнения PHP. Якобы именно по этой причине ВКонтакте не устроил HipHop, также нарекания вызвала высокая сложность и нестабильность сборки конкурента.
Так, разработчиками vk.com утверждается, что скорость выполнения кода в среде kPHP увеличилась более чем в 10 раз (при условии идеальных внешних условий, то есть отсутствия лагов/ожидания ответов со стороны БД и т.п.).
Программисты также заявляют, что после перехода на kPHP они стали использовать почти в два раза меньше серверов для обработки пользовательских запросов, при этом нагрузка осталась прежней.
Информации о потрохах kPHP пока мало, ниже я попробовал перечислить все факты, которые уже стали известны публике:
В силу отчаянной противоречивости последнего пункта — это когда среда изначально была «вылита» с откромсанной поддержкой ООП, а сами разработчики гордо заявляют о ее будущей реализации — придется остановиться на истолковании этой шизофренической вконтактовской дихотомии.
Те немногие утечки, которые есть на эту тему, позволяют дать следующую трактовку происходящего.
В данный момент используются некие «высокооптимизированные» самописные движки БД, о которых лишь известно, что в будущем их исходный код будет также открыт широкой общественности (уже шаблонная оговорка — «вот только сейчас код немного подчистим, и сразу выложим»). Сейчас они взаимодействуют с внешним миром на базе хорошо известных memcache-совместимых протоколов.
Существует мнение, что именно этот протокол является наиболее узким местом в производительности всей системы. Поэтому в качестве ответа на этот серьезный вызов, в игру введен сам родной брат главного Дурова aka Вождя — Николай Дуров, — который и разработал, как это водится в таких случаях, не размениваясь по мелочам — «принципиально новый» универсальный протокол MTProto. Недавно сетью ВКонтакте была развернута бодрая движуха, в частности, начата компания популяризации этого протокола, где делается попытка создания рабочих клиентов на его базе.
Впрочем, как сообщают голоса в моей голове некоторые слухи, в скором будущем этот специализированный и более лаконичный протокол может заменить те самые memcache-совместимые интерфейсы в натруженной утробе ВКонтакте.
В связи с этим, поскольку этот новый бинарный протокол использует объектную TL (схема типов этого протокола), разработчики kPHP внезапно осознали... что им все-таки нужен уже выпиленный ООП!
Впрочем, я бы не ерничал в этом месте, потому как любой разработчик, имевший дело с долгосрочными и сложными проектами, как мне кажется, самолично и многократно наблюдал похожие жестокие для самооценки любого системного архитектора сюжеты вызывающие отчаянное желание немедленно переписать все с нуля. Подмечено, что такие, отчасти неловкие озарения, обычно случаются аккурат после успешной сдачи и завершения проекта.
Что ж, это еще раз подчеркивает, насколько захватывающим и противоречивым может быть жизненный цикл по-настоящему сложных и амбициозных программных продуктов.
Что же касается самого MTProto (который получился сильно навороченным с креном в сторону безопасности и шифрования), то будем надеяться, что его не постигнет фейл Mail.ru с их типа «совсем новым» протоколом WebRTC. Сравнивать же HipHop с kPHP на полном серьёзе мы будем лишь после релиза исходников последнего.
HipHop, равно как и kPHP, весьма хороши сразу по нескольким причинам. Любой перспективный интернет-проект написанный на популярном ныне PHP и разросшийся со временем до космических размеров, неизбежно упрётся в естественные для этого скриптового языка пределы производительности и масштабируемости, как это и случилось с Facebook. В процессе поддержки своего «большого и старого кода» эта компания долгое время занималась различными оптимизациями PHP, в частности движка Zend Eingine. Но по-настоящему переломить ситуацию с недостаточной производительностью смог лишь такой радикальный шаг, как создание новой комплексной технологии — HipHop.
Поэтому с одной стороны открытие исходников подобных проектов даёт возможность и другим большим компаниями применять это готовое решение как выход из сложной ситуации — реальную альтернативу отчаянному желанию «переписать всё с нуля в соответствии с текущими вызовами». С другой стороны, стоит отметить, что применять подобную тяжелую артиллерию есть смысл только по отношению к по-настоящему большим и высоконагруженным проектам, где с помощью HipHop/kPHP они смогут вдохнуть вторую жизнь в свои высоконагруженные проекты на PHP.
Update: Свершилось — публичный релиз KPHP и его движков.
9 комментариев
Больше похоже на затравливание HipHop в умах отечественных разработчиков.
Настаивание на бессмысленности сравнения, очевидность неочевидных вещей, отсутствие внятных бенчмарков на разных тестах.
Упор на то, что разработали победители ACM (в фейсбуке, получается, бомжи с площади 3 вокзалов за бутерброд писали).
Пока для меня это выглядит на подражание "большим дядям". Их благо, если преимущества после релиза увидят не только они.
Пренебрежение kphp это не более чем перенос хипстерского пренебрежения контактом в сферу программирования
PS Слоник похож на путина ? 0о
Вы не разобрались в mtproto. Это никак не замена memcached-like протокола.
> В частности, не так широко известен факт, что заявленный в релизе PHP 5.3 скачок
> производительности в 10% — почти полностью вклад инженеров Facebook
А это кто сказал? И что они такого сделали?
Спасибо за статью. Интересно было узнать эволюцию HipHop. Лично, мой 10 летний опыт показывает, что написать трансформатор синтаксиса с одного языка на другой много ума не надо, где идет тупая замена
$foo='abc' на char* foo = "abc"; или $bar = 123; на int bar = 123;
Все грабли начинаются, когда начинаешь использовать фишки, давно уже зарекомендовавшими себя как "НЕ РЕКОМЕНДУЕТСЯ к использованию" с eval(), есть такая шутка: eval EQ evil,
или фишки, типа: $$name = 'foo';
$this->$name = 'action_1'; $this->$name(); или $payType = new $currPayType();
Специально для таких случаев были придуманы Шаблонный метод или Фабрика. Вот, чтоб применить уже эти алгоритмы при переводе с одно синтаксиса в другой и придется помозговать. Вот от сюда и все сложности, и ООП ограничения.
А вообще я за VK рад, что сделали что-то своё... Но будет ли это общее, еще вопрос.
> HipHop, равно как и kPHP, весьма хороши ... перспективный интернет-проект ... разросшийся со временем до космических размеров, неизбежно упрётся в ... пределы производительности и масштабируемости
Упереться то упрется, но часто ли сейчас встретишь проекты без ООП? Я пока слышал только про один - ВК :)
> что драматически ускоряет работу откомпилированных скриптов на современных
Дословный перевод слова dramatically. Синоним в русском языке -- существенно.
Как же Вам не нравится ВКонтакте и их деятельность...
Да, ещё и не забываем, что Вконтакте очень много перекладывает на клиентскую часть - браузер. Вот тут тоже очень много правды. Ибо юзают хранилища и прочие фишки. В отключенном варианте всё более плачевно. А также ВК с выключенным javascript даже не работает.
Так что немного согласен с "мутками" разрабов ВКонтакте, однако не согласен, что нам не дали никаких тестов сравнения kPHP и HipHop.