1. Как ВКонтакте использует Go
Презентация -
Алексей Акулович ( )
https://ater.me/gomeetup2015/
https://vk.com/ac
2. Вся backend кодовая база проекта разделена на 4 части:
Все движки: и
Логика сайта:
Скрипты cron и разработка: * и
Data mining и (около-) админские скрипты:
C/C++ Go
KPHP
PHP Go
Python
* PHP работает с движками через vkext: C
3. Всяких движков у нас много:
antispam audiofp copyexec copyfast db-proxy
hints image isearch letters lists
logs logs-db logs-stats magus mc-proxy
memcached meowdb money msg-search mutual-friends
news nginx (module) nostradamus photo playlists
pmemcached queue random rpc-proxy sandbox
search search2 seqmap targ weights
... и т.д. . Но код там старый :(https://github.com/vk-com/kphp-kdb
4. Протоколы взаимодействия с движками и между ними:
Текстовый memcache-совместимый
Свой бинарный RPC
deprecated
$mc>set("request{$prog_id},{$t}", $task);
$result = $mc>get("output{$prog_id}");
неотделим от кодовой базы C/C++
$result = rpcCall('video_cluster',
rpcVideoChange(42, 100500, array(
'title' => 'New video title',
))
);
5. Захотелось использовать RPC не из (k)PHP / C++?
Флаг в руки реализовывать с нуля
acc := &bytes.Buffer{}
scheme.Write(acc, vktl.MagicTlMemcacheGet, `smth_key_value`)
if pkg, err := conn.QuerySendRecv(acc.Bytes()); pkg.IsError {
// ...
} else if pkg.Status == vktl.MagicTlMemcacheNotFound {
// ...
} else {
// используем pkg.RespBody
}
6. Но начнем с самого начала
Вначале была node.js, рассылающая пуши
Но работала она плохо и досталась мне
Эксперимент: реализация APNS пушилки на Go
7. Что из себя представляет одна пушилка (что nodejs, что go):
API over HTTPS => пачки пушей
Пачки пушей => распределение по GCM, APNS, MPNS/WNS
GCM и т.п. => распределение по приложениям
Приложение => распределение по соединениям
Обработка соединений
+ сбор статистик, логирование, самомониторинг
9. Что из себя представляет одна пушилка (go):
API over HTTPS => пачки пушей ( )
Пачки пушей => распределение по GCM, APNS, MPNS/WNS ( )
GCM и т.п. => распределение по приложений ( )
Приложение => распределение по соединениям ( )
Обработка соединений ( )
+ сбор статистик, логирование, самомониторинг ( )
~5 go, 1 chan
4 go, 4 chan
4 go, ~100 chan
~100 go, ~5-10k chan
~5-20k go, ~10-20k chan
~10 go, ~5 chan
10. Что из себя представляет одна пушилка (go):
ulimit -n не менее
memory rss
паузы gc (пока это работает на golang 1.4)
cpu из 16 ядер - запас роста еще раза в три
время обработки пуша *
10000
~500M-1G
~50мс
200-500%
40-900мс
11. Что из себя представляют все пушилки:
сервера
пока что до миллиардов отправленных пушей в день
( /сек с сервера)
24
7
>3k
14. Большинство имеющихся наших C/C++ движков - однопоточны
Шардирование на несколько инстанций/ядер дробит
адресуемую память
Хочется использовать много ядер на единой адресуемой памяти
Здравствуй, Go!
* Все в одну машину все-равно не влезет, так что лишь используем по максимуму
15. Новый движок должен вести себя как остальные:
Сериализация/десериализация всех типов данных и запросов
Быть полноценным RPC сервером
server handshake
ping/pong
stats
Быть RPC клиентом
client handshake
forwarding
Писать совместимые бинлоги и снапшоты
Ожидаемо обрабатывать сигналы
Иначе этот движок никто не примет
16. Это все уже реализовано на "чистом" Go.
Выдает больше 120к RPS на ноутбуке, что для нас
пока вполне достаточно.
Код (tlscheme и rpc) лежит в приватных репозиториях
на github, и будет открыт по готовности.
Будет первым полноценным движком на Go (не считая cgo).
Клиентская часть позволяет переносить тяжелые PHP cron
скрипты на Go.
17. Планы по использованию Go:
Принят в стек разработки адекватно;
Сишники не будут использовать Go;
Код сайта не будет переписываться с kPHP на Go;
Отдельные специфические движки и задачи могут
получить воплощение на Go;
Соотвественно, язык остается уделом PHP'шников :)
18. Вопросы?
Рассылка пуш уведомлений на Go
Если вопросы возникнут позже
Документация по движкам
http://habrahabr.ru/post/265731/
https://vk.com/ac
http://vk.cc/4fg1Sn