The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
Раздел полезных советов: Часто используемые параметры sysctl, касающиеся настройки сети в Linux, auto_tips, 14-Сен-23, 15:49  [смотреть все]
++ От переводчика (@zersh).

Это адаптированный перевод работы https://github.com/leandromoreira/linux-network-performance-...
Для понимания некоторых моментов использовалась [[https://habr.com/ru/company/mailru/blog/314168/ статья]]. Принимаются любые замечания и предложения. Спасибо zizmo и @servers(Artem) - за помощь и конструктивную критику)
Лицензия: BSD-3

++ Введение

Иногда люди пытаются найти некие универсальные значения параметров sysctl (https://www.kernel.org/doc/Documentation/networking/ip-sysct... применение которых во всех случаях позволит добиться и высокой пропускной способности, и низкой задержки при обработке сетевых запросов. К сожалению, это не возможно, хотя стоит отметить, что современные версии ядер по умолчанию уже неплохо настроены. Важно понимать, что изменение заданных по умолчанию настроек может ухудшить производительность (https://medium.com/@duhroach/the-bandwidth-delay-proble....

Это краткое руководство, в котором приведены часто используемые параметры  sysctl, касающиеся настройки сети Linux, вдохновлённый иллюстрированным руководством по сетевому стеку Linux (https://blog.packagecloud.io/eng/2016/10/11/monitoring-tunin... и многими постами Marek Majkowski (https://blog.cloudflare.com/how-to-achieve-low-latency/).


++ Обзор сетевых очередей Linux


[[IMG /opennews/pics_base/CFD0C5CECEC5D4_1694351731.png]]


++ Связь переменных sysctl с различными стадиями обработки сетевых потоков в Linux


++ Входящие пакеты (Ingress)

1. Пакеты прибывают в NIC (сетевой адаптер)

2. NIC проверяет `MAC` (если не включён promiscuous-режим) и `FCS (Frame check sequence)` и принимает решение отбросить пакет или продолжить обработку.

3. NIC используя DMA (https://en.wikipedia.org/wiki/Direct_memory_access), помещает пакеты в RAM регионе, ранее подготовленном (mapped) драйвером.

4. NIC ставит ссылки в очередь на пакеты при получении ring buffer (https://en.wikipedia.org/wiki/Circular_buffer) очередь `rx` до истечения таймаута  `rx-usecs` или `rx-frames`

5. NIC Генерируется аппаратное прерывание, чтобы система узнала о появлении пакета в памяти `hard IRQ`

6. CPU запустит `IRQ handler`, который запускает код драйвера

7. Драйвер вызовет  `планировщик NAPI`, очистит `hard IRQ`

8. Драйвер будит подсистему NAPI с помощью `soft IRQ (NET_RX_SOFTIRQ)`

9. NAPI опрашивает данные, полученные из кольцевого буфера до тех пор пока не истечёт таймаут `netdev_budget_usecs`, или `netdev_budget` и `dev_weight` пакета

10. Linux также выделяет память для `sk_buff`

11. Linux заполняет метаданные: протокол, интерфейс, устанавливает MAC-адрес (setmacheader), удаляет ethernet

12. Linux передаёт skb (данные) в стэк ядра (`netif_receive_skb`)

13. Установит сетевые заголовки, клонирует `skb` ловушкам (вроде tcpdump) и передаст на вход

14. Пакеты обрабатываются в qdisc (Queueing discipline) размера `netdev_max_backlog`, алгоритм которого определяется `default_qdisc`

15. Вызывает `ip_rcv` и пакеты обрабатываются в IP

16. Вызывает netfilter (`PREROUTING`)

17. Проверяет маршрутизацию, кому предназначен пакет: переслать (forwarding) или локально (local)

18. Если локально, вызывает netfilter (`LOCAL_IN`)

19. Это вызовет протокол L4 (для примера `tcp_v4_rcv`)

20. Находит нужный сокет

21. Переходит на конечный автомат tcp (finite state machine).

22. Поставит пакет в входящий буфер, размер которого определяется правилами `tcp_rmem`. Если `tcp_moderate_rcvbuf` включён, ядро будет автоматически тюнить  буфер приёма (receive)

23. Ядро сигнализирует приложению, что доступны данные (epoll или другая  polling-система)

24. Приложение просыпается и читает данные

++ Исходящие пакеты (Egress)

1. Приложение отправляет сообщение (`sendmsg` или другие)

2. TCP-стек выделяет память для skb_buff

3. Помещает skb в сокет буфера, размером `tcp_wmem`

4. Создаст TCP заголовки (источник и порт назначения, контрольная сумма)

5. Вызывает обработчик L3 (в данном случае `ipv4` в `tcp_write_xmit` и
`tcp_transmit_skb`)

6. L3 (`ip_queue_xmit`)  построит заголовок IP и вызовет netfilter (`LOCAL_OUT`)

7. Вызывает действие выходного маршрута (Calls output route action)

8. Вызывает netfilter (`POST_ROUTING`)

9. Фрагментирует пакет (`ip_output`)

10. Вызывает функции отправки L2 (`dev_queue_xmit`)

11. Подаёт на выход (QDisc) очередь длинной `txqueuelen` с алгоритмом `default_qdisc`

12. Код драйвера помещает пакеты в `ring buffer tx`

13. Драйвер генерирует `soft IRQ (NET_TX_SOFTIRQ)` после `tx-usecs` таймаута или `tx-frames`

14. Реактивирует аппаратное прерывание (IRQ) в NIC

15. Драйвер отражает (map) все пакеты (для отправки) в некоторую область DMA

16. NIC получит пакеты (через DMA) из RAM для передачи

17. После передачи NIC поднимет сигнал `hard IRQ` о его завершении

18. Драйвер обработает это прерывание IRQ (выключает)

19. И планирует (`soft IRQ`) NAPI poll system

20. NAPI будет обрабатывать сигналы приёма пакетов и освобождать ОЗУ


Для отслеживания обработки событий, связанных с выполнением сетевой операции, можно использовать команду:

   perf trace --no-syscalls --event 'net:*' ping globo.com -c1 > /dev/null


++ Что, Почему и Как - сеть и  sysctl параметры

++ Кольцевой буфер (Ring Buffer) - rx, tx

Что: драйвер очереди приёма/отправки одной или нескольких очередей с фиксированным размером, обычно реализованный как FIFO, находится в ОЗУ

Почему: буфер для плавного прима соединений без их отбрасывания. Возможно, вам понадобится увеличить эти очереди, когда вы увидите сбросы (drops) или переполнения, то есть, если поступает больше пакетов, чем ядро может обработать. Побочным эффектом от увеличения буфера может стать увеличение задержки.

Как:

Команда проверки:

   ethtool -g ethX

Как изменить:

   ethtool -G ethX rx значение tx значение

Как мониторить:

   ethtool -S ethX | grep -e "err" -e "drop" -e "over" -e "miss" -e "timeout" -e "reset" -e "restar" -e "collis" -e "over" | grep -v "\: 0"

++ Слияние прерываний (Interrupt Coalescence - IC) - rx-usecs, tx-usecs, rx-frames, tx-frames (аппаратные IRQ)

Что: количество микросекунд / кадров, ожидающих перед поднятием hard IRQ, с точки зрения сетевого адаптера это будет пакеты данных DMA до этого тайм-аута / количества кадров

Почему: сокращение использования CPUs, аппаратных IRQ, может увеличить пропускную способность за счет задержки.

Как:

Команда проверки:

   ethtool -c ethX

Как изменить:

   ethtool -C ethX rx-usecs value tx-usecs value

Как мониторить:

   cat /proc/interrupts
  

++ Объединение прерываний (soft IRQ) и   управления сетевыми очередями  QDisc входящих пакетов (ingress).


Что: максимальное число микросекунд в одном NAPI (https://en.wikipedia.org/wiki/New_API) цикле опроса. Опрос завершится когда, либо `netdev_budget_usecs` истечёт по временя цикла опроса или количество обработанных пакетов достигнет `netdev_budget`.

Почему: вместо того чтобы обрабатывать кучу softIRQ, драйвер сохраняет данные в пуле (polling data); следите за состояниями `dropped` (число пакетов,  отброшенных из-за того, что `netdev_max_backlog` был превышен) и  `squeezed` (число раз когда ksoftirq превысил `netdev_budget`).


Как:

Команда проверки:

   sysctl net.core.netdev_budget_usecs

Как изменить:

   sysctl -w net.core.netdev_budget_usecs value

Как мониторить:

   cat /proc/net/softnet_stat

или [[https://raw.githubusercontent.com/majek/dump/master/how-to-r... скриптом]].


Что: `netdev_budget` максимальное количество пакетов, взятых со всех интерфейсов за один цикл опроса (NAPI poll). В одном цикле опроса интерфейсы, которые зарегистрированы для опроса, зондируются круговым способом. Кроме того, цикл опроса не может превышать `netdev_budget_usecs` микросекунд, даже если `netdev_budget` не был исчерпан.


Как:

Команда проверки:

   sysctl net.core.netdev_budget

Как изменить:

   sysctl -w net.core.netdev_budget value

Как мониторить:

cat /proc/net/softnet_stat

или [[https://raw.githubusercontent.com/majek/dump/master/how-to-r... скриптом]].


Что: `dev_weight` максимальное количество пакетов, которое ядро может обработать при прерывании NAPI, это переменная для каждого процессора. Для драйверов, которые поддерживают LRO или GRO_HW, аппаратно агрегированный пакет считается в этом пакете одним.

Как:

Команда проверки:

   sysctl net.core.dev_weight

Как изменить:

  sysctl -w net.core.dev_weight value

Как мониторить:

   cat /proc/net/softnet_stat

или [[https://raw.githubusercontent.com/majek/dump/master/how-to-r... скриптом]].


Что: `netdev_max_backlog` максимальное количество пакетов, находящихся в очереди на стороне INPUT (входной qdisc_), когда интерфейс получает пакеты быстрее, чем ядро может их обработать.

Как:

Команда проверки:

   sysctl net.core.netdev_max_backlog

Как изменить:

   sysctl -w net.core.netdev_max_backlog value

Как мониторить:

   cat /proc/net/softnet_stat

или [[https://raw.githubusercontent.com/majek/dump/master/how-to-r... скриптом]].

++ Исходящие QDisc - txqueuelen (длина очереди tx) и default_qdisc


Что: `txqueuelen` максимальное количество пакетов, поставленных в очередь на стороне вывода.

Почему: buffer/queue появление разрывов соединений, а также примением контроля трафика [[http://tldp.org/HOWTO/Traffic-Control-HOWTO/intro.html tc]] (traffic control).

Как:

Команда проверки:

   ifconfig ethX

Как изменить:

   ifconfig ethX txqueuelen value

Как мониторить:

   ip -s link


Что: `default_qdisc` дисциплина очереди по умолчанию, используемая для сетевых устройств.

Почему: Каждое приложение имеет разную нагрузку и требует контроля трафика, оно также используется для борьбы с  излишней сетевой буферизацией [[https://www.bufferbloat.net/projects/codel/wiki/ bufferbloat]].

Как:

Команда проверки:

   sysctl net.core.default_qdisc


Как изменить:

   sysctl -w net.core.default_qdisc value

Как мониторить:

   tc -s qdisc ls dev ethX


++ Буферы/очереди чтения и записи (TCP Read and Write Buffers/Queues)

Что: `tcp_rmem` - min (минимальный размер доступный при создании сокета), default (начальный размер), max (максимальный размер) - максимальный размер приёмного буфера TCP.

Почему: буфер/очередь приложения для записи/отправки данных. Понять последствия может помочь статья https://blog.cloudflare.com/the-story-of-one-latency-spike/

Как:

Команда проверки:

   sysctl net.ipv4.tcp_rmem

Как изменить:

   sysctl -w net.ipv4.tcp_rmem="min default max"

когда меняете значение по умолчанию, не забудьте перезагрузить приложения в пользовательском окружении (т.е. ваш веб-сервер, nginx, и т.п.)

Как мониторить:

   cat /proc/net/sockstat


Что: `tcp_wmem` - min (минимальный размер доступный при создании сокета), default (начальный размер), max (максимальный размер) - размер буфера отправки, используемого сокетами TCP.

Как:

Команда проверки:

   sysctl net.ipv4.tcp_wmem


Как изменить:

   sysctl -w net.ipv4.tcp_wmem="min default max"

когда меняете значение по умолчанию, не забудьте перезагрузить приложения в пользовательском окружении (т.е. ваш веб-сервер, nginx, и т.п.)

Как мониторить:

   cat /proc/net/sockstat

Что: `tcp_moderate_rcvbuf` - если установлено, TCP выполняет автонастройку приёмного буфера, пытаясь автоматически определить размер буфера.

Как:

Команда проверки:

  sysctl net.ipv4.tcp_moderate_rcvbuf

Как изменить:

   sysctl -w net.ipv4.tcp_moderate_rcvbuf value

Как мониторить:

   cat /proc/net/sockstat


++ TCP FSM и алгоритм перегрузки (Honorable mentions - TCP FSM and congestion algorithm)

** `sysctl net.core.somaxconn` - обеспечивает верхний предел значения параметра backlog, передаваемого в функцию `listen()`
(https://eklitzke.org/how-tcp-sockets-work), известный пользователям как `SOMAXCONN`. Если вы меняете это значение, вы также должны изменить в своём приложении совместимые значения (т.е. [[http://nginx.org/en/docs/http/ngx_http_core_module.html#listen nginx backlog]]).

** `cat /proc/sys/net/ipv4/tcp_fin_timeout` - указывает количество секунд ожидания окончательного пакета FIN, прежде чем сокет будет принудительно закрыт. Это строго является нарушением спецификации TCP, но требуется для предотвращения атак типа «отказ в обслуживании».

** `cat /proc/sys/net/ipv4/tcp_available_congestion_control` - показывает доступные варианты управления перегрузкой, которые зарегистрированы.

** `cat /proc/sys/net/ipv4/tcp_congestion_control` - устанавливает алгоритм управления перегрузкой, используемое для новых соединений.

** `cat /proc/sys/net/ipv4/tcp_max_syn_backlog` - задаёт максимальное число запросов подключения в очереди, которые еще не получили подтверждения от подключающегося клиента; если это число будет превышено, ядро начнёт отбрасывать запросы.

** `cat /proc/sys/net/ipv4/tcp_syncookies` - включён/выключен [syn cookies](https://en.wikipedia.org/wiki/SYN_cookies), полезен для защиты от syn flood атак (https://www.cloudflare.com/learning/ddos/syn-flood-ddos-atta....

** `cat /proc/sys/net/ipv4/tcp_slow_start_after_idle` - включён/выключен медленный старт tcp.


Как мониторить:

общая сводка

   netstat -atn | awk '/tcp/ {print $6}' | sort | uniq -c


счётчики по определённому состоянию: `established`, `syn-sent`, `syn-recv`, `fin-wait-1`, `fin-wait-2`, `time-wait`, `closed`, `close-wait`, `last-ack`, `listening`, `closing`:

   ss -neopt state time-wait | wc -l`


tcp статистика

   netstat -st

более читаемая tcp статистика

   nstat -a


обобщённая статистика сокетов

   cat /proc/net/sockstat

детальная статистика, описание полей смотрите: https://www.kernel.org/doc/Documentation/networking/proc_net...

   cat /proc/net/tcp

`ListenOverflows` и `ListenDrops` - важные поля для наблюдения

   cat /proc/net/netstat

читаемый вариант /proc/net/netstat (https://sa-chernomor.livejournal.com/9858.html)


   cat /proc/net/netstat | awk '(f==0) { i=1; while ( i<=NF) {n[i] = $i; i++ }; f=1; next} \
   (f==1){ i=2; while ( i<=NF){ printf "%s = %d\n", n[i], $i; i++}; f=0} ' | grep -v "= 0


[[IMG /opennews/pics_base/CFD0C5CECEC5D4_1694352027.png]]

Источник: https://commons.wikimedia.or/wiki/File:Tcp_state_diagram_fix...


++ Сетевые утилиты для тестирования и мониторинга

** iperf3 (https://iperf.fr/) - пропускная способность сети
** vegeta (https://github.com/tsenart/vegeta) - нагрузочное тестирование HTTP
** netdata (https://github.com/firehol/netdata) - система распределённого мониторинга производительности и работоспособности в реальном времени

++ Рекомендации

** https://www.kernel.org/doc/Documentation/sysctl/net.txt
** https://www.kernel.org/doc/Documentation/networking/ip-sysct...
** https://www.kernel.org/doc/Documentation/networking/scaling.txt
** https://www.kernel.org/doc/Documentation/networking/proc_net...
** https://www.kernel.org/doc/Documentation/networking/multique...
** http://man7.org/linux/man-pages/man7/tcp.7.html
** http://man7.org/linux/man-pages/man8/tc.8.html
** http://www.ece.virginia.edu/cheetah/documents/papers/TCPlinu...
** https://netdevconf.org/1.2/papers/bbr-netdev-1.2.new.new.pdf
** https://blog.cloudflare.com/how-to-receive-a-million-packets/
** https://blog.cloudflare.com/how-to-achieve-low-latency/
** https://blog.packagecloud.io/eng/2016/06/22/monitoring-tunin.../
** https://www.youtube.com/watch?v=6Fl1rsxk4JQ
** https://oxnz.github.io/2016/05/03/performance-tuning-networking/
** https://www.intel.com/content/dam/www/public/us/en/documents...
** https://access.redhat.com/sites/default/files/attachments/20...
** https://medium.com/@matteocroce/linux-and-freebsd-netwo...
** https://blogs.technet.microsoft.com/networking/2009/08/12/wh.../
** https://www.intel.com/content/dam/www/public/us/en/documents...
** http://syuu.dokukino.com/2013/05/linux-kernel-features-for-h...
** https://www.bufferbloat.net/projects/codel/wiki/Best_practic.../
** https://software.intel.com/en-us/articles/setting-up-intel-e...
** https://courses.engr.illinois.edu/cs423/sp2014/Lectures/Linu...
** https://www.coverfire.com/articles/queueing-in-the-linux-net.../
** http://vger.kernel.org/~davem/skb.html
** https://www.missoulapubliclibrary.org/ftp/LinuxJournal/LJ13-...
** https://opensourceforu.com/2016/10/network-performance-monit.../
** https://www.yumpu.com/en/document/view/55400902/an-adventure...
** https://lwn.net/Articles/616241/
** https://medium.com/@duhroach/tools-to-profile-networkin...
** https://www.lmax.com/blog/staff-blogs/2016/05/06/navigating-.../
** https://es.net/host-tuning/100g-tuning/
** http://tcpipguide.com/free/t_TCPOperationalOverviewandtheTCP...
** http://veithen.github.io/2014/01/01/how-tcp-backlog-works-in...
** https://people.cs.clemson.edu/~westall/853/tcpperf.pdf
** http://tldp.org/HOWTO/Traffic-Control-HOWTO/classless-qdiscs...
** https://es.net/assets/Papers-and-Publications/100G-Tuning-Te...
** https://www.kernel.org/doc/ols/2009/ols2009-pages-169-184.pdf
** https://devcentral.f5.com/articles/the-send-buffer-in-depth-...
** http://packetbomb.com/understanding-throughput-and-tcp-windows/
** https://www.speedguide.net/bdp.php
** https://www.switch.ch/network/tools/tcp_throughput/
** https://www.ibm.com/support/knowledgecenter/en/SSQPD3_2.6.0/...
** https://blog.tsunanet.net/2011/03/out-of-socket-memory.html
** https://unix.stackexchange.com/questions/12985/how-to-check-...
** https://serverfault.com/questions/498245/how-to-reduce-numbe...
** https://unix.stackexchange.com/questions/419518/how-to-tell-...
** https://eklitzke.org/how-tcp-sockets-work
** https://www.linux.com/learn/intro-to-linux/2017/7/introducti...
** https://staaldraad.github.io/2017/12/20/netstat-without-netstat/
** https://loicpefferkorn.net/2016/03/linux-network-metrics-why.../
** http://assimilationsystems.com/2015/12/29/bufferbloat-networ.../


URL: https://github.com/leandromoreira/linux-network-performance-...
Обсуждается: http://www.opennet.me/tips/info/3228.shtml




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру