sockets unix erlang freebsd whatsapp

sockets - ¿Cómo logró WhatsApp 2 millones de conexiones por servidor?



unix erlang (2)

Si tienes suficiente memoria RAM, no es demasiado difícil manejar 1M o más conexiones en Linux. Estos chicos manejaron 10 millones de conexiones con una aplicación java en una sola caja utilizando kernel de CentOS regular con algunos ajustes de 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

También equilibraron / proc / irq / s del adaptador de red y agregaron un ajuste para un mejor trabajo de JVM con páginas enormes:

sysctl -w vm.nr_hugepages=30720

Con dos CPUs de 6 núcleos cargadas al 57%, served 1Gbps en 12 millones de conexiones en 2013.

Pero necesitas una GRAN cantidad de RAM para eso. La prueba anterior estaba en un servidor con 96GB de RAM, y 36GB de esos fueron utilizados por el kernel para buffers de 12M sockets.

Para servir conexiones de 1M con configuraciones similares, necesitará un servidor con al menos 8GB de RAM y 3-4GB de ellas se usarán solo para buffers de socket.

En Ubuntu, el número máximo de sockets que se puede abrir parece estar gobernado por lo siguiente:

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

Según una de las presentaciones de Rick Reed (de WhatsApp), estos chicos tomaron hasta 2 millones de conexiones simultáneas en un "servidor único" utilizando FreeBSD y ErLang. Tengo entendido que siempre necesitaremos algo de apoyo del kernel. Y sí, parece que el ajuste de FreeBSD tiene esta capability :

hw.machine: amd64 hw.model: Intel(R) Xeon(R) CPU X5675 @ 3.07GHz hw.ncpu: 24 hw.physmem: 103062118400 hw.usermem: 100556451840 kb@c123$ uname -rps FreeBSD 8.2-STABLE amd64 jkb@c123$ cat /boot/loader.conf.local kern.ipc.maxsockets=2400000 kern.maxfiles=3000000 kern.maxfilesperproc=2700000

Entonces, parece que kernel puede ser modificado para soportar tantas conexiones físicas, dado que tenemos suficiente cantidad de memoria, ¿correcto? En caso afirmativo, parece bastante simple, entonces, ¿cuál es la exageración al respecto? ¿O me falta algo?

Gracias.


Tenga en cuenta que hay tres cosas aquí:

  1. Conseguir que el servidor admita dos millones de conexiones. Por lo general, se trata de ajustar el kernel de modo que se permita el número de conexiones simultáneas y que el contexto asociado a cada conexión se ajuste a la memoria principal (cableada). Esto último significa que no puede tener un espacio de búfer megabyte asignado para cada conexión.

  2. Haciendo algo con cada conexión Los mapea en el espacio de usuario en un proceso (Erlang en este caso). Ahora, si cada conexión asigna demasiados datos en el nivel de espacio de usuario, volvemos al punto uno. No podemos hacerlo

  3. Obtener múltiples núcleos para hacer algo con las conexiones. Esto es necesario debido a la gran cantidad de trabajo que se debe hacer. También es el punto en el que desea evitar el bloqueo demasiado y así sucesivamente.

Pareces enfocado solo en 1.