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
photo_2025-01-20_08-36-01.jpg
60.5 KB
Ранее я писал о баге Haproxy: после рестарта треды не завершались, что приводило к их накоплению, память иссякала и приходил OOM Killer.
Проблему решали костылем — директива hard-stop-after принудительно завершает треды после рестарта.
Но Haproxy не сдается и наносит ответный удар!
Симптомы схожи: утечка памяти.
Но сбой наступает когда (это гипотеза) заканчивается память для TCP-буферов (
На скрине такой период отмечен красным прямоугольником.
Где
Оказалось, что система насыщается "повисшими" соединениями, чьи буферы сокетов содержат данные:
где:
*
*
А раз есть не прочитанные данные, значит таймер TCP keepalive не взводится:
Был бы повод, а костыль найдется!
Ребята из CloudFlare писали в свое время статью When TCP sockets refuse to die, где в виде решения предлагалось использовать опцию сокета
В свою очередь Haproxy поддерживает ее через tcp-ut.
Посмотрим, как себя покажет.
tags: #tcp #linux #kernel #troubleshooting #кейс
Проблему решали костылем — директива hard-stop-after принудительно завершает треды после рестарта.
Но Haproxy не сдается и наносит ответный удар!
Причины еще предстоит выяснить, поэтому это скорее "заметка с полей"
Симптомы схожи: утечка памяти.
Но сбой наступает когда (это гипотеза) заканчивается память для TCP-буферов (
net.ipv4.tcp_mem
) - ядро с переменным успехом пытается освободить память для новых / существующих соединений, что приводит к затруднению в сетевых взаимодействиях.На скрине такой период отмечен красным прямоугольником.
# sysctl net.ipv4.tcp_mem
net.ipv4.tcp_mem = 90435 120582 180870
Где
180870
- максимальное значение (в страницах памяти) под все TCP сокеты в системе, что равно ~ 706MB. Оказалось, что система насыщается "повисшими" соединениями, чьи буферы сокетов содержат данные:
# ss -ntOai | awk '{for(i=1;i<=NF;i++)if($i~/^lastsnd:/){split($i,a,":");print a[2], $2, $4, $5}}' | sort -n | tail
#lastsnd # Recv-Q #Src #Dst
234423668 157355 10.11.12.4:57354 10.11.6.123:80
235316436 302417 10.11.12.4:56232 10.11.6.124:80
238200680 301585 10.11.12.4:37940 10.11.6.124:80
238726828 300103 10.11.12.4:58944 10.11.6.124:80
243816724 297015 10.11.12.4:51700 10.11.6.125:80
251456440 302959 10.11.12.4:52324 10.11.6.125:80
252237780 302464 10.11.12.4:47786 10.11.6.123:80
257868244 163453 10.11.12.4:41568 10.11.6.125:80
259905196 300433 10.11.12.4:40202 10.11.6.123:80
261307944 214022 10.11.12.4:54888 10.11.6.123:80 # это ~ 72 часа
где:
*
lastsnd
- время с последней отправки данных, в милисекундах;*
Recv-Q
- объем не прочитанных данных, в байтах.А раз есть не прочитанные данные, значит таймер TCP keepalive не взводится:
static void tcp_keepalive_timer (struct timer_list *t)
{
...
/* It is alive without keepalive 8) */
if (tp->packets_out || !tcp_write_queue_empty(sk))
goto resched;
...
resched:
inet_csk_reset_keepalive_timer (sk, elapsed);
goto out;
...
out:
bh_unlock_sock(sk);
sock_put(sk);
}
Был бы повод, а костыль найдется!
Ребята из CloudFlare писали в свое время статью When TCP sockets refuse to die, где в виде решения предлагалось использовать опцию сокета
TCP_USER_TIMEOUT
:...it specifies the maximum amount of time in milliseconds that transmitted data may remain unacknowledged, or buffered data may remain untransmitted (due to zero window size) before TCP will forcibly close the corresponding connection and return **ETIMEDOUT** to the application...
В свою очередь Haproxy поддерживает ее через tcp-ut.
Посмотрим, как себя покажет.
tags: #tcp #linux #kernel #troubleshooting #кейс
👍21🔥2
(Не) очевидные особенности настроек TCP сокетов. Часть 1.
Задача: затюнить размеры сокетов у Nginx, чтобы без потерь переживать всплески трафика.
Уточним размер буфера чтения:
Нас интересует значение
Окей, допустим мы хотим сделать его равным 6291456 байт (~6мб).
В Nginx за размер буфер приема отвечает параметр
Вносим изменения в конфиг и перезапускаем Nginx:
Проверяем:
———
Среднее значение
Документация к
1. ядро будет удваивать переданное значение (что и увидим в`rb`)
2. дефолтное (начальное) равно
3. максимум задается через
Окей, произведем расчеты:
Похоже, что мы уперлись в
Получаем искомое
Промежуточный итог: если мы выставляем руками размеры буферов на уровне приложение (опция
Следующая часть.
tags: #tcp #linux #kernel
Задача: затюнить размеры сокетов у Nginx, чтобы без потерь переживать всплески трафика.
Уточним размер буфера чтения:
# ss -ntlmO | grep ':80 '
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* skmem:(r0,rb131072,t0,tb16384,f0,w0,o0,bl0,d0)
Нас интересует значение
rb
- 131072 байт. Окей, допустим мы хотим сделать его равным 6291456 байт (~6мб).
В Nginx за размер буфер приема отвечает параметр
rcvbuf
, см. док .Вносим изменения в конфиг и перезапускаем Nginx:
# grep listen /etc/nginx/nginx.conf
listen 80 rcvbuf=6291456;
# systemctl restart nginx
Проверяем:
# ss -ntlmO | grep ':80 '
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* skmem:(r0,rb425984,t0,tb16384,f0,w0,o0,bl0,d0)
425984
не похоже на 6291456
;)———
# sysctl -a | grep rmem
net.core.rmem_default = 212992
net.core.rmem_max = 212992
net.ipv4.tcp_rmem = 4096 131072 18874368
...
Среднее значение
tcp_rmem
соответствует размеру буфера до изменений, а новое (425984
) не совпадает ни с чем.Документация к
rcvbuf
говорит, что настройка соответствует опции сокета SO_RCVBUF
:# man 7 socket
SO_RCVBUF
Sets or gets the maximum socket receive buffer in bytes. The kernel doubles this value (to allow space for bookkeeping overhead) when it is set using setsockopt(2), and this doubled value is returned by getsockopt(2). The default value is set by the /proc/sys/net/core/rmem_default file, and the maximum allowed value is set by the /proc/sys/net/core/rmem_max file...
1. ядро будет удваивать переданное значение (что и увидим в`rb`)
2. дефолтное (начальное) равно
rmem_default
;3. максимум задается через
rmem_max
.Причины удвоения (хотя там могут быть разные варианты) стоит искать в "man 7 tcp" и в "net.ipv4.tcp_adv_win_scale". Или в подробной статье от CloudFlare.
Окей, произведем расчеты:
425984 / 2 = 212992
.Похоже, что мы уперлись в
net.core.rmem_max
:# sysctl net.core.rmem_max=6291456
net.core.rmem_max = 6291456
# nginx -s reload
# ss -ntlmO | grep '0.0.0.0:80 '
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* skmem:(r0,rb12582912,t0,tb16384,f0,w0,o0,bl0,d0)
Получаем искомое
rb
в 12582912
(6mb * 2). Промежуточный итог: если мы выставляем руками размеры буферов на уровне приложение (опция
SO_RCVBUF
), следует учесть это и в net.core.rmem_max
.Следующая часть.
tags: #tcp #linux #kernel
The Cloudflare Blog
Optimizing TCP for high WAN throughput while preserving low latency
Tuning TCP servers for both low latency and high WAN throughput usually involves making tradeoffs. Due to the breadth of products and variety of traffic patterns at Cloudflare, we need both. In this post, we describe how we modified the Linux kernel to optimize…
🔥15
(Не) очевидные особенности настроек TCP сокетов. Часть 2.
Начало тут.
Есть мнение, что механизмы autotuning TCP в Linux не просто так придумали и в норме стоит пользоваться именно ими, а хардкод стоит избегать.
Потому разберемся с настройкой
Перефразирую:
- дефолтное значение
- максимальное значение
Делаем промежуточные вывод, что:
1.
2.
Проверим!
Начнем с конца:
Действительно, максимальный
Теперь проверим, что
Размер буфера выставляется равным дефолтному
——
Особо пытливым для перепроверки можно обратиться к исходникам:
2. либо в определении начального TCP окна:
что все таки не бьется с документацией.
Выходит обманывают нас разработчики или я так интерпретирую тексты :)
Окончательные выводы:
1.
2.
В итоге решение задачи может быть следующим:
tags: #tcp #linux #kernel
Начало тут.
Есть мнение, что механизмы autotuning TCP в Linux не просто так придумали и в норме стоит пользоваться именно ими, а хардкод стоит избегать.
Потому разберемся с настройкой
net.ipv4.tcp_rmem
и узнаем оказывает ли на него влияние net.core.rmem_max
:# man 7 tcp
...
tcp_rmem (since Linux 2.4)
This is a vector of 3 integers: [min, default, max]. These parameters are used by TCP to regulate receive buffer sizes. ...
min minimum size of the receive buffer used by each TCP socket. The default value is the system page size. (On Linux 2.4, the default value is 4 kB, lowered to PAGE_SIZE bytes in low-memory systems.)...
default the default size of the receive buffer for a TCP socket. This value overwrites the initial default buffer size from the generic global net.core.rmem_default defined for all protocols...
max the maximum size of the receive buffer used by each TCP socket. This value does not override the global net.core.rmem_max. This is not used to limit the size of the receive buffer declared using SO_RCVBUF on a socket...
Перефразирую:
- дефолтное значение
tcp_rmem
перезаписывает net.core.rmem_default
— это мы заметили в самом начале, до использования rcvbuf
;- максимальное значение
tcp_rmem
НЕ перезаписывает net.core.rmem_max
и НЕ используется при выставлении SO_RCVBUF
.Делаем промежуточные вывод, что:
1.
net.core.rmem_max
задает жесткий лимит на размер TCP буфера;2.
tcp_rmem
не участвует в игре при выставлении SO_RCVBUF
.Проверим!
Начнем с конца:
# sysctl -a | grep rmem
net.core.rmem_default = 212992
net.core.rmem_max = 6291456
net.ipv4.tcp_rmem = 4096 131072 18874368
### Выставляем максимальное значение tcp_rmem ниже rmem_max
# sysctl net.ipv4.tcp_rmem="4096 131072 851968"
net.ipv4.tcp_rmem = 4096 131072 851968
# grep listen /etc/nginx/nginx.conf
listen 80 rcvbuf=6291456;
# systemctl restart nginx
# ss -ntlmO | grep '0.0.0.0:80 '
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* skmem:(r0,rb12582912,t0,tb16384,f0,w0,o0,bl0,d0)
Действительно, максимальный
tcp_rmem
не сыграл.Теперь проверим, что
net.core.rmem_max
задает жесткий лимит над размером TCP сокетов:# sysctl -a | grep rmem
net.core.rmem_default = 212992
net.core.rmem_max = 6291456
net.ipv4.tcp_rmem = 4096 131072 851968
### Делаем net.core.rmem_max ниже чем дефолтный tcp_rmem, значение которого поднимем
# sysctl net.core.rmem_max=212992
net.core.rmem_max = 212992
# sysctl net.ipv4.tcp_rmem="4096 524288 851968"
net.ipv4.tcp_rmem = 4096 524288 851968
### Убираем директиву rcvbuf
# grep listen /etc/nginx/nginx.conf
listen 80;
# systemctl restart nginx
# ss -ntlmO | grep '0.0.0.0:80 '
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* skmem:(r0,rb524288,t0,tb16384,f0,w0,o0,bl0,d0)
Размер буфера выставляется равным дефолтному
tcp_rmem
(кстати без удвоений), который больше net.core.rmem_max
. ——
Особо пытливым для перепроверки можно обратиться к исходникам:
1. net.core.rmem_max
участвует либо в обработке опции SO_RCVBUF:...
case SO_RCVBUF:
...
__sock_set_rcvbuf(sk, min_t(u32, val, READ_ONCE(sysctl_rmem_max)));
2. либо в определении начального TCP окна:
...
space = max_t(u32, space, READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_rmem[2]));
space = max_t(u32, space, READ_ONCE(sysctl_rmem_max));
space = min_t(u32, space, *window_clamp);
*rcv_wscale = clamp_t(int, ilog2(space) - 15,
0, TCP_MAX_WSCALE);
что все таки не бьется с документацией.
Выходит обманывают нас разработчики или я так интерпретирую тексты :)
Окончательные выводы:
1.
net.core.rmem_max
играет только при ручном выставлении размеров сокетов (SO_RCVBUF
);2.
net.ipv4.tcp_rmem
напротив, не участвует в SO_RCVBUF
, зато позволяет использовать автоподстройку, что в большинстве случаев будет более гибким решением.В итоге решение задачи может быть следующим:
# sysctl net.ipv4.tcp_rmem="4096 1048576 12582912"
tags: #tcp #linux #kernel
Telegram
Performance matters!
(Не) очевидные особенности настроек TCP сокетов. Часть 1.
Задача: затюнить размеры сокетов у Nginx, чтобы без потерь переживать всплески трафика.
Уточним размер буфера чтения:
# ss -ntlmO | grep ':80 '
LISTEN 0 511 0.0.0.0:80 0.0.0.0:*…
Задача: затюнить размеры сокетов у Nginx, чтобы без потерь переживать всплески трафика.
Уточним размер буфера чтения:
# ss -ntlmO | grep ':80 '
LISTEN 0 511 0.0.0.0:80 0.0.0.0:*…
👍23
Готовлюсь к внутреннему митапу с докладом о потерях сетевого трафика: как их диагностировать и устранять.
В основе GIF-анимация, иллюстрирующая путь и остановки входящего сетевого пакета в ядре Linux.
Очереди в ядре Linux
* RX queue. Первая остановка: очередь сетевой карты (см.
* QDisc. Приоритизация, модификация и многое другое возможны с помощью дисциплины очередей. Calico, Cilium и подобные ребята перехватывает пакеты именно здесь (eBPF)
* Input Packet Queue. Очередь перед стеком протоколов.
📍Для новых соединений
* SYN queue. Очередь, где SYN-сегменты дожидаются ACK;
* Accept queue. Приложение через
📍Для уже установленных соединений
* Out Of Order queue. При нарушении очередности (sequence number больше ожидаемого), пакет помещается в нее, до восстановления правильного порядка;
* Recv queue. TCP-буфер сокета, из него приложение читает данные системным вызовом
———
Подробнее я описывал весь процесс в двух частях: один, два.
P.S. Кстати, поддержать канал теперь можно на Бусти или просто донатом!
#network #tcp #kernel
В основе GIF-анимация, иллюстрирующая путь и остановки входящего сетевого пакета в ядре Linux.
Очереди в ядре Linux
* RX queue. Первая остановка: очередь сетевой карты (см.
ethtool -l eth0
)* QDisc. Приоритизация, модификация и многое другое возможны с помощью дисциплины очередей. Calico, Cilium и подобные ребята перехватывает пакеты именно здесь (eBPF)
* Input Packet Queue. Очередь перед стеком протоколов.
📍Для новых соединений
* SYN queue. Очередь, где SYN-сегменты дожидаются ACK;
* Accept queue. Приложение через
accept()
подтверждает, что соединение установлено - зеленый свет для обмена данными.📍Для уже установленных соединений
* Out Of Order queue. При нарушении очередности (sequence number больше ожидаемого), пакет помещается в нее, до восстановления правильного порядка;
* Recv queue. TCP-буфер сокета, из него приложение читает данные системным вызовом
read()
.———
Подробнее я описывал весь процесс в двух частях: один, два.
P.S. Кстати, поддержать канал теперь можно на Бусти или просто донатом!
#network #tcp #kernel
🔥18👍9
На днях node-exporter зарелизил версию 1.9.0, где среди изменений мне бросилось в глаза:
В обсуждении к MR был комментарий от @SuperQ:
Что за рекомендации такие и кого они аффектят?
—————
Для начала чуть теории 📖
Обработчики прерываний бывает двух типов: аппаратные (Hard IRQ) и программные (SoftIRQ).
Hard IRQ вызываются устройствами (диск, клавиатура, сеть и т. д.) и немедленно обрабатываются процессором. Они могут прервать любой код, поэтому их обработку делают минимальной, чтобы быстрее освободить CPU для других задач.
SoftIRQ обрабатывает прерывания асинхронно в контексте ядра, не блокируя CPU. Поэтому ему отдают наиболее длительные этапы обработки.
В CPU Usage нагрузка от Hard IRQ отображается в
—————
Теперь вернемся к изначальному вопросу.
Оказывается
В redhat-like дистрибутивах эта опция включена, тогда как в debian и им подобным её по умолчанию отключают!
А дальше самое интересное.
Если
1. если прерывание произошло в user mode, то время его обработки будет учтено как
2. если прерывание произошло во время выполнения процесса в system mode, его обработка будет засчитана в
3. если прерывание произошло во время выполнения фоновых задач ядра (kworker, ksoftirqd), то его обработка будет засчитана в
В итоге точность анализа загрузки CPU снижается, что может вводить в заблуждение. Говорят, что погрешность может достигать 5–7%! А это хорошо бы проверить😉
Судя по документации ядра, опцию отключают из-за её небольшого влияния на производительность:
И это проверим:)
P.S. Подробнее, с примерами про подсчет irq читай в блоге Танел Подера.
#cpu #kernel
- [FEATURE] pressure: add IRQ PSI metrics [#3048]
В обсуждении к MR был комментарий от @SuperQ:
Nice, it's too bad `CONFIG_IRQ_TIME_ACCOUNTING` is recommend to be off so very few people will benefit from this by default.
Что за рекомендации такие и кого они аффектят?
—————
Для начала чуть теории 📖
Обработчики прерываний бывает двух типов: аппаратные (Hard IRQ) и программные (SoftIRQ).
Hard IRQ вызываются устройствами (диск, клавиатура, сеть и т. д.) и немедленно обрабатываются процессором. Они могут прервать любой код, поэтому их обработку делают минимальной, чтобы быстрее освободить CPU для других задач.
SoftIRQ обрабатывает прерывания асинхронно в контексте ядра, не блокируя CPU. Поэтому ему отдают наиболее длительные этапы обработки.
В CPU Usage нагрузка от Hard IRQ отображается в
%irq
, а от SoftIRQ в %softirq
.—————
Теперь вернемся к изначальному вопросу.
Оказывается
%irq
отображается только при включённой опции CONFIG_IRQ_TIME_ACCOUNTING
, иначе он всегда равен нулю. В redhat-like дистрибутивах эта опция включена, тогда как в debian и им подобным её по умолчанию отключают!
# mpstat 1
Linux 5.10.0-20-amd64 02/18/2025 _x86_64_ (8 CPU)
11:28:51 PM CPU %usr %nice %sys %iowait %irq %soft %steal %idle
11:28:52 PM all 40.15 0.00 1.38 0.00 0.00 0.63 0.00 57.84
11:28:53 PM all 28.81 0.00 1.78 0.25 0.00 0.51 0.13 68.53
11:28:54 PM all 35.29 0.00 2.25 0.00 0.00 0.25 0.00 62.20
11:28:55 PM all 17.68 0.00 1.14 0.00 0.00 0.38 0.25 80.56
11:28:56 PM all 16.31 0.00 1.99 0.00 0.00 0.25 0.25 81.20
# mpstat -I ALL 1
11:32:53 PM CPU intr/s
11:32:54 PM all 18466.00
11:32:55 PM all 11983.00
11:32:56 PM all 14019.00
%irq
нулевой, хотя кол-во прерываний десятки тысяч.А дальше самое интересное.
Если
CONFIG_IRQ_TIME_ACCOUNTING
отключена, нагрузка от Hard IRQ никуда не исчезнет (кэп🙂), а учитывается как:1. если прерывание произошло в user mode, то время его обработки будет учтено как
%user
того процесса, который выполнялся до прерывания.2. если прерывание произошло во время выполнения процесса в system mode, его обработка будет засчитана в
%sys
этого процесса.3. если прерывание произошло во время выполнения фоновых задач ядра (kworker, ksoftirqd), то его обработка будет засчитана в
%sys
системыВ итоге точность анализа загрузки CPU снижается, что может вводить в заблуждение. Говорят, что погрешность может достигать 5–7%! А это хорошо бы проверить😉
Судя по документации ядра, опцию отключают из-за её небольшого влияния на производительность:
Select this option to enable fine granularity task irq time
accounting. This is done by reading a timestamp on each
transitions between softirq and hardirq state, so there can be a
small performance impact.
If in doubt, say N here.
И это проверим:)
P.S. Подробнее, с примерами про подсчет irq читай в блоге Танел Подера.
#cpu #kernel
GitHub
Release 1.9.0 / 2025-02-17 · prometheus/node_exporter
[CHANGE] meminfo: Convert linux implementation to use procfs lib #3049
[CHANGE] Update logging to use Go log/slog #3097
[FEATURE] filesystem: Add node_filesystem_mount_info metric #2970
[FEATURE] b...
[CHANGE] Update logging to use Go log/slog #3097
[FEATURE] filesystem: Add node_filesystem_mount_info metric #2970
[FEATURE] b...
👍16🔥12
Из серии "Смотрите что нашел!"
Low latency tuning guide - сборник техник по оптимизации системы для минимизации задержек.
Внутри как привычные подходы вроде изоляции ядер и отключения гиперпоточности, так и совсем для меня новые:
- сокращение прерываний таймера планировщика через
- закрепление страниц в RAM с помощью
Особую ценность добавляет обилие ссылок для более глубокого погружения в предмет.
Упражнение: задавать себе вопросы из разряда: "Для low latency советуют SCHED_RR и SCHED_FIFO, а что если важнее пропускная способность? Как бы я изменил подход? Почему?"
#kernel #tuning #low_latency
Low latency tuning guide - сборник техник по оптимизации системы для минимизации задержек.
Внутри как привычные подходы вроде изоляции ядер и отключения гиперпоточности, так и совсем для меня новые:
- сокращение прерываний таймера планировщика через
nohz_full
, что будет снижать накладные расходы на context swithing.- закрепление страниц в RAM с помощью
mlockall(MCL_CURRENT | MCL_FUTURE)
, чтобы избежать их выгрузки на диск.Особую ценность добавляет обилие ссылок для более глубокого погружения в предмет.
Упражнение: задавать себе вопросы из разряда: "Для low latency советуют SCHED_RR и SCHED_FIFO, а что если важнее пропускная способность? Как бы я изменил подход? Почему?"
#kernel #tuning #low_latency
rigtorp.se
Low latency tuning guide
This guide describes how to tune your AMD64/x86_64 hardware and Linux system for running real-time or low latency workloads.
🔥22👍8👎1