- Максимальное количество сокетов в Linux
- 8 ответов
- Настройка сетевого стека Linux для высоконагруженных систем
- Максимизируем количество входящих соединений
- Очередь приема и netdev_max_backlog
- Очередь ожидающих запросов на соединение и tcp_max_syn_backlog
- SYN Cookie
- Повторы SYN+ACK
- Повторы SYN
- Очередь установленных соединений ожидающих принятия (accept queue) и somaxconn
- somaxconn и параметр backlog в listen()
- Значения по умолчанию для очереди
- Изменение размера очереди
- Потоки
- Соединения и файловые дескрипторы
- Системные ограничения
- Пользовательские ограничения
- Настройка
- Количество worker’ов
- Системные ограничения
- Пользовательские ограничения
- Настройка
- Обратный прокси и TIME_WAIT
- Собираем все вместе
- Параметры
- Заключение
Максимальное количество сокетов в Linux
Кажется, что сервер ограничен в
32720 розетки. Я пробовал каждое известное изменение переменной, чтобы поднять этот предел. Но сервер остается ограниченным в 32720 открытом сокете, даже если есть еще 4Go свободной памяти и 80% бездействующего процессора.
8 ответов
Если вы имеете дело с openssl и потоками, проверьте /proc/sys/vm/max_map_count и попробуйте поднять его.
о каком сервере вы говорите ? Возможно, он имеет жестко закодированный max или работает в других пределах (max threads/out of address space и т. д.)
http://www.metabrew.com/article/a-million-user-comet-application-with-mochiweb-part-1 имеет некоторую настройку, необходимую для достижения большого количества соединений, но это не помогает, если серверное приложение ограничивает его тем или иным образом.
в IPV4 уровень TCP имеет 16 бит для порта назначения и 16 бит для порта источника.
видя, что ваш предел 32K, я ожидал бы, что вы действительно видите предел исходящих TCP-соединений, которые вы можете сделать. Вы должны иметь возможность получить максимум 65K сокетов (это будет предел протокола). Это ограничение для общего числа именованных соединений. К счастью, привязка порта для входящих подключений использует только 1. Но если вы пытаетесь проверить количество соединений с одной машины, вы можете иметь только 65K общих исходящих соединений (для TCP). Для проверки количества входящих подключений потребуется несколько компьютеров.
Примечание: Вы можете вызвать сокет (AF_INET. ) до количества доступных файловых дескрипторов, но вы не можете связать их без увеличения числа доступных портов. Чтобы увеличить диапазон, сделайте это:
Эхо «1024 65535» > /proc/sys / net/ipv4/ip_local_port_range (cat, чтобы увидеть, что у вас есть в настоящее время-по умолчанию 32768 до 61000)
возможно, пришло время для нового протокола TCP, который позволит 32 бита для исходного и dest портов? Но сколько приложений действительно нужно более 65 тысяч исходящих подключений?
следующее позволит 100 000 входящих подключений на linux mint 16 (64 бит) (вы должны запустить его как root, чтобы установить пределы)
Если вы рассматриваете приложение, где вы считаете, что вам нужно открыть тысячи сокетов, вы обязательно захотите прочитать о Проблема C10k. На этой странице обсуждаются многие проблемы, с которыми вы столкнетесь при увеличении количества клиентских подключений к одному серверу.
в Gnu+Linux максимум-это то, что вы написали. Это число (вероятно) указано где-то в стандартах сети. Сомневаюсь, что тебе нужно так много розеток. Вы должны оптимизировать способ использования сокетов, а не создавать десятки все время.
чистая/сокет.c fd выделяется в sock_alloc_fd (), который вызывает get_unused_fd ().
глядя на linux/fs / файл.c, единственное ограничение на количество fd-это sysctl_nr_open , ограниченном
и может быть прочитано с помощью sysctl fs.nr_open что дает 1M по умолчанию здесь. Так что fd, вероятно, не ваша проблема.
редактировать вы, вероятно, также проверили это, но не могли бы вы поделиться выводом
вообще иметь слишком много живых соединений-это плохо. Однако все зависит от приложения и шаблонов, с которыми оно взаимодействует со своими клиентами.
Я полагаю, что существует шаблон, когда клиенты должны быть постоянно асинхронно подключены, и это единственный способ работы распределенного решения.
Assumimg нет узких мест в памяти / cpu / сети для текущей нагрузки, и имея в виду, что оставить простое открытое соединение-единственный способ распределенные приложения потребляют меньше ресурсов (например, время подключения и общая/Пиковая память), общая производительность сети ОС может быть выше, чем использование лучших практик, которые мы все знаем.
хороший вопрос, и он нуждается в решении. Проблема в том, что никто не может на это ответить. Я бы предложил использовать технику divide & conquer, и когда узкое место будет найдено, вернитесь к нам.
пожалуйста, разберите приложение на тестовом стенде, и вы найдете узкое место.
Проверьте реальные пределы запущенного процесса.
max для nofiles определяется ядром, следующее, поскольку root увеличит max до 100 000 «файлов», т. е. 100k CC
чтобы сделать его постоянным edit/etc / sysctl.conf
затем вам нужно, чтобы сервер запрашивал больше открытых файлов, это отличается от сервера. Например, в nginx вы устанавливаете
перезагрузите nginx и проверьте /proc /
чтобы проверить это, вам нужно 100 000 сокетов в вашем клиенте, вы ограничены в тестировании количеством портов в TCP на IP-адрес.
для увеличения диапазона локальных портов до максимума.
64000 портов для тестирования.
если этого недостаточно, вам нужно больше IP-адресов. При тестировании на localhost вы можете привязать источник / клиент к IP, отличному от 127.0.0.1 / localhost.
например вы можете привязать тестовые клиенты к IPs, случайным образом выбранным от 127.0.0.1 до 127.0.0.5
используя apache-bench, вы установите
сокеты Nodejs будут использовать
/ etc / security / limits.conf настраивает PAM: обычно это не имеет значения для сервера.
если сервер проксирует запросы, используя TCP, например, upstream или mod_proxy, сервер ограничен ip_local_port_range. Это легко может быть предел 32,000.
Источник
Настройка сетевого стека Linux для высоконагруженных систем
Максимизируем количество входящих соединений
Приглашаем всех желающих посетить открытый демо-урок «Практикум по написанию Ansible роли». На этом вебинаре участники вместе с экспертом будут писать, тестировать и отлаживать ansible роли. Это важно для тех, кто хочет автоматизировать настройку инфраструктуры, поскольку это один из инструментов, который это позволяет сделать. Сетевой стек — одна из самых запутанных вещей в Linux. И не только из-за сложности некоторых концепций и терминов, но и из-за изменения смысла некоторых параметров в разных версиях ядра. В этой статье приведена информация для ядра 2.2 и выше, а также, там где это возможно, указано различие между версиями вплоть до 5.5.
Очередь приема и netdev_max_backlog
Каждое ядро процессора перед обработкой пакетов сетевым стеком может хранить их в кольцевом буфере. Если буфер заполняется быстрее, чем TCP-стек обрабатывает пакеты, то пакеты отбрасываются и увеличивается счетчик отброшенных пакетов (dropped packet counter). Для увеличения размера очереди следует использовать параметр net.core.netdev_max_backlog .
net.core.netdev_max_backlog — параметр задается на ядро процессора.
Очередь ожидающих запросов на соединение и tcp_max_syn_backlog
Соединения создаются для SYN-пакетов из очереди приема и перемещаются в очередь ожидания (SYN Backlog Queue). Также соединение помечается как «SYN_RECV» и клиенту отправляется «SYN+ACK». Эти соединения не перемещаются в очередь установленных соединений ожидающих обработки accept() (accept queue) до тех пор, пока не будет получен и обработан соответствующий ACK. Максимальное количество соединений в этой очереди устанавливается параметром net.ipv4.tcp_max_syn_backlog .
Для просмотра очереди приема используйте команду netstat . На правильно настроенном сервере при нормальной нагрузке значение не должно быть больше 1. При большой нагрузке значение должно быть меньше размера очереди ожидания (SYN Backlog):
Если в состоянии «SYN_RECV» находятся много соединений, то можно также подстроить продолжительность нахождения SYN-пакета в этой очереди.
SYN Cookie
Если SYN cookie отключены, то клиент просто повторяет отправку SYN-пакета. Если включены (net.ipv4.tcp_syncookies), то соединение не создается и не помещается в SYN backlog, но клиенту отправляется SYN+ACK так, как если бы это было сделано на самом деле. SYN cookie могут быть полезны при нормальной нагрузке, но при всплесках трафика некоторая информация о соединении может быть потеряна и клиент столкнется с проблемами, когда соединение будет установлено. Подробнее о SYN cookie можно прочитать в статье Грэма Коула (Graeme Cole) SYN cookies ate my dog (SYN cookie съели мою собаку), в которой подробно объясняется, почему включение SYN cookie на высоконагруженных серверах может привести к проблемам.
Повторы SYN+ACK
Что происходит, если SYN+ACK отправлен, но ответа ACK нет? В этом случае сетевой стек сервера повторит отправку SYN+ACK. Задержка между попытками вычисляется таким образом, чтобы обеспечить восстановление сервера. Если сервер получает SYN и отправляет SYN+ACK, но не получает ACK, то тайм-аут повторной передачи вычисляется по экспоненте (Exponental Backoff) и, следовательно, зависит от количества повторных попыток. Количество повторных попыток отправки SYN+ACK задается параметром ядра net.ipv4.tcp_synack_retries (по умолчанию равно 5). Повторные попытки будут через следующие интервалы: 1с, 3с, 7с, 15с, 31с. При шести попытках последняя будет примерно через 63 секунды после первой. Это позволяет удержать SYN-пакет в очереди ожидания более 60 секунд до истечения времени ожидания пакета. Если очередь SYN backlog мала, то не требуется большого количества соединений, чтобы возникла ситуация, когда полуоткрытые соединения никогда не завершатся и тогда никакие соединения не смогут быть установлены. Установите количество повторных попыток SYN+ACK равным 0 или 1, чтобы избежать такого поведения на высоконагруженных серверах.
Повторы SYN
Несмотря на то что повторные SYN-пакеты отправляются клиентом во время ожидания SYN+ACK, они могут влиять и на высоконагруженные серверы, работающие с прокси-соединениями. Например, сервер nginx, устанавливающий несколько десятков прокси-соединений к бэкенд-серверу, из-за всплесков трафика может на некоторое время перегрузить сетевой стек, а повторные попытки создадут дополнительную нагрузку на бэкэнд как в очереди приема, так и в очереди ожидания (SYN backlog). Это, в свою очередь, может повлиять на клиентские соединения. Повторные попытки SYN контролируются параметром net.ipv4.tcp_syn_retries (по умолчанию 5 или 6 в зависимости от дистрибутива). Ограничьте количество повторных попыток SYN до 0 или 1, чтобы не было долгих повторных попыток отправки в течение 63–130 с.
Более подробно о проблемах с клиентскими соединениями при обратном прокси-сервере читайте в статье Linux Kernel Tuning for High Performance Networking: Ephemeral Ports.
Очередь установленных соединений ожидающих принятия (accept queue) и somaxconn
Очередь запросов на соединение создает приложение, используя listen() и указывая размер очереди в параметре «backlog». Начиная с ядра 2.2 поведение этого параметра изменилось с максимального количества неоконченных запросов на соединение, которое может удерживать сокет, на максимальное количество полностью установленных соединений, ожидающих, пока они будут приняты. Как описано выше, максимальное количество неоконченных запросов на соединение теперь задается с помощью параметра ядра net.ipv4.tcp_max_syn_backlog .
somaxconn и параметр backlog в listen()
Хотя за размер очереди для каждого слушателя отвечает приложение, есть ограничение на количество соединений, которые могут находиться в очереди. Размером очереди управляют два параметра: 1) параметр backlog в функции listen() и 2) параметр ядра net.core.somaxconn , задающий максимальный размер очереди.
Значения по умолчанию для очереди
Значение по умолчанию для net.core.somaxconn берется из константы SOMAXCONN, которая в ядрах Linux вплоть до версии 5.3 имеет значение 128, но в 5.4 она была увеличена до 4096. Однако, на момент написания этой статьи, ядро 5.4 еще не очень распространено, поэтому в большинстве систем значение будет 128, если вы не модифицировали net.core.somaxconn.
Часто приложения для размера очереди по умолчанию используют константу SOMAXCONN, если этот размер не задается в конфигурации приложения. Хотя некоторые приложения устанавливают и свои значения по умолчанию. Например, в nginx размер очереди равен 511, который автоматически усекается до 128 в ядрах Linux до версии 5.3.
Изменение размера очереди
Многие приложения позволяют указывать размер очереди в конфигурации, указывая значение параметра backlog для listen() . Если приложение вызывает listen() со значением backlog , превышающим net.core.somaxconn, то размер очереди будет автоматически усечен до значения SOMAXCONN.
Потоки
Если очередь большая, то подумайте также об увеличении количества потоков, которые обрабатывают запросы в приложении. Например, установка для nginx очереди ожидания в 20480 для HTTP-listener без достаточного количества worker_connections для управления очередью приведет к тому, что сервер будет отказываться отвечать на запросы на установку соединения.
Соединения и файловые дескрипторы
Системные ограничения
Любое сокетное соединение использует файловый дескриптор. Максимальное количество дескрипторов, которые могут быть созданы в системе, задается параметром ядра fs.file-max. Посмотреть количество используемых дескрипторов можно следующим образом:
Вывод показывает, что используется 1976 файловых дескрипторов. Выделено, но не используется 12 (для ядер 2.6+), а максимальное количество — 2048. В высоконагруженной системе значение должно быть достаточно большим, чтобы справиться как с большим количеством соединений, так и с потребностями в файловых дескрипторах других процессов.
Пользовательские ограничения
Помимо системного ограничения количества файловых дескрипторов, у каждого пользователя есть свои лимиты. Они настраиваются в системном файле limits.conf (nofile) или, при запуске процесса под управлением systemd, в unit-файле systemd (LimitNOFILE). Чтобы увидеть значение по умолчанию запустите:
Для systemd (на примере nginx):
Настройка
Для настройки системных ограничений установите параметр ядра fs.max-file в максимальное количество файловых дескрипторов, которое может быть в системе (с учетом некоторого буфера). Например:
Для настройки пользовательского лимита установите достаточно большое значение, чтобы хватило сокетам и файловым дескрипторам рабочих процессов (также с некоторым буфером). Пользовательские ограничения устанавливаются в /etc/security/limits.conf, в conf-файле в /etc/security/limits.d/ или в unit-файле systemd. Например:
Количество worker’ов
Аналогично файловым дескрипторам, количество worker’ов или потоков, которые может создать процесс, ограничено как на уровне ядра, так и на уровне пользователя.
Системные ограничения
Процессы могут создавать рабочие потоки. Максимальное количество потоков, которые могут быть созданы, задается параметром ядра kernel.threads-max . Для просмотра максимального и текущего количества потоков, выполняющихся в системе, запустите следующее:
Пользовательские ограничения
Есть свои ограничения и у каждого пользовательского процесса. Это также настраивается с помощью файла limits.conf (nproc) или unit-файла systemd (LimitNPROC). Для просмотра максимального количества потоков, которое может создать пользователь запустите:
Для systemd (на примере nginx):
Настройка
В большинстве случаев системные ограничения достаточно большие, чтобы справиться с высокой нагрузкой. Однако их можно настроить через параметр ядра kernel.threads-max . Установите его значение в максимальное количество потоков, необходимых системе, плюс некоторый буфер. Например:
Как и в случае с nofile , ограничения для пользователей ( nproc ) устанавливаются в /etc/security/limits.conf, в conf-файле в /etc/security/limits.d/ или в unit-файле systemd. Пример с nproc и nofile :
Обратный прокси и TIME_WAIT
При большом всплеске трафика прокси-соединения, застрявшие в «TIME_WAIT», суммарно могут потреблять много ресурсов при закрытии соединения. Это состояние говорит, что клиент получил последний FIN-пакет от сервера (или вышестоящего worker’а) и находится в ожидании для корректной обработки пакетов. Время нахождения соединения в состоянии «TIME_WAIT» по умолчанию составляет 2 x MSL (Maximum Segment Length — максимальная длина сегмента), что составляет 2 x 60 с. В большинстве случаев это нормальное и ожидаемое поведение, и значение по умолчанию в 120 с вполне приемлемо. Однако много соединений в состоянии «TIME_WAIT» может привести к тому, что приложение исчерпает эфемерные порты для соединений к клиентскому сокету. В этом случае следует уменьшить FIN тайм-аут.
Управляет этим тайм-аутом параметр net.ipv4.tcp_fin_timeout . Рекомендуемое значение для высоконагруженных систем составляет от 5 до 7 секунд.
Собираем все вместе
Очередь приема (receive queue) должна быть рассчитана на обработку всех пакетов, полученных через сетевой интерфейс, не вызывая отбрасывания пакетов. Также необходимо учесть небольшой буфер на случай, если всплески будут немного выше, чем ожидалось. Для определения правильного значения следует отслеживать файл softnet_stat на предмет отброшенных пакетов. Эмпирическое правило — использовать значение tcp_max_syn_backlog, чтобы разрешить как минимум столько же SYN-пакетов, сколько может быть обработано для создания полуоткрытых соединений. Помните, что этот параметр задает количество пакетов, которое каждый процессор может иметь в своем буфере, поэтому разделите значение на количество процессоров.
Размер SYN очереди ожидания (SYN backlog queue) на высоконагруженном сервере должен быть рассчитан на большое количество полуоткрытых соединений для обработки редких всплесков трафика. Здесь эмпирическое правило заключается в том, чтобы установить это значение, по крайней мере, на максимальное количество установленных соединений, которое слушатель может иметь в очереди приема, но не выше, чем удвоенное количество установленных соединений. Также рекомендуется отключить SYN cookie, чтобы избежать потери данных при больших всплесках соединений от легитимных клиентов.
Очередь установленных соединений, ожидающих принятия (accept queue) должна быть рассчитана таким образом, чтобы в периоды сильного всплеска трафика ее можно было использовать в качестве временного буфера для установленных соединений. Эмпирическое правило — устанавливать это значение в пределах 20–25% от числа рабочих потоков.
Параметры
В этой статье были рассмотрены следующие параметры ядра:
И следующие пользовательские ограничения:
Заключение
Все параметры в этой статье приведены в качестве примеров и не должны вслепую применяться на ваших продакшн-серверах без тестирования. Есть и другие параметры ядра, которые влияют на производительность сетевого стека. Но в целом, это наиболее важные параметры, которые я использовал при настройке ядра для высоконагруженных систем.
Источник