Подтвердить что ты не робот

Как WhatsApp достигла 2 миллионов подключений на сервер?

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

$ cat /proc/sys/net/ipv4/tcp_max_orphans
262144

Согласно одной из презентаций Рика Рида (от WhatsApp), эти ребята приняли до 2 миллионов одновременных соединений на "одном сервере" с использованием FreeBSD и ErLang. Я понимаю, что мы всегда будем нуждаться в поддержке от ядра. И да, похоже, что у FreeBSD есть возможность :

hw.machine: amd64
hw.model: Intel(R) Xeon(R) CPU X5675 @ 3.07GHz
hw.ncpu: 24
hw.physmem: 103062118400
hw.usermem: 100556451840

[email protected]$ uname -rps
FreeBSD 8.2-STABLE amd64

[email protected]$ cat /boot/loader.conf.local
kern.ipc.maxsockets=2400000
kern.maxfiles=3000000
kern.maxfilesperproc=2700000

Итак, похоже, что ядро ​​может быть настроено для поддержки стольких физических подключений, учитывая, что у нас есть достаточный объем памяти, правильно? Если да, то это выглядит довольно просто, тогда в чем заключается обман? Или я что-то упускаю?

Спасибо.

4b9b3361

Ответ 1

Обратите внимание, что здесь есть три вещи:

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

  • Выполнение чего-то с каждым подключением. Вы сопоставляете их в пользовательское пространство в процессе (в этом случае Erlang). Теперь, если каждое соединение выделяет слишком много данных на уровне пользовательского пространства, мы вернемся к квадрату. Мы не можем этого сделать.

  • Получение нескольких ядер для работы с соединениями. Это необходимо из-за огромного объема работы. Это также точка, в которой вы хотите избежать слишком большого количества блокировок и т.д.

Вы, кажется, сосредоточены на 1. в одиночку.

Ответ 2

Если у вас достаточно ОЗУ, не слишком сложно обрабатывать 1M или более соединений в Linux. Эти ребята обработали 10 миллионов соединений с java-приложением на одном ящике, используя обычное ядро ​​CentOS с несколькими настройками sysctl:

sysctl -w fs.file-max=12000500
sysctl -w fs.nr_open=20000500
ulimit -n 20000000
sysctl -w net.ipv4.tcp_mem='10000000 10000000 10000000'
sysctl -w net.ipv4.tcp_rmem='1024 4096 16384'
sysctl -w net.ipv4.tcp_wmem='1024 4096 16384'
sysctl -w net.core.rmem_max=16384
sysctl -w net.core.wmem_max=16384

Также они сбалансировали/proc/irq/сетевого адаптера и добавили настройку для лучшей работы JVM с огромными страницами:

sysctl -w vm.nr_hugepages=30720

С двумя 6-ядерными процессорами, загруженными на 57%, они обслуживали 1 Гбит/с через 12M-соединения в 2013 году.

Но для этого вам нужно ОГРОМНОЕ количество ОЗУ. Вышеупомянутый тест был на сервере с 96 ГБ ОЗУ, а 36 ГБ из них были использованы ядром для буферов сокетов 12М.

Для обслуживания 1M-соединений с аналогичными настройками вам понадобится сервер с объемом памяти не менее 8 ГБ, а 3-4 ГБ будут использоваться только для буферов сокетов.