Рубрика "Вредные советы" ч.1 — асинхронность в Nginx
В интернетах вращается множество статей из разряда "Top Five Tips for <Твоя технология> in 2024", обещающих повысить, ускорить, оптимизировать.
Подобные гайды передаются из уст в уста и заботливо копируются в инфраструктуры, ведь "на прошлом месте работы это помогло!".
И не важно, что это было в 2012 году, на версии Linux kernel 2.4.x, в другом стеке и вообще не у меня, а у знакомого :)
Такой вот cargo cult.
С другой стороны, чем я хуже? У меня тоже есть парочка советов 😁
—————————————————————————————————
Nginx под капотом использует event‑driven архитектуру. Это когда у воркера есть очередь с ивентами, которую он последовательно "перемалывает".
И чем дольше занимает обработка события (например, чтение с диска), тем дольше ждут остальные в очереди.
Одно из решений — асинхронная обработка событий.
И у Nginx есть что предложить по опциям:
Теперь вся работа воркера с диском заключается в инициировании запроса, а сам процессинг делегируется отдельным тредам.
Таким образом, воркер способен еще быстрее переключаться между ивентами, ускоряя весь пайплайн!
Пруфы
Измерим latency работы функции
1. Без внедрения
2. С
Гистограмма показывает значительное сокращение задержек тяжелых операций, а среднее время обработки снизилось почти втрое. Неплохо!
—————————————————————————————————
P.S. Использовать на свой страх и риск, с предварительной проверкой на своей рабочей нагрузке!
Удачи!
В интернетах вращается множество статей из разряда "Top Five Tips for <Твоя технология> in 2024", обещающих повысить, ускорить, оптимизировать.
Подобные гайды передаются из уст в уста и заботливо копируются в инфраструктуры, ведь "на прошлом месте работы это помогло!".
И не важно, что это было в 2012 году, на версии Linux kernel 2.4.x, в другом стеке и вообще не у меня, а у знакомого :)
Такой вот cargo cult.
С другой стороны, чем я хуже? У меня тоже есть парочка советов 😁
—————————————————————————————————
Nginx под капотом использует event‑driven архитектуру. Это когда у воркера есть очередь с ивентами, которую он последовательно "перемалывает".
И чем дольше занимает обработка события (например, чтение с диска), тем дольше ждут остальные в очереди.
Одно из решений — асинхронная обработка событий.
И у Nginx есть что предложить по опциям:
aio threads;
aio_write on;
Теперь вся работа воркера с диском заключается в инициировании запроса, а сам процессинг делегируется отдельным тредам.
Таким образом, воркер способен еще быстрее переключаться между ивентами, ускоряя весь пайплайн!
Пруфы
Измерим latency работы функции
ngx_process_events_and_timers
(ссылка) — сколько времени уходит на обработку ивента.1. Без внедрения
aio
# funclatency-bpfcc /usr/sbin/nginx:ngx_process_events_and_timers -m -d 100
Function = b'ngx_process_events_and_timers' [147018]
msecs : count distribution
0 -> 1 : 60492 |********************************|
2 -> 3 : 5567 |*** |
4 -> 7 : 3937 |** |
8 -> 15 : 1899 |* |
16 -> 31 : 429 | |
...
avg = 27 msecs, total: 3797767 msecs, count: 136964
2. С
aio
:# funclatency-bpfcc /usr/sbin/nginx:ngx_process_events_and_timers -m -d 100
Function = b'ngx_process_events_and_timers' [146165]
msecs : count distribution
0 -> 1 : 103291 |*******************************|
2 -> 3 : 2581 | |
4 -> 7 : 1962 | |
8 -> 15 : 1757 | |
16 -> 31 : 0 | |
32 -> 63 : 374 | |
64 -> 127 : 49 | |
...
avg = 10 msecs, total: 3534364 msecs, count: 342992
Гистограмма показывает значительное сокращение задержек тяжелых операций, а среднее время обработки снизилось почти втрое. Неплохо!
—————————————————————————————————
P.S. Использовать на свой страх и риск, с предварительной проверкой на своей рабочей нагрузке!
Удачи!
👍8🔥1
🔥 Топовые инженеры в сферах SRE, производительности и Linux, на которых стоит подписаться (Linkedin)
👉 Mark Dawson, Jr.
Ведет активную деятельность как на LinkedIn, так и в своем блоге. Море "deep dive" по устройству Linux, его взаимодействию с вычислительными ресурсами и тому, как это влияет на производительность приложений.
👉 Tanel Poder
Создатель 0xtools (утилиты для траблшутинга), частый гость P99CONF и автор множества статей в блоге о Linux и поиске проблем в системах.
👉 Jose Fernandez
Двигает тему eBPF в Netflix, разрабатывая утилиты для повышения наблюдаемости и надежности систем. Активно делится своим опытом с сообществом.
👉 Viacheslav Biriukov
В бытность Яндекса читал лекции в КИТ, а позже завел блог, где простыми словами рассказывает про внутреннее устройство Unix-систем. Супер познавательно!
🎯 Бонус трек — @bobrik (github)
Создатель ebpf_exporter и активный контрибьютер в популярные open-source решения. Его код полезно и интересно читать. А еще ведет страничку в Mastodon про eBPF, Linux и все вокруг.
💬 А кто у вас в подписках?
👉 Mark Dawson, Jr.
Ведет активную деятельность как на LinkedIn, так и в своем блоге. Море "deep dive" по устройству Linux, его взаимодействию с вычислительными ресурсами и тому, как это влияет на производительность приложений.
👉 Tanel Poder
Создатель 0xtools (утилиты для траблшутинга), частый гость P99CONF и автор множества статей в блоге о Linux и поиске проблем в системах.
👉 Jose Fernandez
Двигает тему eBPF в Netflix, разрабатывая утилиты для повышения наблюдаемости и надежности систем. Активно делится своим опытом с сообществом.
👉 Viacheslav Biriukov
В бытность Яндекса читал лекции в КИТ, а позже завел блог, где простыми словами рассказывает про внутреннее устройство Unix-систем. Супер познавательно!
🎯 Бонус трек — @bobrik (github)
Создатель ebpf_exporter и активный контрибьютер в популярные open-source решения. Его код полезно и интересно читать. А еще ведет страничку в Mastodon про eBPF, Linux и все вокруг.
💬 А кто у вас в подписках?
JabPerf Corp
Blog
A collection of musings on deeply technical topics distilled through the lens of contemporary social and cultural analogies
🔥13
The Art of System Debugging — Decoding CPU Utilization
Или как баг в Java вызвал перегрузку CPU из-за избыточного чтения
Заметка показывает, как eBPF помогает быстро находить сложные проблемы, и насколько труднее обходиться без него.
Статья интересна:
1. обилием реальных кейсов с использованием bcc утилит — всегда полезно увидеть, как коллеги исследуют системы с их помощью;
2. баги связанные со
В общем два в одном;)
tags: #cpu #troubleshooting
Или как баг в Java вызвал перегрузку CPU из-за избыточного чтения
cgroupfs
.Заметка показывает, как eBPF помогает быстро находить сложные проблемы, и насколько труднее обходиться без него.
Статья интересна:
1. обилием реальных кейсов с использованием bcc утилит — всегда полезно увидеть, как коллеги исследуют системы с их помощью;
2. баги связанные со
spinlock
сложны для диагностики - создают ложное впечатление работы (высокий CPU System Time), хотя на деле система просто "активно ждет", перегружая процессор. Поэтому такие расследования всегда увлекательны. В общем два в одном;)
tags: #cpu #troubleshooting
Medium
The Art of System Debugging — Decoding CPU Utilization
This blog post describes the case study of how we diagnosed, root caused and then mitigated a performance issue in one of our applications…
👍7
Рубрика "Вредные советы" ч.2 — больше не всегда лучше.
Увеличение размера очередей - один из самых частых и эффективных советов по тюнингу, который можно услышать.
И сложно спорить, всего один параметр, а сколько пользы:
* сглаживание всплесков нагрузки;
* меньше переполнений => меньше потери данных;
* пропускная способность растет, как и эффективность обработки (пакетами, а не штуками);
* больше асинхронности, меньше боимся "морганий";
* ...
Но у любого совета, пусть и очень хорошего, всегда найдутся недостатки.
Представим два сервиса (1 и 2), взаимодействующих по сети через большую очередь, например на сетевой карте (2).
Пока (2) успевает обрабатывать поток данных, все работает гладко, с описанными выше преимуществами.
Но как только (2) замедляется на значительное время, могут возникнуть проблемы:
* latency каждого пакета в буфере растет кумулятивно, а хвосты ожидают слишком долго;
* срабатывают таймауты (на уровне приложения, TCP) и происходит переотправка, еще больше нагружая очередь;
* все накопленные данные будут обработаны (2), даже если они давно устарели;
* из-за отсутствия своевременной обратной связи TCP (1) реагирует с опозданием — отсутствует failfast;
* перегрузка накапливается в одной части системы, вместо того чтобы равномерно распределяться — отсутствует backpressure.
Список можно продолжить.
Вывод: не следует слепо следовать интернет-советам — всё нужно ставить под сомнение, проверять и подбирать оптимальные параметры именно под вашу систему.
P.S. проблеме раздутых буферов в свое время даже дали название - bufferbloat. Подробнее почитать о ней можно на www.bufferbloat.net.
tags: #network #tcp #theory
Увеличение размера очередей - один из самых частых и эффективных советов по тюнингу, который можно услышать.
И сложно спорить, всего один параметр, а сколько пользы:
* сглаживание всплесков нагрузки;
* меньше переполнений => меньше потери данных;
* пропускная способность растет, как и эффективность обработки (пакетами, а не штуками);
* больше асинхронности, меньше боимся "морганий";
* ...
Но у любого совета, пусть и очень хорошего, всегда найдутся недостатки.
Представим два сервиса (1 и 2), взаимодействующих по сети через большую очередь, например на сетевой карте (2).
Пока (2) успевает обрабатывать поток данных, все работает гладко, с описанными выше преимуществами.
Но как только (2) замедляется на значительное время, могут возникнуть проблемы:
* latency каждого пакета в буфере растет кумулятивно, а хвосты ожидают слишком долго;
* срабатывают таймауты (на уровне приложения, TCP) и происходит переотправка, еще больше нагружая очередь;
* все накопленные данные будут обработаны (2), даже если они давно устарели;
* из-за отсутствия своевременной обратной связи TCP (1) реагирует с опозданием — отсутствует failfast;
* перегрузка накапливается в одной части системы, вместо того чтобы равномерно распределяться — отсутствует backpressure.
Список можно продолжить.
Вывод: не следует слепо следовать интернет-советам — всё нужно ставить под сомнение, проверять и подбирать оптимальные параметры именно под вашу систему.
P.S. проблеме раздутых буферов в свое время даже дали название - bufferbloat. Подробнее почитать о ней можно на www.bufferbloat.net.
tags: #network #tcp #theory
👍7
Задержка любой операции, будь то ответ базы данных или обработка HTTP запроса, всегда совокупность задержек на более низких уровнях.
Например, чтение из базы данных состоит из множества этапов:
* формирование запроса
* создание TCP сокета
* обработка и маршрутизация на уровнях ниже
* ожидания в очередях и обработка сетевой картой
* поход по сети, и тд. и т.п.
Потому наблюдение за работой всех уровней — ключ к точному и оперативному анализу состояния системы.
Иначе можно искать задержку на дисках, а причина окажется в исчерпанном пуле соединений к базе. И пока разберемся что к чему, потеряем время, силы и деньги.
#latency
Например, чтение из базы данных состоит из множества этапов:
* формирование запроса
* создание TCP сокета
* обработка и маршрутизация на уровнях ниже
* ожидания в очередях и обработка сетевой картой
* поход по сети, и тд. и т.п.
Потому наблюдение за работой всех уровней — ключ к точному и оперативному анализу состояния системы.
Иначе можно искать задержку на дисках, а причина окажется в исчерпанном пуле соединений к базе. И пока разберемся что к чему, потеряем время, силы и деньги.
#latency
🔥10👍4
Kafka и медленная запись
Новая заметка по расследованию деградации записи в Kafka, с флеймграфом и флагами.
#troubleshooting #performance #linux #kafka #кейс
Новая заметка по расследованию деградации записи в Kafka, с флеймграфом и флагами.
#troubleshooting #performance #linux #kafka #кейс
www.alebedev.tech
Kafka и медленная запись
Разработчики провели нагрузочные тесты и выявили значительные задержки при записи данных в Kafka, что приводило к накоплению лага.
Я подключился к анализу причин низкой производительности.
Сильно упрощенный флоу:
приложение пишет в Kafka (кластер на виртуальных…
Я подключился к анализу причин низкой производительности.
Сильно упрощенный флоу:
приложение пишет в Kafka (кластер на виртуальных…
🔥10👍4
CPU Throttling и Runqueue
Заметка о том как выглядит троттлинг со стороны процесса в Linux и почему его стоит избегать.
——
Лайки, репосты приветствуются.
tags: #cpu #troubleshooting
Заметка о том как выглядит троттлинг со стороны процесса в Linux и почему его стоит избегать.
——
Лайки, репосты приветствуются.
tags: #cpu #troubleshooting
www.alebedev.tech
CPU Throttling и Runqueue
Объём ресурсов, потребляемый контейнером, учитывается на уровне cgroup, к которой он относится.
Контейнер состоит из одного или более процессов, а процесс — из одного или более тредов.
Абстракцию можно углубить, разбивая тред на «зелёные потоки», в зависимости…
Контейнер состоит из одного или более процессов, а процесс — из одного или более тредов.
Абстракцию можно углубить, разбивая тред на «зелёные потоки», в зависимости…
👍9❤1🔥1
CPU Usage не так прост в интерпретации, как может показаться.
Сложность в том, что показатель включает в себя не только работу CPU, но и время обращения к памяти.
А так как память на порядки медленнее процессора, то на ожидание ответа может уходить 90%+ времени.
Чтобы точнее интерпретировать CPU Usage стоит присмотреться к показателю IPC (Instructions Per Cycle) - сколько процессор выполняет инструкций за один такт.
В условиях современных суперскалярных процессоров этот показатель может достигать четырех и более инструкций.
Хотя в реальных нагрузках значение IPC будет существенно меньше (0.7 - 1.5).
Таким образом высокий CPU Usage при низком IPC (<1) может говорить не о недостатке вычислительных мощностей (и это первое, что приходит в голову), а о проблемах с IO - недостаток кешей и/или их плохая локальность, слишком частое обращение к памяти и подобное.
Для лучшего погружения в тему читай:
* CPU Utilization is Wrong от Brendan Gregg;
* IPC is to CPU% What Milk is to Cinnamon Toast Crunch от Mark Dawson.
——————————————
P.S. получить значение IPC можно с помощью node_exporter через perf коллектор, например так:
———————————————
P.P.S. этот же пост, но на linkedin.
tags: #cpu #theory #linux
Сложность в том, что показатель включает в себя не только работу CPU, но и время обращения к памяти.
А так как память на порядки медленнее процессора, то на ожидание ответа может уходить 90%+ времени.
Чтобы точнее интерпретировать CPU Usage стоит присмотреться к показателю IPC (Instructions Per Cycle) - сколько процессор выполняет инструкций за один такт.
В условиях современных суперскалярных процессоров этот показатель может достигать четырех и более инструкций.
Хотя в реальных нагрузках значение IPC будет существенно меньше (0.7 - 1.5).
Таким образом высокий CPU Usage при низком IPC (<1) может говорить не о недостатке вычислительных мощностей (и это первое, что приходит в голову), а о проблемах с IO - недостаток кешей и/или их плохая локальность, слишком частое обращение к памяти и подобное.
Для лучшего погружения в тему читай:
* CPU Utilization is Wrong от Brendan Gregg;
* IPC is to CPU% What Milk is to Cinnamon Toast Crunch от Mark Dawson.
——————————————
P.S. получить значение IPC можно с помощью node_exporter через perf коллектор, например так:
sum(rate(node_perf_instructions_total{instance=~"$node",job="$job"}[$__rate_interval])) / sum(rate(node_perf_cpucycles_total{instance=~"$node",job="$job"}[$__rate_interval]))
———————————————
P.P.S. этот же пост, но на linkedin.
tags: #cpu #theory #linux
Wikipedia
Instructions per cycle
measure of processing speed: the average number of instructions executed for each clock cycle
👍12🔥6✍2❤1
Effect of Hyper-Threading in Latency-Critical Multithreaded Cloud Applications and Utilization Analysis of the Major System Resources
Как гиперпоточность/SMT* влияет на производительность различных типов приложений в облачных средах.
Цель исследования — выяснить, какие типы нагрузок выигрывают от SMT, а какие нет.
* SMT позволяет одному физическому процессору выполнять несколько потоков одновременно.
1. Авторы выяснили, что приложения, активно работающие с вводом-выводом (базы данных, очереди, файловые и веб-серверы, кеши), нейтральны к включению SMT.
Их производительность в большей степени зависит от скорости памяти, дисков и сетевых карт, а не от работы процессора.
👉 Потому включение SMT позволяет лучше утилизировать оборудование и экономить ресурсы.
2. Приложения с высокой нагрузкой на процессор (рендеринг видео, сложные расчёты, криптография, high-frequency trading и т. д.) напротив реагировали на SMT негативно - потоки начинают конкурировать за общие ресурсы физического ядра, что приводит к росту задержек.
👉 В окружениях с CPU-bound нагрузкой рекомендуется отключать SMT.
P.S. Кстати метрика IPC (instructions per cycle), которую мы недавно обсуждали, должна помогать в определении профиля нагрузки.
Как гиперпоточность/SMT* влияет на производительность различных типов приложений в облачных средах.
Цель исследования — выяснить, какие типы нагрузок выигрывают от SMT, а какие нет.
* SMT позволяет одному физическому процессору выполнять несколько потоков одновременно.
1. Авторы выяснили, что приложения, активно работающие с вводом-выводом (базы данных, очереди, файловые и веб-серверы, кеши), нейтральны к включению SMT.
Их производительность в большей степени зависит от скорости памяти, дисков и сетевых карт, а не от работы процессора.
👉 Потому включение SMT позволяет лучше утилизировать оборудование и экономить ресурсы.
2. Приложения с высокой нагрузкой на процессор (рендеринг видео, сложные расчёты, криптография, high-frequency trading и т. д.) напротив реагировали на SMT негативно - потоки начинают конкурировать за общие ресурсы физического ядра, что приводит к росту задержек.
👉 В окружениях с CPU-bound нагрузкой рекомендуется отключать SMT.
Не стоит слепо доверять любым исследованиям и это не исключение. Хорошо рассматривать их как повод разобраться глубже и провести свои тесты, учитывающие конкретную специфику.
P.S. Кстати метрика IPC (instructions per cycle), которую мы недавно обсуждали, должна помогать в определении профиля нагрузки.
Telegram
Performance matters!
CPU Usage не так прост в интерпретации, как может показаться.
Сложность в том, что показатель включает в себя не только работу CPU, но и время обращения к памяти.
А так как память на порядки медленнее процессора, то на ожидание ответа может уходить 90%+…
Сложность в том, что показатель включает в себя не только работу CPU, но и время обращения к памяти.
А так как память на порядки медленнее процессора, то на ожидание ответа может уходить 90%+…
👍10
Мониторинг TCP: метрики Zero Window 🚀
Протокол TCP обеспечивает множество функций, включая управление перегрузками.
Для этого используется механизм скользящего окна (sliding window) — объём данных, который отправитель передаёт без подтверждения от получателя.
Размер окна динамически регулируется в зависимости от объёма свободного места в буфере получателя (
Когда буфер получателя заполняется (получатель не успевает за отправителем), TCP расценивает это как перегрузку и уменьшает размер окна в ACK-сегменте вплоть до нуля (Zero Window Advertisement).
Таким образом, при корректной настройке скорости между отправителем и получателем, переполнения очередей удаётся избежать.
С одной стороны, это позволяет избежать потерь пакетов, ретрансмитов и лишней нагрузки на сеть. С другой — мы можем не заметить, что получатель замедлился, и проблема останется скрытой.
❗️❗️❗️Интерпретация метрик ниже ошибочна, за исправленным описанием прошу сюда https://t.iss.one/troubleperf/65 ❗️❗️❗️
К счастью
*
*
*
*
Эти метрики вместе с классическими показателями переполнения буфера и out-of-order очереди позволяют точнее оценивать состояние системы и вовремя выявлять возможные проблемы.
P.S. Лайк можно занести сюда.
tags: #tcp #linux
Протокол TCP обеспечивает множество функций, включая управление перегрузками.
Для этого используется механизм скользящего окна (sliding window) — объём данных, который отправитель передаёт без подтверждения от получателя.
Размер окна динамически регулируется в зависимости от объёма свободного места в буфере получателя (
net.ipv4.tcp_rmem
).Когда буфер получателя заполняется (получатель не успевает за отправителем), TCP расценивает это как перегрузку и уменьшает размер окна в ACK-сегменте вплоть до нуля (Zero Window Advertisement).
Таким образом, при корректной настройке скорости между отправителем и получателем, переполнения очередей удаётся избежать.
С одной стороны, это позволяет избежать потерь пакетов, ретрансмитов и лишней нагрузки на сеть. С другой — мы можем не заметить, что получатель замедлился, и проблема останется скрытой.
❗️❗️❗️Интерпретация метрик ниже ошибочна, за исправленным описанием прошу сюда https://t.iss.one/troubleperf/65 ❗️❗️❗️
К счастью
/proc/net/netstat
позволяет отслеживать события, связанные с нулевым окном:*
TCPFromZeroWindowAdv
— сколько раз отправитель получил уведомление о нулевом окне;*
TCPToZeroWindowAdv
— сколько раз получатель установил нулевое окно;*
TCPWantZeroWindowAdv
— общее время, когда отправитель не мог отправить данные из-за нулевого окна;*
TCPZeroWindowDrop
— сколько раз отправитель отбрасывал пакеты из-за нулевого окна.Эти метрики вместе с классическими показателями переполнения буфера и out-of-order очереди позволяют точнее оценивать состояние системы и вовремя выявлять возможные проблемы.
☝️ показатели нулевого окна доступны в node_exporter через коллектор netstat
P.S. Лайк можно занести сюда.
tags: #tcp #linux
Linkedin
Мониторинг TCP: метрики Zero Window 🚀 | Aleksandr Lebedev
Мониторинг TCP: метрики Zero Window 🚀
Протокол TCP обеспечивает множество функций, включая управление перегрузками.
Для этого используется механизм скользящего окна (sliding window) — объём данных, который отправитель передаёт без подтверждения от получателя.…
Протокол TCP обеспечивает множество функций, включая управление перегрузками.
Для этого используется механизм скользящего окна (sliding window) — объём данных, который отправитель передаёт без подтверждения от получателя.…
🔥16❤3
Рубрика "Вредные советы", №3. Swap.
Есть одно наблюдение и один факт:
* наблюдение: большинство советов по настройке подсистемы памяти Linux рекомендуют либо полностью отключить swap, либо установить
* факт: в большинстве случаев по умолчанию swap включен, а
Не кажется ли странным такой диссонанс?
# Немного про память
Для начала краткий экскурс в то, как работает память в Linux.
Память делится на страницы, которые бывают двух типов: анонимные и file-backed.
- Анонимные страницы содержат данные, созданные во время работы приложений (например, heap или stack).
- File-backed страницы — это файлы, загруженные с диска и хранящиеся в файловом кеше.
Когда система испытывает дефицит памяти, она решает, какие страницы можно выгрузить, чтобы освободить ресурсы. В этом выборе участвует параметр
Кстати, swap используется только для анонимных страниц. File-backed данные, находящиеся на диске, можно всегда подгрузить заново.
В итоге, отключение swap или минимальные значения
---------------------
Возвращаясь к началу: какие системы пострадают от приоритета анонимных страниц над файловым кешем? Где, по вашему мнению, стоит повысить
Давайте обсудим — это интересно!
P. S. поддержать лайком на Linkedin
Есть одно наблюдение и один факт:
* наблюдение: большинство советов по настройке подсистемы памяти Linux рекомендуют либо полностью отключить swap, либо установить
vm.swappiness
на минимальные значения.* факт: в большинстве случаев по умолчанию swap включен, а
vm.swappiness
установлен на 60.Не кажется ли странным такой диссонанс?
# Немного про память
Для начала краткий экскурс в то, как работает память в Linux.
Память делится на страницы, которые бывают двух типов: анонимные и file-backed.
- Анонимные страницы содержат данные, созданные во время работы приложений (например, heap или stack).
- File-backed страницы — это файлы, загруженные с диска и хранящиеся в файловом кеше.
Когда система испытывает дефицит памяти, она решает, какие страницы можно выгрузить, чтобы освободить ресурсы. В этом выборе участвует параметр
vm.swappiness
: чем ниже его значение, тем чаще система будет очищать файловый кеш, сохраняя анонимные страницы с более высоким приоритетом.Кстати, swap используется только для анонимных страниц. File-backed данные, находящиеся на диске, можно всегда подгрузить заново.
В итоге, отключение swap или минимальные значения
vm.swappiness
позволяют держать в памяти анонимные страницы до последнего, что может приводить к ошибкам OOM.---------------------
Возвращаясь к началу: какие системы пострадают от приоритета анонимных страниц над файловым кешем? Где, по вашему мнению, стоит повысить
vm.swappiness
?Давайте обсудим — это интересно!
P. S. поддержать лайком на Linkedin
Linkedin
🚫 Рубрика "Вредные советы", №3. | Aleksandr Lebedev
🚫 Рубрика "Вредные советы", №3. Swap.
Есть одно наблюдение и один факт:
* наблюдение: большинство советов по настройке подсистемы памяти Linux рекомендуют либо полностью отключить swap, либо установить vm.swappiness на минимальные значения.
* факт: в большинстве…
Есть одно наблюдение и один факт:
* наблюдение: большинство советов по настройке подсистемы памяти Linux рекомендуют либо полностью отключить swap, либо установить vm.swappiness на минимальные значения.
* факт: в большинстве…
❤5
Анализируя работу подсистемы памяти я часто обращаюсь к метрикам из
Показатели помогают понять, как система аллоцирует страницы при нехватки свободной памяти.
Что такое pgscan и pgsteal
*
*
Scan/steal процессы могут быть запущены либо фоновым kswapd, либо напрямую приложением (direct).
Причем наличие kswapd в вакууме ничего плохого не подразумевает - демон трудится в бекграунде, чтобы держать определенное кол-во свободных страниц в системе.
А вот наличие direct может настораживать: похоже что kswapd не справляется и приложения явным образом требует предоставить ей памяти. Этот процесс уже происходит в foreground и чреват потерей производительности.
Как интерпретировать значения
* абсолютные значения - чем выше значения, тем чаще свободная память падает до минимума и система вынуждена принимать меры;
* соотношения
Как получить значения в grafana
node_exporter в помощь:
Итого
Резюмируя, если значения
Решения проблемы в вакууме нет, все зависит от кейса: где-то будем докидывать памяти, где-то расширять swap, где-то анализировать потребление памяти приложением, а где-то хватит и лимитов на нее.
/proc/vmstat
- объем просканированных (pgscan
) и украденных (pgsteal
) страниц:pgscan_kswapd
pgsteal_kswapd
pgscan_direct
pgsteal_direct
Показатели помогают понять, как система аллоцирует страницы при нехватки свободной памяти.
Что такое pgscan и pgsteal
*
pgscan
- сколько страниц было просканировано в поисках кандидатов на высвобождение;*
pgsteal
- сколько из просканированных страниц удалось высвободить (украсть).Scan/steal процессы могут быть запущены либо фоновым kswapd, либо напрямую приложением (direct).
Причем наличие kswapd в вакууме ничего плохого не подразумевает - демон трудится в бекграунде, чтобы держать определенное кол-во свободных страниц в системе.
А вот наличие direct может настораживать: похоже что kswapd не справляется и приложения явным образом требует предоставить ей памяти. Этот процесс уже происходит в foreground и чреват потерей производительности.
Как интерпретировать значения
* абсолютные значения - чем выше значения, тем чаще свободная память падает до минимума и система вынуждена принимать меры;
* соотношения
pgsteal/pgscan
- высокое значение (95%+) говорит, что большая часть просканированных страниц успешно освобождается (это хорошо). Низкое напротив - система тратит много ресурсов на сканирование, прежде чем найдет подходящие страницы для освобождения.Как получить значения в grafana
node_exporter в помощь:
node_vmstat_pgscan_direct
node_vmstat_pgsteal_direct
node_vmstat_pgscan_kswapd
node_vmstat_pgsteal_kswapd
Итого
Резюмируя, если значения
pgsteal
, pgscan
растут это сигнал, что память в системе переутилизирована и хорошо бы обратить на это внимание. Решения проблемы в вакууме нет, все зависит от кейса: где-то будем докидывать памяти, где-то расширять swap, где-то анализировать потребление памяти приложением, а где-то хватит и лимитов на нее.
🔥11👍4
𝗚𝗶𝘁𝗟𝗮𝗯 выделяется среди других компаний своими открытыми репозиториями с множеством полезных гайдов и обсуждений 💬
В одном из таких материалов — заметке "𝗛𝗼𝘄 𝘁𝗼 𝘂𝘀𝗲 𝗳𝗹𝗮𝗺𝗲𝗴𝗿𝗮𝗽𝗵𝘀 𝗳𝗼𝗿 𝗽𝗲𝗿𝗳𝗼𝗿𝗺𝗮𝗻𝗰𝗲 𝗽𝗿𝗼𝗳𝗶𝗹𝗶𝗻𝗴" — автор объясняет, что такое 𝗳𝗹𝗮𝗺𝗲𝗴𝗿𝗮𝗽𝗵, зачем он нужен, как собирать данные и какие трудности могут возникнуть при анализе этих красно-желтых графиков.
Заметка также содержит практические примеры интерпретации 𝗳𝗹𝗮𝗺𝗲𝗴𝗿𝗮𝗽𝗵. Для сбора данных используется
На ядрах 4.19+ лучше использовать eBPF-инструмент
В одном из таких материалов — заметке "𝗛𝗼𝘄 𝘁𝗼 𝘂𝘀𝗲 𝗳𝗹𝗮𝗺𝗲𝗴𝗿𝗮𝗽𝗵𝘀 𝗳𝗼𝗿 𝗽𝗲𝗿𝗳𝗼𝗿𝗺𝗮𝗻𝗰𝗲 𝗽𝗿𝗼𝗳𝗶𝗹𝗶𝗻𝗴" — автор объясняет, что такое 𝗳𝗹𝗮𝗺𝗲𝗴𝗿𝗮𝗽𝗵, зачем он нужен, как собирать данные и какие трудности могут возникнуть при анализе этих красно-желтых графиков.
Заметка также содержит практические примеры интерпретации 𝗳𝗹𝗮𝗺𝗲𝗴𝗿𝗮𝗽𝗵. Для сбора данных используется
linux-perf
: он добавляет оверхед, но подходит для старых версий ядер. На ядрах 4.19+ лучше использовать eBPF-инструмент
profile
от bcc.GitLab
docs/tutorials/how_to_use_flamegraphs_for_perf_profiling.md · v2.198.1 · GitLab.com / Runbooks · GitLab
Runbooks for the stressed on-call https://runbooks.gitlab.com Mirrored to https://ops.gitlab.net/gitlab-com/runbooks
🔥7👍2
Когда система становится сложнее (добавляются новые технологии, версии ядер, типы дистрибутивов, машины, кластеры), необходимость в унификации и системном подходе к процессам заметно возрастает.
Профилирование приложений в таких условиях превращается в челендж: разные окружения, требования, версии и типы рантаймов усложняют задачу.
Предлагаю обменяться опытом:
* какой тулинг используете? Например, унифицированные инструменты вроде bcc (eBPF) или языкоориентированные (pprof, async-profiler);
* используете ли continuous profiling? (coroot, pyroscope, etc);
* в каких окружениях работаете (k8s, docker, чистый linux (windows?);
* как доставляете пререквизиты? доступ к
* как обходите ограничения по ИБ? Например, async-profiler требует RW-доступа к файловой системе контейнера, а требования ИБ настаивают на RO-доступе.
Будет интересно узнать, с какими сложностями сталкиваетесь и какие выбираете подходы!
——
Это же обсуждение на linkedin
Профилирование приложений в таких условиях превращается в челендж: разные окружения, требования, версии и типы рантаймов усложняют задачу.
Предлагаю обменяться опытом:
* какой тулинг используете? Например, унифицированные инструменты вроде bcc (eBPF) или языкоориентированные (pprof, async-profiler);
* используете ли continuous profiling? (coroot, pyroscope, etc);
* в каких окружениях работаете (k8s, docker, чистый linux (windows?);
* как доставляете пререквизиты? доступ к
symbols
, frame pointer
, linux-headers
. Тащите все это добро проактивно или "по требованию?;* как обходите ограничения по ИБ? Например, async-profiler требует RW-доступа к файловой системе контейнера, а требования ИБ настаивают на RO-доступе.
Будет интересно узнать, с какими сложностями сталкиваетесь и какие выбираете подходы!
——
Это же обсуждение на linkedin
🔥4
А вынесу из комментарий ответ по «проблемам» профилирования.
Унификация это то, к чему хочется стремиться. То есть одним инструментом профилировать весь зоопарк рантаймов.
На эту роль отлично подходят linux-perf или profile от BCC, но тут есть нюансы:
* многие начитавшись "вредных советов" отключают frame pointer и вырезают symbols при сборке бинарников, отчего профилирование становится бесполезным - на нем ничего не видно. Соответственно у каждого рантайма по своему включаются/отключаются эти опции;
* по умолчанию хочется использовать profile на eBPF, так как он дает сильно меньший оверхед, но для этого и linux ядра должны быть более менее свежие и скомпилированы они должны быть с соответствующими флагами, а еще на машинах должны быть подходящие версии linux-headers ;
* предыдущий пункт отчасти решает такая штука как libbpf, с помощью нее можно собрать бинарник profile, который уже в себе будет иметь все нужное(считай докер контейнер), но требования к свежей версии ядра никуда не деваются;
* далее проблемы на уровне контейнеризации, тот же libbpf profile (переносимый который) в нынешней реализации не container awareness, а значит умеет профилировать только процессы на уровне хоста, значит требуется куча зависимостей;
* а еще есть требования от ИБ, вот про тот же async-profiler и RO файловую систему. Можно деплоить Поды для профилирования на отдельные ноды, где будет все нужное, проводить тесты и деплоить обратно, но это мертворожденная история.
Вообщем проблем куча и их надо решать)
Унификация это то, к чему хочется стремиться. То есть одним инструментом профилировать весь зоопарк рантаймов.
На эту роль отлично подходят linux-perf или profile от BCC, но тут есть нюансы:
* многие начитавшись "вредных советов" отключают frame pointer и вырезают symbols при сборке бинарников, отчего профилирование становится бесполезным - на нем ничего не видно. Соответственно у каждого рантайма по своему включаются/отключаются эти опции;
* по умолчанию хочется использовать profile на eBPF, так как он дает сильно меньший оверхед, но для этого и linux ядра должны быть более менее свежие и скомпилированы они должны быть с соответствующими флагами, а еще на машинах должны быть подходящие версии linux-headers ;
* предыдущий пункт отчасти решает такая штука как libbpf, с помощью нее можно собрать бинарник profile, который уже в себе будет иметь все нужное(считай докер контейнер), но требования к свежей версии ядра никуда не деваются;
* далее проблемы на уровне контейнеризации, тот же libbpf profile (переносимый который) в нынешней реализации не container awareness, а значит умеет профилировать только процессы на уровне хоста, значит требуется куча зависимостей;
* а еще есть требования от ИБ, вот про тот же async-profiler и RO файловую систему. Можно деплоить Поды для профилирования на отдельные ноды, где будет все нужное, проводить тесты и деплоить обратно, но это мертворожденная история.
Вообщем проблем куча и их надо решать)
GitHub
libbpf-tools: add profile by ekyooo · Pull Request #3782 · iovisor/bcc
It is based on Brendan Gregg's BCC profile and much of the code for it is borrowed from offcputime.c and ruqlen.c.
I'm not sure if libbpf-tools requires a profile. So I'm sh...
I'm not sure if libbpf-tools requires a profile. So I'm sh...
👍2🔥2
Investigation of a Cross-regional Network Performance Issue
Траблшутинг от Netflix: исследование причин низкой скорости сети между дата-центрами.
Подобные статьи люблю за то, что можно:
1. "подсмотреть", как инженеры строят гипотезы, проверяют их и находят решения;
2. узнать практические приёмы/фишки и применить в своей работе.
Из интересного
— контейнерам в Netflix по умолчанию ограничивают пропускную способность сети (интересно на основе чего выбираются те или иные значения);
— в окружениях за NAT пары
— в ядре Linux 6.6+ изменился механизм расчёта TCP Receive Window:
— ранее использовался статический параметр
— теперь применяются динамические расчёты на основе
Кроме того, упоминается поле tcp_sock->window_clamp:
Звучит как баг, а не фича. Или это все работает немного не так;)
P.S. Подробнее вопрос Receive Window разбирается Cloudflare в Optimizing TCP for high WAN throughput while preserving low latency.
tags: #tcp #linux #kernel
Траблшутинг от Netflix: исследование причин низкой скорости сети между дата-центрами.
Подобные статьи люблю за то, что можно:
1. "подсмотреть", как инженеры строят гипотезы, проверяют их и находят решения;
2. узнать практические приёмы/фишки и применить в своей работе.
Из интересного
— контейнерам в Netflix по умолчанию ограничивают пропускную способность сети (интересно на основе чего выбираются те или иные значения);
— в окружениях за NAT пары
ip:port
на сервере и клиенте отличаются. Для идентификации одного TCP-стрима можно фильтровать пакеты по Sequence Numbers;— в ядре Linux 6.6+ изменился механизм расчёта TCP Receive Window:
— ранее использовался статический параметр
net.ipv4.tcp_adv_win_scale
.— теперь применяются динамические расчёты на основе
scaling_ratio
, стартовое значение которого — 0.25.Кроме того, упоминается поле tcp_sock->window_clamp:
Это максимальное значение окна приёма, которое может быть объявлено. Оно устанавливается как 0.25 от rcvbuf на основе начального значения scaling_ratio. Из-за этого размер окна ограничен этим значением и не может увеличиваться.
Звучит как баг, а не фича. Или это все работает немного не так;)
P.S. Подробнее вопрос Receive Window разбирается Cloudflare в Optimizing TCP for high WAN throughput while preserving low latency.
tags: #tcp #linux #kernel
Medium
Investigation of a Cross-regional Network Performance Issue
Hechao Li, Roger Cruz
🔥8
Как считается TCP Window Clamp
Ранее я упоминал статью Netflix Investigation of a Cross-regional Network Performance Issue. В ней разбирается деградация скорости TCP-соединений между дата-центрами и проблема возникла из-за изменения алгоритма расчёта TCP Receive Window в новых версиях ядра.
Как часто бывает, такие материалы оставляют больше вопросов, чем ответов — “know unknown” чистой воды.
Я покопался в исходниках Linux, чтобы лучше понять механизм подсчета TCP Window. Делюсь изысканиями:)
tags: #tcp #linux #kernel
Ранее я упоминал статью Netflix Investigation of a Cross-regional Network Performance Issue. В ней разбирается деградация скорости TCP-соединений между дата-центрами и проблема возникла из-за изменения алгоритма расчёта TCP Receive Window в новых версиях ядра.
Как часто бывает, такие материалы оставляют больше вопросов, чем ответов — “know unknown” чистой воды.
Я покопался в исходниках Linux, чтобы лучше понять механизм подсчета TCP Window. Делюсь изысканиями:)
tags: #tcp #linux #kernel
🔥3👏2
Я отмечал ранее, что интерпретация CPU Usage — вещь не очевидная.
Высокие значения не всегда означают, что перегружен именно процессор — иногда проблема в скорости работы с памятью.
Понять во что упираемся помогает параметр — IPC (Instructions Per Cycle):
- высокий CPU Usage, высокий IPC: основная нагрузка идет на процессор;
- высокий CPU Usage, низкий IPC: узкое место в работе с памятью.
——
Окей, допустим мы поняли: надо оптимизировать память. С чего начать?
Отправной точкой может стать сборник статей Johnny's Software Lab: Memory Subsystem Optimizations.
Внутри:
- основы устройства памяти;
- советы по оптимизации кода, ОС и железа;
- техники для бенчмарков;
- и всякое другое.
Разбираемся, применяем на практике и делимся опытом;)
Высокие значения не всегда означают, что перегружен именно процессор — иногда проблема в скорости работы с памятью.
Понять во что упираемся помогает параметр — IPC (Instructions Per Cycle):
- высокий CPU Usage, высокий IPC: основная нагрузка идет на процессор;
- высокий CPU Usage, низкий IPC: узкое место в работе с памятью.
——
Окей, допустим мы поняли: надо оптимизировать память. С чего начать?
Отправной точкой может стать сборник статей Johnny's Software Lab: Memory Subsystem Optimizations.
Внутри:
- основы устройства памяти;
- советы по оптимизации кода, ОС и железа;
- техники для бенчмарков;
- и всякое другое.
Разбираемся, применяем на практике и делимся опытом;)
Telegram
Performance matters!
CPU Usage не так прост в интерпретации, как может показаться.
Сложность в том, что показатель включает в себя не только работу CPU, но и время обращения к памяти.
А так как память на порядки медленнее процессора, то на ожидание ответа может уходить 90%+…
Сложность в том, что показатель включает в себя не только работу CPU, но и время обращения к памяти.
А так как память на порядки медленнее процессора, то на ожидание ответа может уходить 90%+…
👍12🔥7
Breaking down CPU speed: How utilization impacts performance
Инженеры GitHub провели исследование, чтобы найти оптимальный баланс между загрузкой CPU и скоростью его работы.
Для этого они зеркалили продовый трафик в отдельное окружение и замеряли latency обработки операций при разной степени утилизации процессора. Задача была с одной стороны оставаться в рамках SLA, а с другой — не позволять ресурсам простаивать.
В результате, для их типичной рабочей нагрузки (IO-bound) и используемых процессоров (Intel), оптимальная утилизация CPU оказалась в районе 61%.
Интересно, что Б. Грегг в своей книге "Systems Performance" часто упоминает порог в 60% как точку, после которой ресурс (будь то диск или CPU) может стать узким местом в системе.
Цитата:
P.S. Теперь дело "за малым": настроить процессы resource management и capacity planning, чтобы держать утилизацию в районе этих цифр. Изи)
Инженеры GitHub провели исследование, чтобы найти оптимальный баланс между загрузкой CPU и скоростью его работы.
Для этого они зеркалили продовый трафик в отдельное окружение и замеряли latency обработки операций при разной степени утилизации процессора. Задача была с одной стороны оставаться в рамках SLA, а с другой — не позволять ресурсам простаивать.
В результате, для их типичной рабочей нагрузки (IO-bound) и используемых процессоров (Intel), оптимальная утилизация CPU оказалась в районе 61%.
Интересно, что Б. Грегг в своей книге "Systems Performance" часто упоминает порог в 60% как точку, после которой ресурс (будь то диск или CPU) может стать узким местом в системе.
Цитата:
Netflix commonly uses ASGs that target a CPU utilization of 60%, and will scale up and down with the load to maintain that target.
P.S. Теперь дело "за малым": настроить процессы resource management и capacity planning, чтобы держать утилизацию в районе этих цифр. Изи)
The GitHub Blog
Breaking down CPU speed: How utilization impacts performance
The Performance Engineering team at GitHub assessed how CPU performance degrades as utilization increases and how this relates to capacity.
👍18🤨1🤝1
Scaling in the Linux Networking Stack (scaling.txt)
Документ от разработчиков ядра Linux описывает пять техник, которые помогают повысить производительность сетевого стека в многоядерных системах.
Это:
* RSS: Receive Side Scaling
* RPS: Receive Packet Steering
* RFS: Receive Flow Steering
* Accelerated Receive Flow Steering
* XPS: Transmit Packet Steering
В нашей инфраструктуре мы уже давно и успешно используем RSS.
Это аппаратная технология, суть следующая.
Когда поступает сетевой пакет, на основе его заголовков вычисляется хеш. Полученное значение сопоставляется с таблицей, где каждому значению соответствует определенная очередь (RX).
Каждая RX-очередь привязана к конкретному ядру процессора.
Таким образом:
1. Обработка трафика распределяется между несколькими CPU, что позволяет эффективно использовать ресурсы;
2. Все пакеты одного соединения попадают в одну очередь. Это исключает проблему "out of order" пакетов.
Однако бывают ситуации, когда распределить обработку трафика между ядрами не получается, и отдельное ядро или группа ядер оказывается сильно перегруженной:
- одно конкретное соединение прокачивает кратно больший объем трафика, чем другие;
- RX-очередей в системе меньше, чем доступных CPU.
Мы, например, сталкивались с такими проблемами при использовании MetalLB в L2-режиме: весь трафик шел через одну машину MetalLB (мастер) и "приклеивался" к одной RX-очереди на Ingress Controller. Остальные ядра и RX-очереди при этом простаивали.
В подобных случаях может помочь другая техника, описанная в том же документе — RPS (Receive Packet Steering).
RPS — это программная реализация RSS. Она позволяет распределить RX-очереди по конкретным ядрам, выравнивая нагрузку между ними.
Но есть и минусы:
- Программная реализация создает дополнительную нагрузку на CPU, что проявляется в увеличении числа IRQ на графике загрузки процессора;
- Снижается "локальность" данных в кэшах процессора, что может повлиять на производительность.
(на скрине RPS включили после 16:00)
———
Тема сложная, и я не уверен, что до конца понимаю, как это все работает;)
Было бы интересно узнать, какие техники масштабирования трафика используете вы и как справляетесь с подобными проблемами.
Дальнейшее чтение:
- сам документ scaling.txt
- расшифровка доклада от Одноклассников, где ребята решали похожие проблемы;
- примерно тоже самое, но забугорный доклад по перформансу сетевого стека.
tags: #network #tuning #linux #кейс
Документ от разработчиков ядра Linux описывает пять техник, которые помогают повысить производительность сетевого стека в многоядерных системах.
Это:
* RSS: Receive Side Scaling
* RPS: Receive Packet Steering
* RFS: Receive Flow Steering
* Accelerated Receive Flow Steering
* XPS: Transmit Packet Steering
В нашей инфраструктуре мы уже давно и успешно используем RSS.
Это аппаратная технология, суть следующая.
Когда поступает сетевой пакет, на основе его заголовков вычисляется хеш. Полученное значение сопоставляется с таблицей, где каждому значению соответствует определенная очередь (RX).
Каждая RX-очередь привязана к конкретному ядру процессора.
Таким образом:
1. Обработка трафика распределяется между несколькими CPU, что позволяет эффективно использовать ресурсы;
2. Все пакеты одного соединения попадают в одну очередь. Это исключает проблему "out of order" пакетов.
Однако бывают ситуации, когда распределить обработку трафика между ядрами не получается, и отдельное ядро или группа ядер оказывается сильно перегруженной:
- одно конкретное соединение прокачивает кратно больший объем трафика, чем другие;
- RX-очередей в системе меньше, чем доступных CPU.
Мы, например, сталкивались с такими проблемами при использовании MetalLB в L2-режиме: весь трафик шел через одну машину MetalLB (мастер) и "приклеивался" к одной RX-очереди на Ingress Controller. Остальные ядра и RX-очереди при этом простаивали.
В подобных случаях может помочь другая техника, описанная в том же документе — RPS (Receive Packet Steering).
RPS — это программная реализация RSS. Она позволяет распределить RX-очереди по конкретным ядрам, выравнивая нагрузку между ними.
Но есть и минусы:
- Программная реализация создает дополнительную нагрузку на CPU, что проявляется в увеличении числа IRQ на графике загрузки процессора;
- Снижается "локальность" данных в кэшах процессора, что может повлиять на производительность.
(на скрине RPS включили после 16:00)
———
Тема сложная, и я не уверен, что до конца понимаю, как это все работает;)
Было бы интересно узнать, какие техники масштабирования трафика используете вы и как справляетесь с подобными проблемами.
Дальнейшее чтение:
- сам документ scaling.txt
- расшифровка доклада от Одноклассников, где ребята решали похожие проблемы;
- примерно тоже самое, но забугорный доклад по перформансу сетевого стека.
tags: #network #tuning #linux #кейс
👍13
Ingress NGINX Controller vs ClusterIP (IPtables): Балансировка.
Задумывались ли вы почему балансировка через Ingress NGINX Controller показывает более ровное распределение трафика по Подам в сравнении с ClusterIP (IPtables)?
Я до недавнего времени не очень, но "сигналы с мест" требовали разобраться.
Балансировка через ClusterIP (IPtables)
ClusterIP (далее svc) это сущность Kubernetes, позволяющая приземлять трафик в Под.
В свою очередь svc это просто набор IPtables правил (или правил аналогичных инструментов), "приклеивающий" запрос к конкретному Поду.
Примерно так:
Что можно интерпретировать как:
* Pod1 будет выбран в качестве апстрима в 33% случаев;
* далее в 50% Pod2;
* иначе апстримом станет Pod3.
Таким образом, если есть три входящих коннекта, они могут распределиться как по одному на каждый Под, так и все три упасть в один конкрентный.
Теория вероятностей.
Балансировка через Ingress NGINX Controller
Зная о том как функционирует svc, я по наивности полагал, что и Ingress Controller (далее IC) оперирует в качестве апстримов сущностью svc, что будет в итоге давать тот же "уровень" баланcировки.
Факты говорили об обратном, потому я пошел перепроверять.
Под каждый объект Ingress рендерится секция
В ней директива
В
——
Да и как иначе IC сможет обеспечивать разные типы балансировки? А по умолчанию используется round-robin.
Задумывались ли вы почему балансировка через Ingress NGINX Controller показывает более ровное распределение трафика по Подам в сравнении с ClusterIP (IPtables)?
Я до недавнего времени не очень, но "сигналы с мест" требовали разобраться.
Балансировка через ClusterIP (IPtables)
ClusterIP (далее svc) это сущность Kubernetes, позволяющая приземлять трафик в Под.
В свою очередь svc это просто набор IPtables правил (или правил аналогичных инструментов), "приклеивающий" запрос к конкретному Поду.
Примерно так:
iptables -t nat -A KUBE-SVC -m random --probability 0.33 -j DNAT --to <Pod1>
iptables -t nat -A KUBE-SVC -m random --probability 0.50 -j DNAT --to <Pod2>
iptables -t nat -A KUBE-SVC -j DNAT --to <Pod3>
Что можно интерпретировать как:
* Pod1 будет выбран в качестве апстрима в 33% случаев;
* далее в 50% Pod2;
* иначе апстримом станет Pod3.
Таким образом, если есть три входящих коннекта, они могут распределиться как по одному на каждый Под, так и все три упасть в один конкрентный.
Теория вероятностей.
Балансировка через Ingress NGINX Controller
Зная о том как функционирует svc, я по наивности полагал, что и Ingress Controller (далее IC) оперирует в качестве апстримов сущностью svc, что будет в итоге давать тот же "уровень" баланcировки.
Факты говорили об обратном, потому я пошел перепроверять.
Под каждый объект Ingress рендерится секция
server{}
шаблона nginx.tmpl
(пруф):{{ range $tcpServer := .TCPBackends }}
server {...}
{{ end }}
В ней директива
proxy_pass
указывает на некий upstream_balancer
: ### Attention!!!
# We no longer create "upstream" section for every backend.
# Backends are handled dynamically using Lua....
...
balancer_by_lua_block {
balancer.balance()
}
...
В
balancer.balance()
и живет логика выбора апстрима, где peer
== endpoint (считай Pod
):...
local peer = balancer:balance()
if not peer then
ngx.log(ngx.WARN, "no peer was returned, balancer: " .. balancer.name)
return
end
...
——
Да и как иначе IC сможет обеспечивать разные типы балансировки? А по умолчанию используется round-robin.
👍10👏3❤1😐1