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

Resuelto Piyush Kansal asked hace 10 años • 2 respuestas

En Ubuntu, el número máximo de sockets que se pueden abrir parece regirse 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 lograron hasta 2 millones de conexiones simultáneas en un "único servidor" usando FreeBSD y ErLang. Tengo entendido que siempre necesitaremos algún soporte del kernel. Y sí, parece que FreeBSD se modificó para que tenga esta capacidad :

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 el kernel se puede modificar para admitir tantas conexiones físicas, dado que tenemos suficiente cantidad de memoria, ¿correcto? En caso afirmativo, entonces parece bastante simple, entonces ¿cuál es el revuelo al respecto? ¿O me falta algo?

Gracias.

Piyush Kansal avatar Feb 28 '14 15:02 Piyush Kansal
Aceptado

Si tiene suficiente RAM, no es demasiado difícil manejar 1 millón o más de conexiones en Linux. Estos chicos manejaron 10 millones de conexiones con una aplicación Java en una sola caja usando el kernel CentOS normal 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 los /proc/irq/ del adaptador de red y agregaron un ajuste para un mejor trabajo de JVM con páginas grandes:

sysctl -w vm.nr_hugepages=30720

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

Pero necesitas una GRAN cantidad de RAM para eso. La prueba anterior se realizó en un servidor con 96 GB de RAM, y el kernel utilizó 36 GB de ellos para buffers de sockets de 12 M.

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

Guest avatar Oct 05 '2015 01:10 Guest

Tenga en cuenta que aquí hay tres cosas:

  1. Conseguir que el servidor admita dos millones de conexiones. Por lo general, esto consiste simplemente en ajustar el núcleo de modo que se permita la cantidad de conexiones simultáneas y de modo que el contexto asociado con cada conexión encaje en la memoria principal (cableada). Esto último significa que no se puede asignar un espacio de búfer de megabytes para cada conexión.

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

  3. Conseguir que varios núcleos hagan algo con las conexiones. Esto es necesario debido a la enorme cantidad de trabajo que queda por hacer. También es el punto en el que desea evitar bloquear demasiado, etc.

Pareces estar concentrado solo en 1.

I GIVE CRAP ANSWERS avatar Mar 01 '2014 12:03 I GIVE CRAP ANSWERS