Grabduck

Релиз KPHP и движков

:

Довольно часто, выступая на различных конференциях, мы делились желанием выпустить под открытой лицензией KittenPHP, согласно традиции, заложенной крупными IT-компаниями, такими как Google и Facebook.

Это событие несколько раз откладывалось в связи с опасением, что нам не хватит сил и времени на взаимодействие с opensource-сообществом, однако в конце концов заветный день настал, и код KPHP и некоторых других инструментов, используемых внутри проекта, был выложен в открытый доступ.

В связи с этим под катом вас ждет более подробный рассказ о внутреннем устройстве ВКонтакте и тех инструментах, которые сегодня стали доступны opensource-сообществу.


Исходные коды были выложены под лицензиями GNU (GPL и LGPL). Данные лицензии близки нам идеологически, так как при создании этих библиотек мы часто использовали инструменты, лицензированные именно GNU.

Исходный код ВКонтакте разрабатывается на PHP-подобном языке, названном KittenPHP или коротко KPHP. Этот код транслируется в C++ специальным транслятором с одноименным названием. После этого сгенерированный C++ код автоматически компилируется средствами gcc, в результате чего получается бинарник, готовый для запуска. Этот бинарник представляет собой веб-сервер, принимающий http-запросы и генерирующий страницы.
Для того чтобы ускорить процесс разработки, KPHP компилирует различные файлы проекта отдельно, после чего линкует. При последующих компиляциях обрабатываются только измененные файлы, либо, в случае больших по размеру файлов, только их части.

KPHP – минималистичный язык, созданный с целью обеспечить очень высокую скорость работы, без ущерба для удобства и скорости разработки. В связи с этим KPHP поддерживает не все возможности PHP, в частности, в нем отсутствует ООП, за исключением некоторых объектов стандартной библиотеки. Кроме этого не поддерживается eval и связанные с ним вещи, такие как регулярные выражения с модификатором 'e' (вместо этого предлагается использовать функцию preg_replace_callback). Также не поддерживаются функции для работы с определенными элементами массивов first, end, next, prev, current, reset, key; для их замены реализованы функции getValueByPos и getKeyByPos.
Отказ от поддержки большого количества функционала позволил KPHP стать невероятно быстрым по сравнению с другими средствами для веб-разработки.
В качестве примера мы сравнили его с разработанным в Facebook HipHop VM и получили следующие результаты:

Тесты KPHP HHVM PHP
simple 0.000 0.007 0.137
simplecall 0.000 0.004 0.174
simpleucall 0.007 0.008 0.178
simpleudcall 0.007 0.009 0.181
mandel 0.010 0.066 0.392
mandel2 0.011 0.074 0.355
ackermann(7) 0.001 0.011 0.189
ary(50000) 0.003 0.008 0.024
ary2(50000) 0.003 0.010 0.022
ary3(2000) 0.011 0.077 0.191
fibo(30) 0.003 0.019 0.481
hash1(50000) 0.018 0.034 0.044
hash2(500) 0.011 0.021 0.039
heapsort(20000) 0.012 0.040 0.101
matrix(20) 0.007 0.021 0.121
nestedloop(12) 0.000 0.012 0.235
sieve(30) 0.013 0.016 0.114
strcat(200000) 0.002 0.005 0.014
Результаты 0.119 0.442 2.992

Код тестов доступен по ссылке:
gist.github.com/anonymous/9391146#file-bench-php

С точки зрения разработки, KPHP достаточно совместим с PHP, чтобы для быстрого тестирования написанного кода можно было использовать обычный PHP, а компилировать код только перед финальным тестированием и выкатыванием проекта. Для поддержки функций, реализованных в KPHP, но отсутствующих в обычном PHP, была выложена специальная библиотека github.com/vk-com/kphp-kdb/tree/master/vkext, расширяющая возможности PHP.

Кроме того, KittenPHP является хорошим статическим анализатором PHP-кода, указывающим на вероятные ошибки. Например, в процессе перевода ВКонтакте на него год назад было найдено более 20 серьезных багов.

Вместе с компилятором под открытой лицензией разработчики выложили набор движков, которые отлично дополняют KPHP, но могут быть использованы и отдельно от него. Впервые мы анонсировали эти библиотеки opensource-сообществу на Highload 2010, так что просим прощения за достаточно долгий период ожидания.

Надежное key-value хранилище, позволяющее хранить данные без ограничения по времени. По протоколу MC движок работает идентично Memcache, за исключением того, что после перезагрузки все данные остаются.
Помимо своих основных функций, при включении соответствующей опции в конфигурации pmemcached позволяет получать сразу группы записей, у которых префикс ключа соответствует заданному в запросе. Данный движок позволяет хранить и получать различные списки данных.
Одна копия движка может хранить набор списков. Каждый список должен иметь идентификатор (int), по которому с этим списком можно работать.
В каждом списке может быть неограниченное количество элементов. Каждый элемент также должен иметь идентификатор (int), значение (int), флаг (int) и может хранить произвольные 256 символов текста.
Кроме получения списков есть возможность получать подсписки, фильтруя по флагам и сортируя по значениям.

Документация: github.com/vk-com/kphp-kdb/blob/master/docs/ru/KittenDB_Lists.wiki

Модификация движка Lists, позволяющая использовать ключи и идентификаторы записей, состоящие не из одного числа (int), a из заранее заданного в конфигурации движка количества чисел (int). Например, это позволяет создавать списки, ключ которых формируется из идентификатора пользователя и идентификатора записи на его стене.

Документация: github.com/vk-com/kphp-kdb/blob/master/docs/ru/KittenDB_Lists-X.wiki

Предназначен для поиска данных на сайте. Любая текстовая информация может быть проиндексирована в движке с определенным идентификатором, и впоследствии найдена по словам в тексте. В результатах поиска будут возвращены идентификаторы, указанные при индексировании.
Search поддерживает произвольные параметры для поиска по критериям, и специальные параметры для различных сортировок. Также движок позволяет осуществлять сложные группировки и пересечения.

Документация: github.com/vk-com/kphp-kdb/blob/master/docs/ru/KittenDB_Search.wiki

Движок создан для хранения пользовательских данных — фото, видео, аудио, документы. Благодаря хранению различного контента в одном файле и индексированию в памяти смещений, Storage справляется с этой задачей лучше, чем при использовании классического подхода с хранением отдельных файлов в файловой системе.

Документация: github.com/vk-com/kphp-kdb/blob/master/docs/ru/KittenDB_Storage.wiki

Движок Texts позволяет хранить различные текстовые массивы данных. Изначально он был разработан для системы личных сообщений ВКонтакте, но позднее был переиспользован для стен и для комментариев.
Помимо хранения текстов движок поддерживает различные группировки списков с текстами и поиск по текстам. Благодаря нему доступен моментальный поиск по всей личной переписке пользователя, сколь большой бы она не была.
Также в этот движок встроен HTTP сервер, реализующий long poll для получения обновлений с клиентской стороны. Однако позже для этой цели был создан отдельный движок queue, о котором написано ниже.

Документация: github.com/vk-com/kphp-kdb/blob/master/docs/ru/KittenDB_Texts.wiki

Hints решает две важные задачи:
1) Предназначен для поиска объектов пользователя по префиксам слов, используется при быстром поиске на сайте.
2) Позволяет формировать рейтинги объектов, с помощью которых можно упорядочивать списки объектов по степени интереса к ним у пользователя. Например, таким образом работает список друзей ВКонтакте.

Документация: github.com/vk-com/kphp-kdb/blob/master/docs/ru/KittenDB_Hints.wiki

Queue позволяет организовывать общение клиентской и серверной сторон в реальном времени. Клиент подключается к назначенном ему Queue серверу и получает от него обновления, а сервер может в любой момент передать клиенту соответствующее событие. Благодаря использованию каналов, на которые клиент может подписаться при подключении к Queue, движок может использоваться для передачи данных один ко многим, например, когда у пользователя открыта страница новостей, он подписывается в queue на события всех своих друзей, групп и подписок. Когда кто-либо из этого списка публикует запись, он также записывает ее в соответствующую queue-подписку, и каждый подписанный пользователь получает информацию об этом на клиенте, после чего последний может отобразить полученные данные.

Документация: github.com/vk-com/kphp-kdb/blob/master/docs/ru/KittenDB_Queue.wiki

Кроме перечисленных, Вы можете найти в репозитории ряд других, не столь универсальных, но не менее интересных инструментов, документацию к которым вы найдете здесь.

С помощью публикации этих разработок мы возвращаем долг open-source сообществу, которому многим обязаны. 

Мы надеемся, что теперь они помогут разрабатываемым сейчас проектам, как в своё время MySQL, Memcache, nginx и PHP помогли создать ВКонтакте.

Исходный код движков и KPHP Вы можете увидеть в репозитории на github: github.com/vk-com/kphp-kdb
Подробная документация расположена по адресу: github.com/vk-com/kphp-kdb/tree/master/docs/ru