Presa unix locale: idea approssimativa della velocità effettiva


10

Qualcuno è a conoscenza di benchmark / misurazioni della velocità effettiva per l'utilizzo di un socket unix locale per la comunicazione tra processi?

Voglio illustrare il vantaggio in termini di prestazioni di avere un'istanza di database locale sullo stesso server del software che richiede i dati dal database invece di dover comunicare su un collegamento di rete, in particolare uno come Gigabit Ethernet che mi aspetto sia piuttosto lento relativamente parlando.

Durante la ricerca online ho trovato alcuni parametri di riferimento che mostrano il numero di operazioni al secondo, ma non il throughput al secondo (ovvero 12 GB / s).

Capisco che le prestazioni varieranno a causa di cose come forse il throughput di memoria su un determinato sistema o altre caratteristiche hardware, ma è necessaria solo un'idea approssimativa.

Questo non si riferisce alle prestazioni TCP locali o ad un confronto con quello.


Voi siete , in realtà, facendo riferimento a prestazioni locali di rete TCP vs.. È anche la cosa sbagliata da misurare nel tuo scenario.
Satō Katsura,

@SatoKatsura Mi riferisco a en.wikipedia.org/wiki/Unix_domain_socket
sa289,

Sì. E come pensi che i socket di dominio UNIX siano effettivamente implementati?
Satō Katsura,

@SatoKatsura Non sono sicuro, ma c'è qualche differenza in base a ciò che ho letto anche se non è diverso giorno e notte. Inoltre ci sono benchmark che confrontano i socket di dominio unix locali con i socket TCP locali che mostrano una differenza significativa nelle prestazioni.
Sa289,

Inoltre ci sono benchmark che confrontano i socket di dominio unix locali con i socket TCP locali che mostrano una differenza significativa nelle prestazioni. - Puoi indicare uno di questi parametri?
Satō Katsura,

Risposte:


19

È possibile utilizzare socat per un semplice test di velocità socket UNIX.

Di seguito sono riportati i risultati che ottengo sul mio laptop:

#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 su disco (SSD), tramite socket 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 in memoria, tramite socket 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 su / dev / null (scarta), tramite 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, tramite 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

Come puoi vedere, anche il throughput di test della "memoria su disco" è 545 MB / s (ovvero ~ 4360 MiB / s), che è molto più avanti di un throughput teorico massimo per la connessione ethernet da 1 GB (che è ~ 1000/8 = 125 MB / s, nemmeno considerando eventuali costi generali del protocollo).

PS

Si noti che questo è solo un semplice test che utilizza alcuni strumenti semplici e non un vero e proprio benchmark.


1
Come ho detto di seguito, non confondere la larghezza di banda con la velocità effettiva. socat ti dirà la larghezza di banda in condizioni "ideali", ti dirà se la banda teorica non viene raggiunta - ma non ti dirà nulla sui ritardi che causano il rallentamento dell'applicazione. Confronta i / o del disco a 8 Gbit - stress test. Questo è il massimo che puoi ottenere, qualunque sia X. Se l'applicazione raggiunge che "il supporto" potrebbe essere il collo di bottiglia. Se l'applicazione non raggiunge quel livello, il "collo di bottiglia" non è il supporto. Se socat raggiunge il massimo a 1 Gbit, ma l'app non lo fa - socat non mi dice cosa sta limitando il "throughput".
Michael Felt,

3

La mia "risposta" è lunga - la loro chiave è non confondere 'throughput' con 'larghezza di banda' - sebbene 'larghezza di banda' possa essere un fattore limitante

In breve, la velocità effettiva potrebbe essere limitata anche se la larghezza di banda non è satura.


Ho dovuto aiutare le persone a comprendere l'impatto degli stack di applicazioni multilivello.

Per l'aspetto delle comunicazioni TCP faccio uso delle differenze di RTT (round-trip-time).

Per livello singolo è possibile confrontare l'indirizzo IP locale (su una scheda NIC) con lo0 (loopback).

Per multi-tier si confrontano / calcolano gli indirizzi "più distanti", ad es. Multi-tier può essere due VM nello stesso host oppure potrebbe essere host diverso nello stesso datacenter oppure potrebbero trovarsi in data center diversi (forse a soli 500 metri di distanza, ma comunque diverso).

Cordiali saluti: per molte applicazioni le differenze RTT sono trascurabili, ma per le applicazioni che fanno 10-100 di migliaia di piccoli messaggi per il tempo RTT delle applicazioni può diventare un collo di bottiglia.

(Ho visto situaltions in cui il "batch impiegava quasi 6 ore in più in multi-tier quando il RTT era di 0,25 millisec più lungo, rispetto al single-tier)

Quindi, semplice banco di prova:

Il

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

E il mio programma di monitoraggio è tcpdump - con l'opzione -ttt

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

Un microsecondo è un'unità di tempo SI pari a un milionesimo (0,000001 o 10−6 o 1 / 1.000.000). Cioè, 1000 microsecondi == 1 millisecondo.

Quindi, in due finestre diverse ho tcpdump in esecuzione:

Per i tempi "locali": tcpdump -i lo0 -n -ttt port 80 E per il "remoto" tcpdump -I en1 -n -ttt port 80

Nei dati seguenti, l'obiettivo non è fare alcuna analisi, ma mostrare come identificare le "differenze" nel tempo necessario per il completamento delle transazioni. Quando il throughput di un'applicazione è una transazione seriale, il throughput per "sec | min | hour" è influenzato dal tempo totale richiesto per le "risposte". Ho trovato questo il modo più semplice per spiegare usando il concetto di RTT - round-trip-time.

Per una vera analisi ci sono cose aggiuntive da guardare. Quindi, le uniche righe che mostrerò sono l'handshake TCP iniziale, il primo pacchetto in uscita e l'ACK di ritorno. Per il confronto, confrontare i tempi delta di quanto tempo prima che la "risposta" ritorni.

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

nota 01.XXXXXX - per un secondo di sospensione sull'interfaccia "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

macchina virtuale nello stesso host - notare che l'ora inizia a 00.000000 - viene visualizzato il primo pacchetto (e 01.XXXXXX per gli altri due indirizzi di seguito)

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

il mio router - esterno all'host, non una macchina virtuale.

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

stessa connessione di 192.168.129.72, ma è "occupato" mentre "72" è inattivo. Spero che le strette di mano iniziali siano quasi identiche

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>

luppolo multiplo

questo è lo stesso host, lo stesso risultato apache, ma ora tramite l'interfaccia esterna (6 hop IP, piuttosto che diretto) - ora puoi ottenere l'effetto della RTT a lunga distanza. (ps, ho modificato leggermente l'indirizzo IP). Ancora più importante: notare che ci sono due pacchetti in uscita dopo la stretta di mano iniziale prima del primo ACK dopo la restituzione di una stretta di mano.

Quindi, piuttosto che 25msec RTT, pensa che RTT sia di 250 microsecondi, rispetto a 25 microsecondi - e hai 500k transazioni (che arriva a solo 120-125 secondi in più rispetto al locale, e il throughput è, per così dire, comparabile. Ma con 50 milioni di transazioni (come avevo fatto in una situazione di vita reale) guadagni altri 12500 secondi - il che aggiunge circa 3,5 ore aggiuntive per "letteralmente" lo stesso lavoro. (E parte della soluzione per questo caso era di ingrandire i pacchetti - il la dimensione media era originariamente di 400-450 byte).

Ricordiamo, quello che voglio mostrare qui è un modo abbastanza semplice per tenere conto delle differenze nel tempo complessivo per il completamento di un'applicazione (processo batch) quando si confrontano architetture a più livelli con architetture a livello singolo.

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>

Un'altra cosa che mi piace dell'utilizzo di tcpdump è che è un programma generalmente disponibile. Non è necessario installare nulla in più.


2
e che c'entra qualcosa con i socket unix?
Nonch
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.