Zócalo Unix local: idea aproximada del rendimiento

10

¿Alguien está al tanto de los parámetros / mediciones de rendimiento para usar un socket local de Unix para la comunicación entre procesos?

Quiero ilustrar el beneficio de rendimiento de tener una instancia de base de datos local en el mismo servidor que el software que solicita los datos de la base de datos en lugar de tener que comunicarse a través de un enlace de red, especialmente uno como Gigabit Ethernet, que espero sea bastante lento Hablando relativamente.

Al buscar en línea, encontré algunos puntos de referencia que mostraban el número de operaciones por segundo, pero no el rendimiento por segundo (es decir, 12 GB / s).

Entiendo que el rendimiento variará debido a cosas como quizás el rendimiento de la memoria en un sistema dado u otras características de hardware, pero solo se necesita una idea aproximada.

Esto no se refiere al rendimiento del TCP local ni a una comparación con eso.

sa289
fuente
Usted está , en realidad, en referencia al rendimiento de la red TCP vs. local. También es incorrecto medir en su escenario.
Satō Katsura
@SatoKatsura Me refiero a en.wikipedia.org/wiki/Unix_domain_socket
sa289
Sip. ¿Y cómo crees que realmente se implementan los sockets de dominio UNIX?
Satō Katsura
@SatoKatsura No estoy seguro, pero hay alguna diferencia en función de lo que he leído, incluso si no es diferente día y noche. También hay puntos de referencia que comparan los sockets de dominio de Unix local con los sockets TCP locales que muestran una diferencia de rendimiento significativa.
sa289
También hay puntos de referencia que comparan los sockets de dominio de Unix local con los sockets TCP locales que muestran una diferencia de rendimiento significativa. - ¿Puede señalar uno de esos puntos de referencia?
Satō Katsura

Respuestas:

19

Puede usar socat para una simple prueba de velocidad de socket de UNIX.

A continuación se muestran los resultados que obtengo en mi computadora portátil:

#Generate 1GB random file in the "shared memory" (i.e. RAM disk) 
>dd if=/dev/urandom of=/dev/shm/data.dump bs=1M count=1024

Memoria a disco (SSD), a través del zócalo UNIX

>socat -u -b32768 UNIX-LISTEN:/tmp/unix.sock ./data.dump &
>socat -u -b32768 "SYSTEM:dd if=/dev/shm/data.dump bs=1M count=1024" UNIX:/tmp/unix.sock
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 1.96942 s, 545 MB/s

Memoria a memoria, a través del zócalo UNIX

>socat -u -b32768 UNIX-LISTEN:/tmp/unix.sock /dev/shm/data.dump.out &
>socat -u -b32768 "SYSTEM:dd if=/dev/shm/data.dump bs=1M count=1024" UNIX:/tmp/unix.sock
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 0.927163 s, 1.2 GB/s

Memoria a / dev / null (descartar), a través del socket UNIX

>socat -u -b32768 UNIX-LISTEN:/tmp/unix.sock /dev/null &
>socat -u -b32768 "SYSTEM:dd if=/dev/shm/data.dump bs=1M count=1024" UNIX:/tmp/unix.sock
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 0.720415 s, 1.5 GB/s

/ dev / zero a / dev / null, a través del socket UNIX

>socat -u -b32768 UNIX-LISTEN:/tmp/unix.sock /dev/null &
>socat -u -b32768 "SYSTEM:dd if=/dev/zero bs=1M count=1024" UNIX:/tmp/unix.sock
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 0.491179 s, 2.2 GB/s

Como puede ver, incluso el rendimiento de prueba de "memoria a disco" es 545MB / s (es decir, ~ 4360MiB / s), que está muy por delante de un rendimiento teórico máximo para la conexión Ethernet de 1GB (que es ~ 1000/8 = 125MB / s, ni siquiera considerando cualquier sobrecarga de protocolo).

PD

Tenga en cuenta que esta es solo una prueba simple usando algunas herramientas simples, y no un punto de referencia real y adecuado .

zepelín
fuente
1
Como digo a continuación, no confunda el ancho de banda con el rendimiento. socat le dirá el ancho de banda en condiciones "ideales", le dirá si no se está alcanzando el ancho de banda teórico, pero no le dirá nada acerca de los retrasos que causan la desaceleración de la aplicación. Compare la E / S de disco a 8 Gbit - prueba de esfuerzo. Eso es lo máximo que puedes obtener, sea lo que sea X. Si la aplicación alcanza que "los medios" pueden ser su cuello de botella. Si la aplicación no alcanza ese nivel, el "cuello de botella" no es el medio. Si socat alcanza un máximo de 1 Gbit, pero la aplicación no, socat no me dice qué limita el "rendimiento".
Michael sintió el
3

Mi "respuesta" es larga: la clave es no confundir 'rendimiento' con 'ancho de banda', aunque 'ancho de banda' puede ser un factor limitante

En resumen, su rendimiento puede ser limitado aunque su ancho de banda no esté saturado.


He tenido que ayudar a las personas a comprender el impacto de las pilas de aplicaciones de varios niveles.

Para el aspecto de las comunicaciones TCP, utilizo las diferencias en RTT (tiempo de ida y vuelta).

Para un solo nivel, puede comparar la dirección IP local (en una NIC) con lo0 (loopback).

Para los niveles múltiples, puede comparar / calcular las direcciones "más distantes", por ejemplo, los niveles múltiples pueden ser dos VM en el mismo host, o pueden ser hosts diferentes en el mismo centro de datos, o pueden estar en diferentes centros de datos (tal vez solo 500 metros de distancia, pero aún diferente).

FYI: para muchas aplicaciones, las diferencias de RTT son insignificantes, pero para las aplicaciones que hacen de 10 a 100 de miles de mensajes pequeños para el tiempo de RTT de la aplicación pueden convertirse en un cuello de botella.

(He visto situaciones en las que el "lote tardó casi 6 horas más en varios niveles cuando el RTT fue 0,25 milisegundos más, en comparación con un solo nivel)

Entonces, banco de pruebas simple:

los

for host in 127.0.0.1 192.168.129.63 192.168.129.72 192.168.129.254 192.168.129.71 p5.aixtools.net
do
    wget -q http://${host}/ -O - >/dev/null
    sleep 1
done

Y mi programa de monitoreo es tcpdump, con la opción -ttt

   -ttt
        Prints a delta (in microseconds) between current and previous line on each dump line.

Un microsegundo es una unidad de tiempo SI igual a una millonésima (0.000001 o 10−6 o 1 / 1,000,000). Es decir, 1000 microsegundos == 1 milisegundo.

Entonces, en dos ventanas diferentes tengo tcpdump ejecutándose:

Para los tiempos "locales": tcpdump -i lo0 -n -ttt port 80 Y para el "remoto" tcpdump -I en1 -n -ttt port 80

En los datos a continuación, el objetivo no es hacer ningún análisis, sino mostrar cómo puede identificar 'diferencias' en el tiempo requerido para completar las transacciones. Cuando el rendimiento de una aplicación son transacciones en serie, el rendimiento por "seg | min | hora" se ve afectado por el tiempo total requerido para las "respuestas". He encontrado esto más fácil de explicar usando el concepto de RTT: tiempo de ida y vuelta.

Para un análisis real, hay cosas adicionales a tener en cuenta. Entonces, las únicas líneas que mostraré son el protocolo de enlace TCP inicial, y el primer paquete saliente y el ACK de regreso. Para la comparación, compare los tiempos delta de cuánto tiempo antes de que regrese la "respuesta".

127.0.0.1

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo0, link-type 0, capture size 96 bytes
00:00:00.000000 IP 127.0.0.1.42445 > 127.0.0.1.80: S 1760726915:1760726915(0) win 65535 <mss 16856,nop,wscale 2,nop,nop,timestamp 1482096651 0>
00:00:00.**000035** IP 127.0.0.1.80 > 127.0.0.1.42445: S 3339083773:3339083773(0) ack 1760726916 win 65535 <mss 16856,nop,wscale 2,nop,nop,timestamp 1482096651 1482096651>
00:00:00.000013 IP 127.0.0.1.42445 > 127.0.0.1.80: . ack 1 win 33688 <nop,nop,timestamp 1482096651 1482096651>
00:00:00.**000014** IP 127.0.0.1.80 > 127.0.0.1.42445: . ack 1 win 33688 <nop,nop,timestamp 1482096651 1482096651>

192.168.129.63

tenga en cuenta el 01.XXXXXX - para el sueño de un segundo en la interfaz "lo0"

00:00:01.006055 IP 192.168.129.63.42446 > 192.168.129.63.80: S 617235346:617235346(0) win 65535 <mss 16856,nop,wscale 2,nop,nop,timestamp 1482096653 0>
00:00:00.**000032** IP 192.168.129.63.80 > 192.168.129.63.42446: S 1228444163:1228444163(0) ack 617235347 win 65535 <mss 16856,nop,wscale 2,nop,nop,timestamp 1482096653 1482096653>
00:00:00.000014 IP 192.168.129.63.42446 > 192.168.129.63.80: . ack 1 win 33688 <nop,nop,timestamp 1482096653 1482096653>
00:00:00.**000010** IP 192.168.129.63.80 > 192.168.129.63.42446: . ack 1 win 33688 <nop,nop,timestamp 1482096653 1482096653>

192.168.129.72

máquina virtual en el mismo host: tenga en cuenta que la hora comienza a las 00.000000: se muestra el primer paquete (y el 01.XXXXXX para las otras dos direcciones a continuación)

root@x063:[/]tcpdump -i en1 -n -ttt port 80
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on en1, link-type 1, capture size 96 bytes
00:00:00.000000 IP 192.168.129.63.42447 > 192.168.129.72.80: S 865313265:865313265(0) win 65535 <mss 1460,nop,wscale 3,nop,nop,timestamp 1482096655 0>
00:00:00.**000125** IP 192.168.129.72.80 > 192.168.129.63.42447: S 916041515:916041515(0) ack 865313266 win 65535 <mss 1460,nop,wscale 2,nop,nop,timestamp 1481318272 1482096655>
00:00:00.000028 IP 192.168.129.63.42447 > 192.168.129.72.80: . ack 1 win 32761 <nop,nop,timestamp 1482096655 1481318272>
00:00:00.**000055** IP 192.168.129.72.80 > 192.168.129.63.42447: . ack 1 win 65522 <nop,nop,timestamp 1481318272 1482096655>

192.168.129.254

mi enrutador: fuera del host, no una máquina virtual.

00:00:01.005947 IP 192.168.129.63.42448 > 192.168.129.254.80: S 2756186848:2756186848(0) win 65535 <mss 1460,nop,wscale 3,nop,nop,timestamp 1482096657 0>
00:00:00.**000335** IP 192.168.129.254.80 > 192.168.129.63.42448: S 2327415811:2327415811(0) ack 2756186849 win 5792 <mss 1460,nop,nop,timestamp 44854195 1482096657,nop,wscale 2,nop,opt-14:03>
00:00:00.000022 IP 192.168.129.63.42448 > 192.168.129.254.80: . ack 1 win 32761 <nop,nop,timestamp 1482096657 44854195>
00:00:00.**000090** IP 192.168.129.63.42448 > 192.168.129.254.80: P 1:142(141) ack 1 win 32761 <nop,nop,timestamp 1482096657 44854195>

192.168.129.71

misma conexión que 192.168.129.72, pero esto está 'ocupado' mientras que '72' está inactivo. Espero que los apretones de manos iniciales sean casi idénticos

00:00:01.005093 IP 192.168.129.63.42449 > 192.168.129.71.80: S 249227688:249227688(0) win 65535 <mss 1460,nop,wscale 3,nop,nop,timestamp 1482096659 0>
00:00:00.**000072** IP 192.168.129.71.80 > 192.168.129.63.42449: S 1898177685:1898177685(0) ack 249227689 win 65535 <mss 1460,nop,wscale 2,nop,nop,timestamp 1482096104 1482096659>
00:00:00.000022 IP 192.168.129.63.42449 > 192.168.129.71.80: . ack 1 win 32761 <nop,nop,timestamp 1482096659 1482096104>
00:00:00.**000050** IP 192.168.129.71.80 > 192.168.129.63.42449: . ack 1 win 65522 <nop,nop,timestamp 1482096104 1482096659>

saltos múltiples

este es el mismo host, el mismo resultado de apache, pero ahora a través de la interfaz externa (6 saltos IP, en lugar de directo): ahora puede obtener el efecto de RTT de larga distancia. (ps, modifiqué la dirección IP ligeramente). Más importante: observe que hay dos paquetes salientes después del apretón de manos inicial antes del primer ACK después de que vuelve un apretón de manos.

Entonces, en lugar de RTT de 25 ms, piense que el RTT es de 250 microsegundos, en comparación con 25 microsegundos, y tiene transacciones de 500k (eso equivale a solo 120 a 125 segundos adicionales en comparación con el local, y el rendimiento es, en mi opinión, comparable. Pero con 50 millones de transacciones (como lo hice en una situación de la vida real) gana 12500 segundos adicionales, lo que agrega alrededor de 3.5 horas adicionales para "literalmente" el mismo trabajo (y parte de la solución para este caso era hacer que los paquetes fueran más grandes) el tamaño promedio era originalmente de 400-450 bytes).

Recuerde, lo que quiero mostrar aquí es una forma bastante simple de explicar las diferencias en el tiempo general para que se complete una aplicación (trabajo por lotes) al comparar arquitecturas de varios niveles con arquitecturas de un solo nivel.

00:00:01.162974 IP 192.168.129.63.42450 > XX.85.86.223.80: S 1331737569:1331737569(0) win 65535 <mss 1460,nop,wscale 3,nop,nop,timestamp 1482096661 0>
00:00:00.**023962** IP XX.85.86.223.80 > 192.168.129.63.42450: S 3130510306:3130510306(0) ack 1331737570 win 65535 mss 1460,nop,wscale 2,nop,nop,timestamp 1482096106 1482096661,nop,opt-14:03>
00:00:00.000025 IP 192.168.129.63.42450 > XX.85.86.223.80: . ack 1 win 32761 <nop,nop,timestamp 1482096661 1482096106>
00:00:00.000062 IP 192.168.129.63.42450 > XX.85.86.223.80: P 1:142(141) ack 1 win 32761 <nop,nop,timestamp 1482096661 1482096106>
00:00:00.**024014** IP XX.85.86.223.80 > 192.168.129.63.42450: . ack 1 win 65522 <nop,nop,timestamp 1482096107 1482096661>

Otra cosa que "me gusta" sobre el uso de tcpdump es que es un programa que generalmente está disponible. No es necesario instalar nada adicional.

Michael sintió
fuente
2
¿Y cómo tiene eso algo que ver con los zócalos Unix?
nonchip el