Ответ 1
Существует ряд факторов, которые определяют максимальный размер пакета, который может быть отправлен в сокет Unix:
-
Параметр ядра максимального размера буфера отправки
wmem_max
, который определяет максимальный размер буфера отправки, который можно установить с помощьюsetsockopt (SO_SNDBUF)
. Текущую настройку можно прочитать с помощью/proc/sys/net/core/wmem_max
и ее можно установить с помощьюsysctl net.core.wmem_max=VALUE
(добавьте параметр в/etc/sysctl.conf
, чтобы изменения были постоянными при перезагрузках). Обратите внимание, что этот параметр применяется ко всем сокетам и протоколам сокетов, а не только к сокетам Unix. -
Если несколько пакетов отправляются в сокет Unix (с использованием SOCK_DATAGRAM), то максимальный объем данных, которые могут быть отправлены без блокировки, зависит как от размера буфера отправки сокета (см. выше), так и от максимального количества непрочитанных пакетов в сокете Unix (параметр ядра
net.unix.max_dgram_qlen
). -
Наконец, пакет (SOCK_DATAGRAM) требует непрерывной памяти (согласно Каков максимальный размер сообщения датаграммы AF_UNIX, которое можно отправить в Linux?), Сколько непрерывной памяти доступно в ядре, будет зависеть от многих факторов (например, нагрузки ввода-вывода в системе и т.д.).
Таким образом, чтобы максимизировать производительность вашего приложения, вам нужен большой размер буфера сокета (чтобы свести к минимуму изменения контекста контекста пользователя/ядра из-за системных вызовов сокета) и большой очереди сокетов Unix (чтобы разделить производителя и потребителя как насколько это возможно). Однако размер буфера отправки сокета и длина очереди не должны быть настолько большими, чтобы ядро выходило из смежных областей памяти (что вызывало ошибки записи).
Фактические цифры будут зависеть от конфигурации и использования вашей системы. Вам нужно будет определить пределы путем тестирования... начните с wmem_max
при 256 Кб и max_dgram_qlen
в 32 и продолжайте удваивать wmem_max
, пока не заметите, что все начинает ломаться. Вам нужно будет настроить max_dgram_qlen
, чтобы сбалансировать активность производителя и потребителя в определенной степени (хотя, если производитель намного быстрее или намного медленнее, чем потребитель, размер очереди не будет иметь большого влияния).
Обратите внимание, что вашему производителю необходимо будет специально настроить размер буфера отправки сокетов на wmem_max
байты с вызовом setsockopt (SO_SNDBUF)
и ему придется разделить данные на wmem_max
байтовые фрагменты (и потребитель должен будет их собрать).
Лучшее предположение: практические ограничения будут вокруг wmem_max ~ 8Mb и unix_dgram_qlen ~ 32.