Рейтинг:3

Настройте Linux и Nignx для обработки 10 000 соединений на сервере 10 Гбит/с

флаг br

Я только что получил новый сервер 10 Гбит/с с 8 ядрами ЦП, 64 ГБ ОЗУ и 1 ТБ NVMe.

ОС Centos 7.9 ядро ​​3.10.0-1160.36.2.el7.x86_64 также пробовал kernel-ml 5.13
Селинукс отключен.
firewalld и irqbalance остановлены

Я сделал тест сети с помощью iperf3, скорость подтверждена около 9,5 Гбит/с.

Затем еще один тест с использованием 10 серверов по 1 Гбит/с для загрузки статического файла с сервера, сервер смог легко передать почти полные 10 Гбит/с на 10 серверов.

Итак, мы запускаем сервер в эксплуатацию, обслуживая клиентов, загружающих статические файлы с помощью Nginx. Он может обеспечивать стабильную производительность до достижения ~ 2000 подключений, после чего производительность начинает значительно падать. Я вижу, что трафик снижается, когда количество подключений увеличивается, поэтому обслуживание более 4000 подключений дает только 2 Гбит/с!

Изображение 1 показывает трафик и HTTP

Больше всего сбивает с толку то, что ЦП почти простаивает, ОЗУ свободно, использование ввода-вывода низкое благодаря NVMe и большому объему ОЗУ, но когда сервер имеет тысячи подключений, скорость становится медленнее на всех службах HTTP, FTP, SSH, даже обновление yum занимает так много времени. время ответить. Это похоже на перегрузку сети или пакетов или какое-то дросселирование в ядре или сетевом адаптере.

хтоп вершина загрузить

Я пробовал большинство советов по настройке

ifconfig eth0 txqueuelen 20000
ифконфиг eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
        эфир 00:16:3e:c2:f5:21 txqueuelen 20000 (Ethernet)
        Пакеты RX 26012067560 байт 1665662731749 (1,5 ТиБ)
        Ошибки RX 0 отброшено 0 переполнение 0 кадр 0
        Пакеты TX 30684216747 байт 79033055227212 (71,8 ТиБ)
        Ошибки передачи 0 отброшено 0 превышение пропускной способности 0 несущей 0 коллизий 0

tc -s -d qdisc показать dev eth0

qdisc mq 1: корень
    Отправлено 7733649086021 байт 1012203012 пкт (отброшено 0, превышено 0 запросов 169567)
    невыполненная работа 4107556b 2803p запросов 169567
qdisc pfifo_fast 0: родительские полосы 1:8 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
    Отправлено 2503685906926 байт 1714686297 pkt (отброшено 0, превышено 0 запросов 1447)
    отставание 4107556b 2803p запросов 1447
qdisc pfifo_fast 0: родительские полосы 1:7 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
    Отправлено 532876060762 байт 366663805 pkt (отброшено 0, превышено 0 запросов 7790)
    бэклог 0b 0p запрашивает 7790
qdisc pfifo_fast 0: родительские полосы 1:6 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
    Отправлено 563510390106 байт 387948990 pkt (отброшено 0, превышено 0 запросов 9694)
    невыполненные запросы 0b 0p 9694
qdisc pfifo_fast 0: родительские полосы 1:5 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
    Отправлено 563033712946 байт 387564038 pkt (отброшено 0, превышено 0 запросов 10259)
    отставание 0b 0p запрашивает 10259
qdisc pfifo_fast 0: родительские полосы 1:4 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
    Отправлено 562982455659 байт 387451904 пкт (отброшено 0, превышено 0 запросов 10706)
    отставание 0b 0p запрашивает 10706
qdisc pfifo_fast 0: родительские полосы 1:3 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
    Отправлено 559557988260 байт 385263948 pkt (отброшено 0, превышено 0 запросов 9983)
    невыполненные запросы 0b 0p 9983
qdisc pfifo_fast 0: родительские полосы 1:2 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
    Отправлено 528903326344 байт 364105031 pkt (отброшено 0, превышено 0 запросов 7718)
    отставание 0b 0p запрашивает 7718
qdisc pfifo_fast 0: родительские полосы 1:1 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
    Отправлено 1919099245018 байт 1313486295 пкт (отброшено 0, превышено 0 запросов 111970)
    отставание 0b 0p запрашивает 111970

ethtool -k eth0

Возможности для eth0:
rx-контрольная сумма: включено [исправлено]
tx-контрольная сумма: вкл.
        tx-checksum-ipv4: выключено [исправлено]
        tx-checksum-ip-generic: включен
        tx-checksum-ipv6: выключено [исправлено]
        tx-checksum-fcoe-crc: выключено [исправлено]
        tx-checksum-sctp: выключено [исправлено]
разбросать-собрать: вкл.
        tx-рассеять-собрать: включено
        tx-scatter-gather-fraglist: выключено [исправлено]
TCP-сегментация-разгрузка: выключено
        tx-tcp-сегментация: выключено
        tx-tcp-ecn-сегментация: выключено
        tx-tcp6-сегментация: выключено
        tx-tcp-mangleid-сегментация: выключено
udp-фрагментация-разгрузка: вкл.
общая-сегментация-разгрузка: выключено
общий прием-разгрузка: выкл.
big-receive-offload: выключено [исправлено]
rx-vlan-offload: выключен [исправлено]
tx-vlan-offload: выключен [исправлено]
ntuple-фильтры: выключено [исправлено]
получение-хеширование: выключено [исправлено]
highdma: включено [исправлено]
rx-vlan-filter: включено [исправлено]
вызов vlan: выключено [исправлено]
tx-lockless: выключено [исправлено]
netns-local: выключено [исправлено]
tx-gso-робаст: выключено [исправлено]
tx-fcoe-segmentation: выключено [исправлено]
tx-gre-segmentation: выключено [исправлено]
tx-ipip-segmentation: выключено [исправлено]
tx-sit-segmentation: выключено [исправлено]
tx-udp_tnl-сегментация: выключено [исправлено]
fcoe-mtu: выключено [исправлено]
tx-nocache-copy: выключено
петля: выключено [исправлено]
rx-fcs: выключено [исправлено]
rx-all: выключено [исправлено]
tx-vlan-stag-hw-insert: выключен [исправлено]
rx-vlan-stag-hw-parse: выключен [исправлено]
rx-vlan-stag-filter: выключено [исправлено]
занят-опрос: выключен [исправлено]
tx-gre-csum-segmentation: выключено [исправлено]
tx-udp_tnl-csum-segmentation: выключено [исправлено]
tx-gso-partial: выключено [исправлено]
tx-sctp-сегментация: выключено [исправлено]
rx-gro-hw: выключено [исправлено]
l2-fwd-offload: выключено [исправлено]
hw-tc-offload: выключено [исправлено]
rx-udp_tunnel-port-offload: выключено [исправлено]

sysctl -p

vm.max_map_count = 1048575
net.ipv4.tcp_timestamps = 0
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
сеть.ipv4.tcp_ecn = 0
net.ipv4.tcp_sack = 1
net.ipv4.tcp_syncookies = 0
net.ipv4.conf.all.log_martians = 1
vm.swappiness = 10
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65536
net.core.netdev_max_backlog = 250000
fs.file-max = 100000
net.ipv4.ip_local_port_range = 13000 65000
net.ipv4.udp_rmem_min = 8192
net.ipv4.udp_wmem_min = 8192
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.ip_forward = 0
net.ipv6.conf.all.forwarding = 0
net.ipv4.tcp_slow_start_after_idle = 0
net.core.rmem_max = 2147483647
net.core.rmem_default = 2147483647
net.core.wmem_max = 2147483647
net.core.wmem_default = 2147483647
net.core.optmem_max = 2147483647
net.ipv4.tcp_rmem = 4096 87380 2147483647
net.ipv4.tcp_wmem = 4096 65536 2147483647
net.ipv4.tcp_low_latency = 1
net.ipv4.tcp_adv_win_scale = 1
net.ipv4.tcp_keepalive_time = 60
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 5
net.ipv4.tcp_max_tw_buckets = 2000000
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp_keepalive_probes = 5
net.netfilter.nf_conntrack_max = 655360
net.netfilter.nf_conntrack_tcp_timeout_installed = 10800
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

улимит -а

размер основного файла (блоки, -c) 0
размер сегмента данных (кбайт, -d) не ограничен
приоритет планирования (-e) 0
размер файла (блоки, -f) не ограничен
ожидающие сигналы (-i) 256680
максимальная заблокированная память (кбайт, -l) не ограничена
максимальный размер памяти (кбайт, -m) не ограничен
открытые файлы (-n) 100000
размер канала (512 байт, -p) 8
Очереди сообщений POSIX (байты, -q) 819200
приоритет реального времени (-r) 0
размер стека (кбайт, -с) 100000
время процессора (секунды, -t) не ограничено
максимальное количество пользовательских процессов (-u) 100000
виртуальная память (кбайт, -v) не ограничена
блокировка файлов (-x) не ограничена

nginx.conf

рабочие_процессы авто;
worker_rlimit_nofile 100000;

потоки по умолчанию thread_pool = 256 max_queue = 65536;

События {
    worker_connections 65536;
    worker_aio_requests 65536;
    мульти_принять;
    accept_mutex включен;
    использовать эполл;
}

http {
    server_tokens отключены;
    server_names_hash_max_size 4096;
    server_names_hash_bucket_size 128;

    tcp_nopush включен;
    tcp_nodelay включен;
    client_body_timeout 12;
    client_header_timeout 12;
    keepalive_timeout 15;
    keepalive_requests 1000;
    send_timeout 10;

    потоки aio=по умолчанию;
    отправить файл включен;
    sendfile_max_chunk 512k;
    open_file_cache макс=100000 неактив=10м;
    open_file_cache_valid 10 м;
    open_file_cache_min_uses 10;
    open_file_cache_errors включен;

    сжатие выключено;
}

Итак, вопрос: как обслуживать соединения 10k с трафиком 10Gbps, загружая статические файлы? Это проблема Linux, Nginx или оборудования?

Brandon Xavier avatar
флаг us
Есть ли какое-то конкретное руководство, которому вы следовали при настройке? В частности, мне любопытно: A) выбор не включать большие кадры B) привязка/закрепление IRQ — я вижу, что у вас отключен irqbalance, но нет упоминания о закреплении IRQ сетевой карты к конкретному процессору C) различные параметры, которые были изменены из значений по умолчанию (извините, но определение этого только из вашей текущей конфигурации на самом деле не является хорошей тратой времени ;-)
JonS avatar
флаг br
Я прочитал много статей в Интернете https://www.kernel.org/doc/ols/2009/ols2009-pages-169-184.pdf https://fasterdata.es.net/host-tuning/linux/ https://darksideclouds.wordpress.com/2016/10/10/tuning-10gb-nics-highway-to-hell/ A) Потому что, насколько я знаю, он должен быть включен на всех коммутаторах, сетевых устройствах и подключающихся клиентах, поэтому он полезен только для передачи данных между высокоскоростными серверами. Б) Не установил сходство, потому что это виртуальная машина, могу ли я его установить? C) Я думаю, что параметры по умолчанию известны всем, кто хорошо провел время в linux и nginx, и их можно найти в Интернете.
JonS avatar
флаг br
действительно, все прерывания NIC поступают только на один процессор https://pastebin.com/9JTbgt5J, так что это узкое место, как установить привязку irq к VM virtio?
Рейтинг:3
флаг br
Joe

Уже ответил Брэндон. Включите иркбаланс. Запускаем numad и настраиваем. Не пытайтесь настроить, если у вас нет конкретной рабочей нагрузки, которая требует этого.Где результаты вашего рабочего теста по тестированию 2000-10000 запросов перед развертыванием? Эта проблема никогда не должна была быть замечена в производстве. Это явно было бы определено тестированием. Использование в реальных условиях часто выявляет необычные ошибки, но многие/большинство ошибок конфигурации и приложений могут быть идентифицированы и исправлены во время тестирования. Существует множество документов, касающихся привязки irq. Я сомневаюсь, что ваш вариант использования может работать лучше, чем использование встроенных инструментов настройки. Более чем вероятно, что ваша ручная настройка будет работать хуже.

JonS avatar
флаг br
Я включил irqbalance, теперь прерывания сбалансированы по 8 ядрам процессора, но проблема все еще существует, кажется, проблема с обработкой пакетов. я включил большую разгрузку приема и разгрузку tcp-сегментации, но большой разницы нет.
Brandon Xavier avatar
флаг us
Надеюсь, вы работаете над хостом, прежде чем настраивать гостя.
Рейтинг:1
флаг sz

Выход из вершина говорит, что ваше ядро ​​​​завалено программными прерываниями от всех входящих соединений. Соединения устанавливаются так быстро, что аппаратные прерывания, запускаемые сетевой картой, ставят программные прерывания в очередь быстрее, чем ядро ​​может с ними справиться.Вот почему ваш ЦП, ОЗУ и операции ввода-вывода настолько низки; система продолжает прерываться входящими соединениями. Здесь вам нужен балансировщик нагрузки.

JonS avatar
флаг br
Мы уже используем балансировщик нагрузки для отправки трафика на 2 сервера с одинаковой конфигурацией, поэтому я хочу, чтобы каждый сервер обрабатывал множество соединений с высокой пропускной способностью. Решает ли добавление дополнительных ядер ЦП проблему программных прерываний?
JonS avatar
флаг br
действительно, все прерывания NIC поступают только на один процессор https://pastebin.com/9JTbgt5J, так что это узкое место, как установить привязку irq к VM virtio?

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.