Linux. Настройка сети

    Настройка параметров сети, предотвращает потерю данных и настраивает сетевой стэк на максимальную полосу пропускания.

    Системный буфер

    Для передачи/приема данных по протоколу UDP нужно настроить буфер операционной системы.

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

    Параметры размера буфера настраиваются в файле /etc/sysctl.conf
    Рекомендуется использовать следующие значения для сетевых адаптеров 1G:

    net.core.rmem_max = 16777216
    net.core.wmem_max = 16777216
    net.ipv4.udp_mem = 8388608 12582912 16777216
    net.ipv4.tcp_rmem = 4096 87380 8388608
    net.ipv4.tcp_wmem = 4096 65536 8388608
    net.core.wmem_default = 16777216
    net.core.rmem_default = 16777216
    net.ipv4.tcp_tw_reuse = 1

    Для 10G сетевых адаптеров:

    net.core.rmem_max = 67108864
    net.core.wmem_max = 67108864
    net.ipv4.udp_mem = 8388608 16777216 33554432
    net.ipv4.tcp_rmem = 4096 87380 33554432
    net.ipv4.tcp_wmem = 4096 65536 33554432
    net.core.wmem_default = 33554432
    net.core.rmem_default = 33554432
    net.ipv4.tcp_congestion_control=htcp
    net.ipv4.tcp_tw_reuse = 1

    Для 40G сетевых адаптеров:

    net.core.rmem_max = 134217728
    net.core.wmem_max = 134217728
    net.ipv4.udp_mem = 8388608 33554432 67108864
    net.ipv4.tcp_rmem = 4096 87380 67108864
    net.ipv4.tcp_wmem = 4096 65536 67108864
    net.core.wmem_default = 67108864
    net.core.rmem_default = 67108864
    net.ipv4.tcp_congestion_control=htcp
    net.ipv4.tcp_tw_reuse = 1

    Чтобы применить изменения, перезагрузите систему или выполните команду:

    sysctl -p

    Вы можете проверить текущие значения с помощью следующей команды:

    sysctl net.core.rmem_default net.core.rmem_max net.core.wmem_default net.core.wmem_max net.ipv4.udp_mem net.ipv4.tcp_wmem

    Размер буфера сетевой карты

    Для высоконагруженых серверов необходимо настроить буфер сетевой карты. Это позволит избежать потерь в системном буфере.

    Как настроить:
    [root@astra ~]# ethtool -g eth1
    Ring parameters for eth1:
    Pre-set maximums:
    RX:     4096
    RX Mini:    0
    RX Jumbo:   0
    TX:     4096
    Current hardware settings:
    RX:     4096
    RX Mini:    0
    RX Jumbo:   0
    TX:     256

    Здесь мы видим, что rx-буфер увеличен до максимума. Обычно найти верное значение довольно сложно. Наиболее оптимальным является некоторое «среднее» значение. С высокочастотным и многоядерным процессором (> 3GHz) вы можете получить хорошие результаты с максимальным размером буфера.
    Пример команды для увеличения буфера:

    ethtool -G eth1 rx 2048

    RP filter

    rp_filter - является технологией обеспечивающей защиту и безопасность сервера при использовании мультикаст - рассылок.\
    Если ваш сервер имеет несколько сетевых интерфейсов, рекомендуем прописать маршруты для мультикаст-групп. Если это не возможно, вы должны изменить настройки rp_filter.

    Как настроить

    Добавьте в файл /etc/sysctl.conf следующую запись:

    net.ipv4.conf.eth0.rp_filter = 2

    Где eth0 - имя интерфейса.

    Чтобы применить изменения, перезапустите систему или выполните команду:

    sysctl -p

    Версия IGMP

    Многие операционные системы отправляют запрос на подписку к мультикаст-группе в формате igmp v3\
    Если сетевой коммутатор не может работать с этим протоколом, или протокол не сконфигурирован - попытка подписки на мультикаст группу будет неудачной. Протокол igmp v2 поддерживается большинством коммутаторов.

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

    Версия IGMP может быть настроена в файле /etc/sysctl.conf\
    Например, настройка IGMPv2 для интерфейса eth1:\
    net.ipv4.conf.eth1.force_igmp_version=2

    Чтобы применить изменения, перезапустите систему или выполните команду:

    sysctl -p

    Вы можете проверить версию IGMP с помощью tcpdump выполнив команду:

    tcpdump -i eth1 igmp

    Затем попробуйте подписаться на мультикаст. Например:

    astra --analyze udp://eth1@239.255.1.1:1234

    sysctl.conf

    Для высоконагруженных серверов рекомендуется добавить следующие записи в файл /etc/sysctl.conf

    Показать:
    fs.file-max = 818000
    fs.suid_dumpable = 0
    kernel.core_uses_pid = 1
    kernel.exec-shield = 1
    kernel.kptr_restrict = 1
    kernel.maps_protect = 1
    kernel.msgmax = 65535
    kernel.msgmnb = 65535
    kernel.pid_max = 65535
    kernel.randomize_va_space = 2
    kernel.shmall = 268435456
    kernel.shmmax = 268435456
    kernel.sysrq = 0
    net.core.default_qdisc = fq
    net.core.dev_weight = 64
    net.core.netdev_budget = 50000
    net.core.netdev_max_backlog = 100000
    net.core.optmem_max = 204800
    net.core.rmem_default = 67108864
    net.core.somaxconn = 65535
    net.ipv4.conf.all.accept_redirects = 0
    net.ipv4.conf.all.accept_source_route = 0
    net.ipv4.conf.all.arp_ignore = 1
    net.ipv4.conf.all.bootp_relay = 0
    net.ipv4.conf.all.force_igmp_version=2
    net.ipv4.conf.all.forwarding = 0
    net.ipv4.conf.all.log_martians = 0
    net.ipv4.conf.all.proxy_arp = 0
    net.ipv4.conf.all.secure_redirects = 0
    net.ipv4.conf.all.send_redirects = 0
    net.ipv4.conf.default.accept_redirects = 0
    net.ipv4.conf.default.accept_source_route = 0
    net.ipv4.conf.default.forwarding = 0
    net.ipv4.conf.default.log_martians = 0
    net.ipv4.conf.default.secure_redirects = 0
    net.ipv4.conf.default.send_redirects = 0
    net.ipv4.conf.lo.log_martians = 0
    net.ipv4.icmp_echo_ignore_all = 0
    net.ipv4.icmp_echo_ignore_broadcasts = 1
    net.ipv4.icmp_ignore_bogus_error_responses = 1
    net.ipv4.ip_forward = 0
    net.ipv4.ipfrag_high_thresh = 512000
    net.ipv4.ipfrag_low_thresh = 446464
    net.ipv4.ip_local_port_range = 16384 65535
    net.ipv4.neigh.default.gc_interval = 30
    net.ipv4.neigh.default.gc_thresh1 = 32
    net.ipv4.neigh.default.gc_thresh2 = 1024
    net.ipv4.neigh.default.gc_thresh3 = 2048
    net.ipv4.neigh.default.proxy_qlen = 96
    net.ipv4.neigh.default.unres_qlen = 6
    net.ipv4.netfilter.ip_conntrack_buckets = 65536
    net.ipv4.netfilter.ip_conntrack_generic_timeout = 60
    net.ipv4.netfilter.ip_conntrack_icmp_timeout = 10
    net.ipv4.netfilter.ip_conntrack_tcp_timeout_close = 10
    net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 20
    net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 900
    net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait = 30
    net.ipv4.netfilter.ip_conntrack_tcp_timeout_last_ack = 30
    net.ipv4.netfilter.ip_conntrack_tcp_timeout_syn_recv = 30
    net.ipv4.netfilter.ip_conntrack_tcp_timeout_syn_sent = 15
    net.ipv4.netfilter.ip_conntrack_tcp_timeout_syn_sent2 = 15
    net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 30
    net.ipv4.netfilter.ip_conntrack_udp_timeout = 30
    net.ipv4.netfilter.ip_conntrack_udp_timeout_stream = 45
    net.ipv4.route.flush = 1
    net.ipv4.tcp_congestion_control=htcp
    net.ipv4.tcp_ecn = 1
    net.ipv4.tcp_fastopen = 1
    net.ipv4.tcp_fin_timeout = 7
    net.ipv4.tcp_keepalive_intvl = 15
    net.ipv4.tcp_keepalive_probes = 5
    net.ipv4.tcp_keepalive_time = 300
    net.ipv4.tcp_max_orphans = 65536
    net.ipv4.tcp_max_syn_backlog = 4096
    net.ipv4.tcp_max_tw_buckets = 1440000
    net.ipv4.tcp_moderate_rcvbuf = 1
    net.ipv4.tcp_mtu_probing = 1
    net.ipv4.tcp_no_metrics_save = 1
    net.ipv4.tcp_orphan_retries = 1
    net.ipv4.tcp_reordering = 3
    net.ipv4.tcp_retries1 = 3
    net.ipv4.tcp_retries2 = 15
    net.ipv4.tcp_rfc1337 = 1
    net.ipv4.tcp_sack = 1
    net.ipv4.tcp_slow_start_after_idle = 0
    net.ipv4.tcp_synack_retries = 2
    net.ipv4.tcp_syncookies = 1
    net.ipv4.tcp_syn_retries = 2
    net.ipv4.tcp_timestamps = 1
    net.ipv4.tcp_tw_recycle = 0
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_window_scaling = 1
    net.ipv6.conf.all.accept_ra=0
    net.ipv6.conf.all.accept_redirects = 0
    net.ipv6.conf.all.accept_source_route = 0
    net.ipv6.conf.all.autoconf=0
    net.ipv6.conf.all.forwarding = 0
    net.ipv6.conf.default.accept_ra=0
    net.ipv6.conf.default.accept_redirects = 0
    net.ipv6.conf.default.accept_source_route = 0
    net.ipv6.conf.default.autoconf=0
    net.ipv6.conf.default.forwarding = 0
    net.ipv6.route.flush = 1
    net.netfilter.nf_conntrack_max = 1048576
    net.nf_conntrack_max = 1048576
    net.unix.max_dgram_qlen = 50
    vm.dirty_background_bytes = 67108864
    vm.dirty_background_ratio = 5
    vm.dirty_bytes = 134217728
    vm.dirty_ratio = 30
    vm.min_free_kbytes = 65535
    vm.mmap_min_addr = 4096
    vm.nr_hugepages = 1024
    vm.overcommit_memory = 0
    vm.overcommit_ratio = 50
    vm.swappiness = 1
    vm.vfs_cache_pressure = 50

    Чтобы применить изменения, перезагрузите систему или выполните команду:

    sysctl -p
    Как узнать информацию о потерях

    Ключевые слова: missed, dropped, fifo, error, rx.

    ip -s -s link show eth1

    Нужно проверить ошибки RX. Некоторые сетевые карты предоставляют более подробную информацию о потерях:

    ethtool -S eth1

    Потери могут быть не только на сетевых картах вашего сервера. Они также могут находиться на порту сетевого оборудования. Вы можете узнать, как это увидеть из документации производителя сетевого оборудования.

    Настройка и диагностика сетевой подсистемы с помощью netutils

    Данный набор утилит позволяет диагностировать сетевые потери, настраивать сетевую подсистему и проводить некоторую другую диагностику.

    Читать далее

    Установка

    yum install python3
    pip3 install netutils-linux

    network-top

    Image

    Эта утилита нужна для оценки применённых настроек и отображает равномерность распределения нагрузки (прерывания, softirqs, число пакетов в секунду на ядро процессора) на ресурсы сервера, всевозможные ошибки обработки пакетов. Значения, превышающие пороговые подсвечиваются.

    rss-ladder

    # rss-ladder eth1 0
    - distributing interrupts of eth1 (-TxRx) on socket 0:"
      - eth1: irq 67 eth1-TxRx-0 -> 0
      - eth1: irq 68 eth1-TxRx-1 -> 1
      - eth1: irq 69 eth1-TxRx-2 -> 2
      - eth1: irq 70 eth1-TxRx-3 -> 3
      - eth1: irq 71 eth1-TxRx-4 -> 8
      - eth1: irq 72 eth1-TxRx-5 -> 9
      - eth1: irq 73 eth1-TxRx-6 -> 10
      - eth1: irq 74 eth1-TxRx-7 -> 11

    Эта утилита распределяет прерывания сетевой карты на ядра выбранного физического процессора (по умолчанию на нулевой).

    server-info

    # server-info --rate
    cpu:
      BogoMIPS: 7
      CPU MHz: 7
      CPU(s): 1
      Core(s) per socket: 1
      L3 cache: 1
      Socket(s): 10
      Thread(s) per core: 10
      Vendor ID: 10
     disk:
       vda:
         size: 1
         type: 1
     memory:
       MemTotal: 1
       SwapTotal: 10
     net:
       eth1:
         buffers:
           cur: 5
           max: 10
         driver: 1
         queues: 1
     system:
       Hypervisor vendor: 1
       Virtualization type: 1

    Данная утилита позволяет сделать две вещи:

    server-info --show: посмотреть, что за оборудование установлено в сервере. В целом похоже на lshw, но с акцентом на интересующие нас параметры.

    server-info --rate: найти узкие места в аппаратном обеспечении сервера. В целом похоже на индекс производительности Windows, но с акцентом на интересующие нас параметры. Оценка производится по шкале от 1 до 10.

    Прочие утилиты

    rx-buffers-increase eth1 

    автоматически увеличивает буфер выбранной сетевой карты до оптимального значения.

    maximize-cpu-freq

    отключает плавающую частоту процессора.

    Примеры использования:

    Пример 1. Максимально простой.

    Дано:

    один процессор с 4 ядрами.
    одна 1 Гбит/сек сетевая карта (eth0) с 4 combined очередями
    входящий объём трафика 600 Мбит/сек, исходящего нет.
    все очереди висят на CPU0, суммарно на нём ?55000 прерываний и 350000 пакетов в секунду, из них около 200 пакетов/сек теряются сетевой картой. Остальные 3 ядра простаивают

    Решение:

    распределяем очереди между ядрами командой rss-ladder eth0
    увеличиваем ей буфер командой rx-buffers-increase eth0

    Пример 2. Чуть сложнее.

    Дано:

    два процессора с 8 ядрами
    две NUMA-ноды
    Две двухпортовые 10 Гбит/сек сетевые карты (eth0, eth1, eth2, eth3), у каждого порта 16 очередей, все привязаны к node0, входящий объём трафика: 3 Гбит/сек на каждую
    1 х 1 Гбит/сек сетевая карта, 4 очереди, привязана к node0, исходящий объём трафика: 100 Мбит/сек.

    Решение:

    1 Переткнуть одну из 10 Гбит/сек сетевых карт в другой PCI-слот, привязанный к NUMA node1.
    2 Уменьшить число combined очередей для 10гбитных портов до числа ядер одного физического процессора:

    for dev in eth0 eth1 eth2 eth3; do
      ethtool -L $dev combined 8
    done

    3 Распределить прерывания портов eth0, eth1 на ядра процессора, попадающие в NUMA node0, а портов eth2, eth3 на ядра процессора, попадающие в NUMA node1:

    rss-ladder eth0 0
    rss-ladder eth1 0
    rss-ladder eth2 1
    rss-ladder eth3 1

    4 Увеличить eth0, eth1, eth2, eth3 RX-буферы:

    for dev in eth0 eth1 eth2 eth3; do
      rx-buffers-increase $dev
    done

    Напоминание:

    В случае с сетевыми картами с одной очередью распределить нагрузку между ядрами можно с помощью RPS, но потери при копировании пакетов в память это не устранит.

    Распределение прерываний осуществляется на базе расчета хеш функции (остаток от деления) от совокупности таких данных: protocol, source and destination IP, and source and destination port. Технология называется: Receive-side scaling (RSS).