TGStat
TGStat
Введите текст для поиска
Расширенный поиск каналов
  • flag Russian
    Язык сайта
    flag Russian flag English flag Uzbek
  • Вход на сайт
  • Каталог
    Каталог каналов и чатов Региональные подборки Тематические подборки Платные каналы Поиск каналов
    Добавить канал/чат
  • Рейтинги
    Рейтинг каналов Рейтинг чатов Рейтинг публикаций
    Рейтинги брендов и персон
  • Аналитика
  • Поиск по публикациям
  • Мониторинг Telegram
  • Продвижение
    Реклама через Яндекс Бизнес Реклама в каналах через TGStat Agency Реклама на сайте TGStat.ru
Yandex for Backend

14 Sep, 12:04

Открыть в Telegram Поделиться Пожаловаться

📎 Как сэкономить 1000+ ядер на ровном месте

На связи Миша Иглицкий, бэкенд-разработчик в платформе Яндекс Еды. У нас есть PHP-монолит, в который пишут мало нового кода, поэтому он спокойно работает и не привлекает к себе лишнего внимания. Так оно бы и продолжалось, если бы не случился период повышенной нагрузки и понадобилось зарезервировать побольше мощностей для беспроблемной обработки подобного спроса.

Монолит отлично справился. Но после этой ситуации я случайно обратил внимание, что RPS в пиковые вечерние часы подозрительно совпадает с количеством ядер CPU, выделенных на весь монолит. Нехитрая арифметика показала: 100% загрузки одного ядра приходятся на 2,5 RPS. Я решил разобраться, что к чему.

Спойлер: дело оказалось не только в PHP.

❇️ Perforator vs PHP-монолит

У нас есть Perforator, который установлен почти на все хост-машины, и с его помощью можно посмотреть, на что уходит процессорное время на подах. Проблема в том, что он видит почти всю работу PHP как вызов zend_execute_ex.

Хорошая новость: коллеги как раз допиливали поддержку PHP в Perforator, но пока не вмержили её в основную ветку. Однако нам залили на одну из хост-машин, где крутился инстанс PHP-монолита, специально собранную версию с поддержкой PHP. И я сразу же увидел пожирателя CPU.

Им оказалась функция getRoutePattern для атрибута http.route. Изначально никто не заметил, что getRouteCollection не возвращает готовый закешированный список роутов, а каждый раз собирает его заново: проходит по всем YAML-файлам и читает аннотации в PHP-файлах.

🦾 Исправление оказалось элементарным: теперь роуты читаются и сохраняются один раз на этапе сборки контейнера, а в рантайме берутся из кеша.

➖ Результат: потребление CPU в 99-м процентиле снизилось почти на 30%.

❇️ Инфраструктурные полтергейсты

На стороне PHP очевидных тормозов больше не было. Но я обратил внимание, что теперь топ потребления CPU выглядит так:

🟢 PHP: 20%
🟢 HAProxy: 19%
🟢 psql: 17%

🔍 Внутри psql мы увидели странный call stack. Оказалось, что в Debian psql по историческим причинам запускается через Perl-обёртку. Она выбирает нужную версию клиента, потому что в системе может быть установлено сразу несколько версий PostgreSQL (этой возможности уже больше 20 лет).

Также монолит на PHP не использует postgres-специфичные connection string, чтобы подключаться к primary-ноде БД — это решение вынесено на уровень HAProxy. А он не умеет делать это нативно, только проверять tcp connectivity. Так что для проверки были написаны специальные скрипты, которые и вызывали psql. В итоге один только запуск Perl-обёртки начал заметно потреблять ресурсы.

🦾 Проблему решили довольно просто: добавили agent-check в HAProxy. Передаём проверку состояния бэкенда отдельному агенту, который может делать то, чего HAProxy не умеет.

➖ Результат: строки с описанием бэкенда теперь длиннее, но зато работа стала быстрее и стабильнее. И после выкатки этого изменения на тестинге Perl пропал в профилях.

🔶 Читайте больше подробностей в статье на Хабре. Там я рассказал, почему HAProxy продолжал расходовать много CPU даже после наших изменений. А ещё поделился, как мы увеличили выделенную под APCu память и реализовали динамическую балансировку.

Подписывайтесь:
💬 @Yandex4Backend
📹 @YandexforBackend

2.5k 0 7 1 24
Каталог
Каталог каналов и чатов Подборки каналов Поиск каналов Добавить канал/чат
Рейтинги
Рейтинг каналов Telegram Рейтинг чатов Telegram Рейтинг публикаций Рейтинги брендов и персон
API
API статистики API поиска публикаций API Callback
Наши каналы
@TGStat @TGStat_Chat @telepulse @TGStatAPI
Почитать
Академия TGStat Исследование Telegram 2019 Исследование Telegram 2021 Исследование Telegram 2023
Контакты
Справочный центр Поддержка Почта Вакансии
Всякая всячина
Пользовательское соглашение Политика конфиденциальности Публичная оферта
Наши боты
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot