TGViewer
Yandex for Backend Yandex for Backend @yandexforbackend · 10.1K subscribers
Post #1095 1.84K
📎 Как сэкономить 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
  • 👍 7
  • 🔥 5
  • ❤ 4
  • 🥱 2
  • 🤷‍♀ 1
  • 👀 1
  • 🙈 1
  • 🙊 1
More from @yandexforbackend
  1. Sep 18, 2026🔠 Приглашаем в Архитектурный клуб Яндекс 360 Это открытое сообщество для архитекторов и и…
  2. Sep 17, 2026🏆 Международное соревнование для разработчиков Young&&Yandex открывает регистрацию на Yan…
  3. Sep 16, 2026🐾 Яндексоиды рассказывают про свои пет-проекты: ktoml и diktat Продолжаем показывать виде…
  4. Sep 13, 2026📺 «Нерешённые задачи» — премьера к празднику Сегодня, 13 сентября, мы отмечаем День прогр…
  5. Sep 11, 2026🐾 Яндексоиды рассказывают про свои пет-проекты: робот-художник Хотим познакомить вас с ра…
  6. Sep 7, 2026🛎 «Я про бэкенд» × «2718»: ищем сложные задачи для инженеров Яндекса В карточках знакомим…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →