- PVSM.RU - https://www.pvsm.ru -
Нам очень нравится формат AMA (ask me anything) [1] на Reddit, когда кто-нибудь (в нашем случае – команда разработчиков) приходит в сабреддит AMA и говорит, что готов отвечать на заданные вопросы. Из самых запоминающихся сессий Ask Me Anything, например, команда инженеров Space X [2], или инженеры из Google [3], и даже действующий президент США Барак Обама четыре года назад отвечал на вопросы на Реддите [4]. Недавно наша Android-команда [5] проводила AMA и в онлайн-режиме отвечала на вопросы разработчиков.
Но в России нет своего Реддита. Зато есть свой Хабр. Поэтому мы решили прийти с форматом «задай нам вопрос» сюда. И не с пустыми руками, как велят правила AMA. Чтобы вам было проще понять тему, мы выбрали одну из наших команд – «Платформу» – и попросили ребят рассказать, чем они занимаются, на чём программируют и чего добились за время существования команды. И подвели небольшие итоги уходящего 2016 года. Поехали!
1. Чем занимается «Платформа» [6]
2. Сервисы: Pinba, SoftMocks и другие [7]
3. Системное программирование. Как мы начали использовать Go и к чему это привело [8]
4. Фотографии [9]
5. Скриптовое облако [10]
6. LSD: Live Streaming Daemon [11]
7. Cassandra Time Series: что это и как работает [12]
8. Badoo AMA: задай вопрос разработчикам «Платформы» [13]
Пруф [14], что это действительно мы.
Антон Поваров, einstein_man [15], руководитель «Платформы»
Михаил Курмаев, demi_urg [16], руководитель команды A-Team
«Платформа» – это инфраструктурная команда, которая помогает другим подразделениям. Наша основная цель – сделать так, чтобы всем было хорошо, чтобы всё работало, программисты были довольны и могли спокойно писать код без оглядки на всякие сложные штуки. Мы – backend для backend.
«Платформа» состоит из двух команд: команда С-программистов (пишут на С, но в последнее время – и на Go) и А-Team (пишут на PHP и местами тоже на Go). Сишники пишут сервисы, делают PHP extensions. A-Team занимается PHP и database-инфраструктурой, а также разработкой и поддержкой инструментов для других команд.
Если говорить о конкретных проектах с точки зрения того, что видит пользователь (то, что он использует), то мы занимаемся:
За «обертки» мы отвечаем, потому что хочется скрыть все эти внутренности от backend-разработчиков других команд, чтобы упростить их работу и не допускать непредвиденных ситуаций, когда всё, чем мы занимаемся из основных задач, внезапно сломалось.
Некоторые из наших внутренних сервисов со временем выросли в полноценные продукты и даже стали стандартом де-факто в экосистеме PHP. Самые известные из них – это PHP-FPM (сейчас он стал частью стандартной поставки PHP для веба), его написал Андрей Нигматулин (доклад на эту тему можно посмотреть здесь [17]), и Pinba (http://pinba.org/), сервис для получения realtime-статистики [18] от работающих приложений без накладных расходов на её сбор (UDP), с помощью которого легко понимать, что происходит с производительностью вашего приложения в любой момент времени.
Pinba удобна тем, что позволяет нам всё время собирать данные. И эти данные будут под рукой всегда, когда нужно разобраться в причине проблемы. Это удобно и значительно сокращает время, затрачиваемое на поиск и устранение проблемы. Не менее важно и то, что Pinba помогает увидеть проблему заранее, когда она ещё не затронула юзеров.
Ещё мы придумали и сделали SoftMocks, это наш собственный фреймворк, облегчающий unit-тестирование, который позволяет подменять классы и функции в тестах. Нам пришлось создать его в связи с переходом на PHP7, в котором была сильно переработана внутренняя архитектура интерпретатора, и наш старый Runkit просто перестал работать. На тот момент у нас было около 50к юнит-тестов, большинство из которых так или иначе используют моки для изоляции внешнего окружения, и мы решили попробовать другой подход, потенциально более мощный, чем Runkit/ Uopz.
Одними из основных преимуществ SoftMocks являются независимость от внутренней структуры интерпретатора и отсутствие необходимости в каких-либо сторонних расширениях PHP. Это достигается за счёт выбранного нами подхода – переписывание исходного кода программы на лету, а не динамическая подмена внутри интерпретатора. На данный момент проект выложен в open-source [19], и им может воспользоваться любой желающий.
Вы, возможно, знаете о том, у нас в Badoo очень сильная команда PHP-разработчиков. Поэтому нет ничего удивительного в том, что мы оказались в числе первых компаний, которые перевели проект такого масштаба (как Badoo) на PHP 7 в этом, 2016-м, году. Прочитать о том, как мы пришли к этому, с чем столкнулись и что получили, можно в этом посте [20].
Марко Кевац, mkevac [21], программист в отделе C/C++
В отделе C/C++ мы разрабатываем высокопроизводительные in-memory демоны, которые обрабатывают сотни тысяч запросов в секунду и хранят сотни гигабайт данных в памяти. Среди них можно найти такие вещи, как поисковые демоны, использующие bitmap-индексы и осуществляющие поиск по ним с использованием самописного JIT, или умный прокси, который обрабатывает соединения и запросы всех наших мобильных клиентов. При необходимости мы расширяем язык PHP под наши нужды. Какие-то патчи отправляются в апстрим, какие-то – слишком специфичны для нас, а какие-то вещи удаётся сделать в виде загружаемых модулей. Мы пишем и поддерживаем модули для NGINX, занимающиеся такими вещами, как шифрование урлов и данных и быстрая обработка фотографий «на лету».
Мы – хардкорные системные программисты, но при этом прекрасно понимаем все недостатки программирования на С/C++: медленная разработка, потенциальные ошибки, сложность программирования с использованием потоков.
С самого появления Go, новомодного, молодёжного и многообещающего языка от Google, мы им заинтересовались. И почти сразу же после выхода первой стабильной версии в 2012 году мы начали рассматривать возможность его применения в production.
Go обещал быть близким по духу и производительности нашему любимому С, но позволял делать прототипы и даже конечные продукты заметно быстрее и с меньшим количеством ошибок. И тот факт, что Go являлся синонимом конкурентности с его каналами и горутинами, особенно возбуждал нашу фантазию.
В тот момент у нас появилась новая крутая и очень срочная задача по поиску пересечений между людьми в реальном мире. Послушав требования, мы чуть ли не хором воскликнули: «Это задача для Go!» Требовалось потоково обработать большое количество координат пользователей, правильно их пересечь в нескольких «координатах», включая время, и выдать какой-то результат. Очень много взаимодействий между частями, очень много параллельных вычислений. Словом, именно то, что является базовой задачей для Go.
Прототип был сделан тремя людьми за неделю. Он работал. Он работал хорошо. И мы поняли, что Go у нас приживётся. В 2015 году Антон Поваров подробно рассказал [22] в своём выступлении о Go в Badoo.
Но нельзя сказать, что наш роман был идеальным. Go на тот момент был совсем молодым языком с кучей проблем, а мы сразу же начали писать продукты, которые обрабатывали десятки тысяч запросов в секунду и потребляли почти 100 гигабайт памяти.
Нам приходилось оптимизировать наши сервисы, чтобы не делать лишних аллокаций памяти напрямую и чтобы компилятор Go не решал делать эти аллокации за нас. И здесь красота и удобство Go снова проявили себя. С самого начала Go обладал отменными средствами для профилирования производительности, потребления памяти, для того, чтобы видеть, когда компилятор решает выделить какой-то кусок на куче, а не на стеке. Наличие этих средств сделало оптимизацию интересным и познавательным приключением, а не мукой.
В первом же проекте нам нужно было использовать существующую библиотеку для геовычислений, написанную на C. Так что мы окунулись в самую гущу проблем и нюансов взаимодействия этих двух языков.
Поскольку Go стал инициативой «снизу», нам нужно было постараться, чтобы наши коллеги и менеджеры не отвергли нашу идею сразу. Мы понимали, что нужно сделать так, чтобы со стороны эксплуатации проект на Go никак не отличался от проекта на C: такие же конфиги в JSON, те же протоколы взаимодействия (основной protobuf и дополнительный на JSON), та же стандартная статистика, которая уходит в RRD. Нам надо было сделать так, чтобы со стороны релиз инжиниринга проекта на Go никак не отличался от проекта на C: тот же самый Git + TeamCity Flow, та же сборка в TeamCity, тот же процесс выкладки. И у нас это получилось.
Администраторы, эксплуатация и релиз-инженеры не задумываются о том, на чём написан проект. Мы поняли, что теперь можно не стесняться использовать новые инструменты, так как они прекрасно показали себя на практике (в некритичных задачах, как и положено для начала).
Мы не создавали ничего с нуля – мы встраивали Go в существующую много лет инфраструктуру. Этот факт ограничивал нас в использовании каких-то вещей, которые для Go являются стандартными. Но именно этот факт вкупе с тем, что мы сразу начали писать серьёзный высоконагруженный проект, позволил нам окунуться в язык по уши. Мы знатно испачкались, скажу я вам, но эта близость помогла нам «срастись» с этим прекрасным языком.
Интересно было наблюдать, как с каждой выходящей версией Go рос, как ребёнок, превращающийся во взрослого человека. Мы видели, как паузы GC на наших демонах таяли с каждой новой версией, и это без изменения кода с нашей стороны!
Сейчас, спустя четыре года работы с этим языком, у нас около десятка самых разноплановых сервисов на Go в трёх командах и ещё несколько новых в планах. Go прочно вошёл в наш арсенал. Мы знаем, как его «готовить» и когда его стоит применять. Спустя столько лет интересно слышать, как программистами регулярно говорятся такие вещи, как «да набросай быстренько прототип на Go» или «тут столько параллельности и взаимодействий, это работа для Go».
Артём Денисов, bo0rsh201 [23], старший PHP-программист
Фотографии являются одним из ключевых компонентов Badoo с точки зрения продукта, и мы просто обязаны уделять инфраструктуре их хранения и показа много внимания. На данный момент мы храним около 3 ПБ фотографий, каждый день пользователи заливают около 3,5 млн новых снимков, а нагрузка на чтение составляет около 80k req/sec на каждой площадке.
Концептуально это устроено следующим образом. У нас есть три точки присутствия в трёх дата-центрах (в Майами, Праге и Гонконге), которые обеспечивают локальность к большинству наших целевых рынков.
Первый слой инфраструктуры – это кэширующие серверы с быстрыми SSD дисками, которые обрабатывают 98% входящего трафика, на них работает наш собственный мини-CDN – это кэширующий прокси, оптимизированный под наш характер нагрузки, на котором также работает много утилитарной/ продуктовой логики (ACL, resize, наложение фильтров и watermark’ов на лету, circuit breaker и т. д.).
Следующий слой – кластер из пар серверов, ответственных за долговременное хранение,
часть из которых имеет локальные диски, на которых непосредственно хранятся фотографии, а часть подключена по оптике к третьему слою – Storage Area Network.
Эти пары машин обслуживают одинаковые диапазоны пользователей и работают в режиме master – master, полностью реплицируя и резервируя друг друга через асинхронную очередь. Наличие таких пар позволяет нам иметь отказоустойчивость не только на уровне жёстких дисков, но и на уровне физических хостов (kernel panic, reboot, blackout и т. д.), а также легко проводить плановые работы и без деградации сервиса переживать сбои, которые при больших масштабах не являются редкостью.
Более подробно о нашей работе с фотографиями Артём Денисов рассказал [24] в этом году на Highload++ [25].
Ни для кого не секрет, что в любом проекте, помимо действий, которые выполняются в контексте запроса пользователя, существует большое количество фоновых задач, выполняемых отложенно или по определённому расписанию. Обычно для их запуска применяют какой-то планировщик background worker’ов (в простейшем случае это cron).
С ростом количества таких задач и количества потребляемых ими ресурсов, которые постепенно перестают влезать на одну, а иногда и на несколько десятков физических машин, управлять этими кронами и балансировать нагрузку вручную для каждой ноды из кластера становится сложновато. Так возникла необходимость создания нашего облака – гибкой инфраструктуры для прозрачного запуска девелоперских задач.
Работает это примерно следующим образом:
1) Разработчик описывает job в виде PHP-класса, который реализует один из нескольких интерфейсов (крон-скрипт, разборщик очереди, обходчик баз и т.д…
2) Добавляет его через веб-интерфейс в облако, выбирает параметры для частоты запуска, тайм-ауты и ограничения по ресурсам.
3) Далее система сама запускает этот job на распределённой инфраструктуре, которая выделена под облако, следит за его выполнением и балансирует нагрузку на кластер. Девелоперу остаётся лишь следить за статусом работы своего job’а и смотреть логи через Web UI (сколько инстансов запущено, какие настройки, какие запуски как завершились).
На данный момент в облаке у нас порядка 2000 хостов в двух ДЦ ~ 48k CPU cores/ 84Tb memory. 1800 пользовательских заданий генерируют около 4 000 запусков в секунду.
Об облаке мы рассказывали тут [26] и тут [27].
Каждый, кто работает с большими объёмами данных, так или иначе сталкивается с задачей их стриминга. Как правило, мы стримим какие-то данные из большого количества разных источников в одно место, чтобы там централизованно их обработать. Причём тип этих данных зачастую не играет роли: мы стримим логи приложений, статистические данные, пользовательские события и многое другое. Концептуально мы используем два разных подхода для решения этой задачи:
1) Нашу собственную реализацию сервера очередей для доставки событий, связанных с логикой продукта/ приложения.
2) Более простой механизм для стриминга различных логов, статистических метрик и просто больших объёмов данных со множества нод, которые надо централизованно агрегировать и обрабатывать большими пачками в одном месте.
Для второй задачи мы долгое время использовали Scribe от Facebook [28], но с увеличением количества прокачиваемых через него данных он становился всё менее и менее предсказуемым и уже давно предан забвению.
В итоге в какой-то момент нам стало выгоднее написать своё решение (благо эта задача не выглядит очень сложной), которое было бы легче поддерживать.
Собственную стримилку событий мы назвали LSD: Live Streaming Daemon.
Ключевые особенности LSD:
В этом году мы опубликовали исходный код LSD, и теперь вы можете использовать его [29] в своих проектах.
Евгений Гугучкин, che [30], старший PHP-программист
Badoo – сложная система, состоящая из множества связанных компонентов. Оценить состояние этой системы – непростая задача. Для того чтобы это сделать, мы собираем более 250 миллионов метрик со скоростью около 200 000 значений в секунду, и эти данные занимают примерно 10 ТБ.
Исторически для хранения и визуализации временных рядов мы использовали известную утилиту RRDtool, «обернувши» её своим фреймфорком для удобства работы.
Что нам нравилось в RRDtool, так это скорость чтения. Однако существуют и серьёзные недостатки:
Именно последний пункт стал для нас решающим, потому что без него мы не могли отобразить на одном графике метрики с разных серверов.
В итоге мы провели подробнейший анализ существующих решений в области time series баз данных, убедились, что ни одно нам не подходит, и написали своё решение на основе Cassandra.
На данный момент половина наших реальных данных дублируется в новое хранилище. В цифрах это выглядит так:
При этом мы решили практически все задачи, которые перед нами стояли:
Мы очень гордимся проделанной работой по анализу существующих решений и построению нового. Мы наступили на бесчисленное количество грабель при работе с Cassandra и с удовольствием ответим на ваши вопросы, поделимся нашим опытом.
И теперь, собственно, то, зачем мы публикуем этот пост. Сегодня с 12:00 и до 19:00 (по московскому времени), команда «Платформы», будем отвечать на ваши вопросы. Мы много всего пережили за время существования команды: мы расширялись, менялись, учились, сталкиваясь с какими-то проблемами, приходили к новым языкам программирования. И мы готовы поделиться с вами нашим опытом (в том числе рассказать про фейлы, факапы и нашу боль).
Например, спрашивайте про:
Но не ограничивайтесь этим!
Автор: Badoo
Источник [31]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/php-2/220208
Ссылки в тексте:
[1] AMA (ask me anything): https://www.reddit.com/r/AMA/
[2] инженеров Space X: https://www.reddit.com/r/IAmA/comments/1853ap/we_are_spacex_software_engineers_we_launch/
[3] инженеры из Google: https://www.reddit.com/r/MachineLearning/comments/4w6tsv/ama_we_are_the_google_brain_team_wed_love_to/
[4] отвечал на вопросы на Реддите: https://www.reddit.com/r/IAmA/comments/z1c9z/i_am_barack_obama_president_of_the_united_states/c60mm5n/
[5] Android-команда: https://www.reddit.com/r/androiddev/comments/4wx1yy/were_the_badoo_android_engineering_team_ask_us/
[6] 1. Чем занимается «Платформа»: https://habrahabr.ru/company/badoo/blog/317442/#a
[7] 2. Сервисы: Pinba, SoftMocks и другие: https://habrahabr.ru/company/badoo/blog/317442/#b
[8] 3. Системное программирование. Как мы начали использовать Go и к чему это привело: https://habrahabr.ru/company/badoo/blog/317442/#c
[9] 4. Фотографии: https://habrahabr.ru/company/badoo/blog/317442/#d
[10] 5. Скриптовое облако: https://habrahabr.ru/company/badoo/blog/317442/#e
[11] 6. LSD: Live Streaming Daemon: https://habrahabr.ru/company/badoo/blog/317442/#f
[12] 7. Cassandra Time Series: что это и как работает: https://habrahabr.ru/company/badoo/blog/317442/#g
[13] 8. Badoo AMA: задай вопрос разработчикам «Платформы»: https://habrahabr.ru/company/badoo/blog/317442/#h
[14] Пруф: https://twitter.com/BadooDev/status/808582609169186816
[15] einstein_man: https://habrahabr.ru/users/einstein_man/
[16] demi_urg: https://habrahabr.ru/users/demi_urg/
[17] доклад на эту тему можно посмотреть здесь: https://vimeo.com/6443121
[18] сервис для получения realtime-статистики: https://habrahabr.ru/company/badoo/blog/149695/
[19] проект выложен в open-source: https://github.com/badoo/soft-mocks
[20] в этом посте: https://habrahabr.ru/company/badoo/blog/279047/
[21] mkevac: https://habrahabr.ru/users/mkevac/
[22] Антон Поваров подробно рассказал: https://www.youtube.com/watch?v=pOgAnWfNjms
[23] bo0rsh201: https://habrahabr.ru/users/bo0rsh201/
[24] Артём Денисов рассказал: http://www.slideshare.net/profyclub_ru/badoo-badoo-68903760
[25] на Highload++: http://www.highload.ru/2016/abstracts/2280.html
[26] тут: https://tech.badoo.com/ru/presentation/129/badoo-v-oblakax-reshenie-dlya-zapuska-cli-skriptov-v-oblake/
[27] тут: https://tech.badoo.com/ru/presentation/49/oblako-v-badoo-god-spustya/
[28] Scribe от Facebook: https://github.com/facebookarchive/scribe
[29] можете использовать его: https://github.com/badoo/lsd
[30] che: https://habrahabr.ru/users/che/
[31] Источник: https://habrahabr.ru/post/317442/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.