см. http://www.slideshare.net/rybaxek/serverside-api
Полмиллиона юзеров в онлайне без падений: оптимизация высоконагруженного server-side API десктопного приложения. Сергей Аверин, Badoo.
Доклад рассказывает о реально примененных способах оптимизации производительности API компании Badoo для собственных десктоп-приложений: как специфика «много постоянных соединений/однотипные запросы/большая нагрузка» повлияла на стратегию оптимизации производительности.
Что было сделано:
• Планирование архитектуры изначально (fault-tolerance, адаптивные апдейты и тайм-ауты, отказ от попыток восстановления после ошибок для единичных команд).
• Переехали с redis на handlersocket.
• Rate-limiting запросов к демонам.
• Синхронизация записей.
• Асинхронность.
• Записи при достижении порога изменения параметров.
• Профилирование кода, анализ потребления CPU, времени ответа.
• Статистика, статистика и еще раз статистика.
• Pconnect.
Доклад будет интересен:
• системным архитекторам,
• server-side разработчикам.
Mind map от «Полмиллиона юзеров в онлайне без падений: оптимизация высоконагруженного server-side API десктопного приложения»
1. Полмиллиона юзеров в онлайне без падений:
оптимизация высоконагруженного server-side API десктопного приложения
Про Баду
Про программу
Server-side архитектура
Изначальные архитектурные решения
Доклад РИТ 2011
Специфика приложения
Оптимизации
Суровая реальность
Заключение
2. Лого
Концепция Социальная сеть для знакомств с новыми людьми
В Top-200 alexa c 2007 года Сейчас на 130-м месте в Alex'е
115 млн пользователей
Для юзеров Метрики 10 млн пользователей заходят на сайт в течение дня
1,5 млн фотографий загружается каждый день
Про Баду
Пользователей/разработчиков > 1 000 000
Быстрорастущая компания
В январе перешагнули 100 млн
Метрики 30 тыс. запросов/с к PHP бекендам в пике
Для разработчиков MySQL, PHP, C/C++, Linux, nginx,
Мы используем PHP_FPM, memcached и много
своего
3. Бесплатная
Win/Mac
Висит в трее
Поддерживает ваш онлайн-статус Знает когда вы не у компьютера
на сайте
Показывает разные уведомления о новых событиях
Программа
Рассказывает нам о вашем
местоположении
Позволяет быстро и удобно
попасть в нужный раздел сайта
Показывает разные полезные
счетчики с сайта
Про программу Дает разные бонусы на сайте
1,7 миллиона пользователей в месяц
Метрики 680 тыс. подключенных программ в пике
17 тыс. запросов/с к PHP бекендам
Это знакомства поблизости
Своего рода игра с привязкой к местности
Что это в итоге такое?
На сайте можно узнать насколько далеко
от тебя тот или иной пользователь
Сценарий работы
Набор команд
4. Соединяемся с главным
фронтендом
Он отправляет нас на нужный
фронтенд
Создаем/восстанавливаем
Сценарий работы сессию
Получаем настройки, перевод и
меню
Показываем уведомления
Выполняем в цикле
Посылаем данные о wi-fi и скрин-
сейвере
5. Создание/Восстановление сессии
Из программы Авторизация
Данные о wi-fi сетях, работе скрин-сейвера
Набор команд
Ваш id сессии, язык и статус авторизации
В программу Настройки, перевод, меню
Уведомления
7. Протокол асинхронный
Для команд, требующих ответа, Сработал тайм-аут —
Не требует ответа на есть тайм-аут на ответ переподключаемся
большинство команд
Сложная логика на сервере
Как можно более простые
Изначальные протокол и логика программ
архитектурные решения
Один exception handler
При ошибке на сервере не
пытаемся восстановиться, а Посылаем в программу команду При ошибке программа
прерываем обработку ошибки переподключается
команды
Переподключение сначала скрыто
Нам не нужна 100%
синхронность данных Что не можем показать — не показываем
8. Маленький набор и размер
команд
Большое кол-во постоянных
соединений
Хорошо предсказуемый
Большой поток команд
Меняется плавно в течении дня
Специфика приложения Обработка одной команды
занимает мало времени
Время ответа сервера не так
критично, как для веб-
страниц
Ошибки при обработке
команд на серверной стороне
программы сильно не
расстраивают
9. Из беты в устойчивую систему
Профилирование и поиск
тормозов в коде
Железно-площадочные
оптимизации
Сам себе DDOS'ер
Оптимизации
Заставили программы помогать
нам
Перестали делать «лишние
телодвижения»
Пороговые срабатывания
Асинхронность и пост-обработка
10. И из-за специфики приложения
top вам ничего не даст
(surprise) И из-за специфики подсчета
«Вроде как-то медленно PHP-код работает»
Тулзы — тысячи их, много open-source
Для хорошего программера — почти нереально
Профилирование Ищем места в коде, которые и выясняем, в чем дело
стандартными способами выполняются > 1 мс
Зато наводит на кучу мыслей
Часто натолкнет вас места, где Но видение этого требует опыта
Профилирование и поиск можно улучшить, изменив логику
тормозов в коде работы
Это PINBA (open-source) Сделано в Баду
Профилирование, база для статистики и мониторинга — 3-в-1
Real-time
профилирование Все соединения и запросы к Ищем, что тупит во время падений
сервисам оборачиваем в таймеры
Видно проблемы не в коде, а в работе приложения в целом
Про код
Знаем примерно что, как, где
работает
Про внешние вызовы к демонам
Итог
Заменили CURL на file_get_contents 25% времени выполнения одной команды
('http://...') и выиграли 4 мс на запрос
11. по 200 тыс. одновременных коннектов на сервер
на серверах, получающих основную массу
коннектов задействовали все 4 сетевые карты Лучше производительность
Минимум конкуренции
отдельный мемкеш
меньше зависишь от соседей — спокойнее живешь
переехали с MemCacheDB Не использовать никогда
оказалось так себе
на Redis Большие тормоза при дампах
Меняли способ хранения сессий Append-only режима не было
Затем на MySQL+HandlerSocket
read и write-оптимизированные системы
Вывод:
все БД нужно тестировать под большой нагрузкой
Железно-площадочные
оптимизации Вместо оптимистичных тайм-аутов Больше свободных процессов php-fpm
Долгие тайм-ауты при ответов демонов устанавливаем
торможении площадки жесткие (0,5—1с)
занимают ресурсы
Есть сервисы, которые «забывают» memcached — отличный пример
вам ответить/теряются пакеты
Демоны, ответ которых нам
все-таки важен (например, умеем бороться с единичными ошибками
загрузку сессий программ, без посылки ошибок в программу
пытаемся опрашивать
без которых ни одну команду несколько раз с паузой между
не обработать) Снижает кол-во показываемых ошибок
попытками
Снижает кол-во реконнектов
Где можем, используем pconnect
Какая была интересная история, как
Коннект — дорогая операция всех не туда перезалогинило
Вывод: отличная шутка, большой но надо «уметь правильно готовить»
выигрыш
12. Мы устраивали сами себе DDOS сервиса
программы отваливались и переподсоединялись
При проблемах на площадке скопом за короткий промежуток времени
ложилось все резко падало и
плохо поднималось Даже если все сервис могли Положительная обратная связь
работать нормально, бесконечно
поднималось и падало волнами Можно ли ее избежать?
которая означает либо ошибку при
при получении ошибки выполнении команды либо таймаут
backed'а
Увеличивание пауз посылки
команд при ошибках программа притормаживает посылку следующей команды
при получении нормальных ответов притормаживание плавно снимается
Сам себе DDOS'ер
Если при сбое все программы отваливаются
То же самое для то очень скоро попытки подключения пойдут со значительными интервалами
реконнектов
что даст площадке свободные для восстановления производительности
ресурсы
вместо схемы «сходи на роутер- переподключение стало отличаться от первого
сервер, потом иди куда он скажет» подключения после запуска программы
Улучшили алгоритм При переподключении мы пытаемся несколько
реконнекта раз подключиться туда, где мы были
и только после того, как все идем на роутер-сервер (полный
попытки оказались неуспешными цикл реконнекта)
13. пишем в мемкеш
Для отслеживания времени
последнего обновления почему бы не заставить программу Снимает большую часть
статуса нужно это время отслеживать и сообщать нам это? нагрузки на мемкеш
куда-то писать
Нам такие пользователи на сайте они оффлайн
неинтересны
Пользователь может быть не
Заставили программы за компьютером Сделали снижение частоты Экономит серверные мощности
помогать нам посылки уведомлений
Бывало вообще не приконнекчивалась
Ввели интеллектуальное увеличение и
Медленные соединения уменьшение времени тайм-аута на ответ сервера
(GPRS)
Меньше реконнектов, больше
подсоединенных программ
14. меню,
счетчики,
Скешировали все, что можно настройки,
данные пользователей,
посылаемые программу
Перестали делать Потому что это бесполезно
«лишние телодвижения»
Запретили обновление статуса Нагрузка на сервис не
Ввели rate-limiting пользователя чаще, чем раз в 40 только снизилась
обновления данных секунд
Но и при повальных реконнектах
сервис перестал валиться
Если сессия не меняется — зачем Записи сократились раза в три
Отслеживание, а надо ли ее заново записывать?
вообще писать
15. То появляются, то пропадают
Уровень сигнала постоянно меняется
Wi-fi сети «мигают»
Каждый раз это вызывает посылку кучи
данных и вычисление координат
При любом изменении
сетевой/wi-fi конъюнктуры
ввели сбор данных о том, какие
вычислялись новые сети вокруг
координаты
и постепенное повышение порога
Ввели порог на срабатывание
срабатывания
Пороговые срабатывания Чтобы учесть медленные изменения
принудительно обновляем раз в 10 минут
Записывалось в mysql-базу с Это медленная и ресурсоемкая
данными пользователя. процедура
Мы готовы немного потерять в
актуальности данных
При любой смене координат
вычислялось новое
Маловероятно, что смена
местоположение координат до 300 м. перенесет вас
в соседний город
Ввели порог на срабатывание Время обработки команды выросло
вычисления и записи города в 300 м втрое
16. быстрее получит — меньше таймаутов
Ответ на команду как можно
раньше
Быстрее ответ
Стараемся сервисные задачи
выносить из прямой Меньше ошибок валится в программы
обработки команд
Пакетная обработка всегда быстрее
Многие сервисные задачи на стороне сервера можно выполнять без
привязки к конкретному времени
Асинхронность и пост- почему бы не синхронизировать их,
обработка уменьшив нагрузку на этот ресурс?
Если несколько таких задач
используют один ресурс
Например все вместе раз в сутки
для одного user_id
Синхронизация использования
Если начала выполняться автоматически запускаются все
ресурсов сервисная задача, которая пишет в остальные, которые тоже будут
сессию писать в сессию
Ввели временное окно на
Если задача так и не была запускаем ее принудительно
выполнение каждой сервисной
выполнена, а временное окно
задачи
истекает
Снизило кол-во записей сессий на
20%
17. Limited CPU
Ограниченная производительность
От падейний никто не защищен всех внешних сервисов
Ограниченное кол-во одновременно то есть процессов php-fpm
обрабатываемых запросов
забыли поставить на мониторинг
на всех возможных уровнях
всего один сервер
с профилированием
Не график с отметкой раз в 5—15
минут, а в реальном времени
Много SPOF
Одна ошибка и вы заваливаете сами
себя
Мониторинг, мониторинг и еще
Суровая реальность раз мониторинг Большая взаимозависимость между
отдельными элементами системы
realtime (командами, внеш. сервисами)
Вы работаете в совершенно другой
среде, в отличие от веба Вы должны реагировать быстро
и видеть результат своих действий
сразу
мониторинг должен быть сразу с
профилировкой
PINBA, да
ручная
выкладка старого кода
автоматическая
Failover
выключение части функционала Ручное точно необходимо
выпадение отдельного сервера из
кластера и возврат в строй
18. крайне необходим realtime-
сервисам
Мониторинг
Все тормозящие внешние сервисы
— это тоже ваша ответственность
это часто «смотришь в книгу, видишь
фигу»
Нужно уметь анализировать отчеты
это не значит что у вас не тормозит
Профилирование Если вы выпилили все медленые где-то еще
Заключение места в php-коде
Вы сделали 1 из 7 пунктов доклада
можно добиться улучшения в 10
Поменяв логику работы
раз, в отличие от вылизывания php-
приложения (часто с обеих сторон)
кода
и подготовьте их решения
Предусмотрите все возможные
проблемы заранее
необходимый вам подход
We build wheels while existing
suck or don't exist