Soquete unix local - ideia aproximada de taxa de transferência

10

Alguém está ciente das referências / medições de taxa de transferência para usar um soquete unix local para comunicação entre processos?

Quero ilustrar o benefício de desempenho de ter uma instância de banco de dados local no mesmo servidor que o software que está solicitando os dados do banco de dados vs. ter que se comunicar por um link de rede, especialmente um como Ethernet de gigabit, que espero ser bastante lento relativamente falando.

Ao pesquisar on-line, encontrei alguns parâmetros que mostram o número de operações por segundo, mas não a taxa de transferência por segundo (ou seja, 12 GB / s).

Entendo que o desempenho variará devido a coisas como talvez a taxa de transferência de memória em um determinado sistema ou outras características de hardware, mas apenas uma idéia aproximada é necessária.

Isso não se refere ao desempenho local do TCP ou uma comparação com isso.

sa289
fonte
Na verdade, você está se referindo ao desempenho TCP local versus rede. Também é a coisa errada a ser medida no seu cenário.
Satō Katsura
@SatoKatsura Estou me referindo a en.wikipedia.org/wiki/Unix_domain_socket
sa289
Sim. E como você acha que os soquetes de domínio UNIX são realmente implementados?
Satō Katsura
@SatoKatsura Não tenho certeza, mas há alguma diferença com base no que li, mesmo que não seja dia e noite diferentes. Também existem benchmarks comparando soquetes de domínio unix local com soquetes TCP locais, que mostram uma diferença significativa de desempenho.
sa289
Também existem benchmarks comparando soquetes de domínio unix local com soquetes TCP locais, que mostram uma diferença significativa de desempenho. - Você pode apontar para um desses benchmarks?
Satō Katsura

Respostas:

19

Você pode usar o socat para um teste simples de velocidade do soquete UNIX.

Abaixo estão os resultados que recebo no meu 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

Memória em disco (SSD), através do soquete 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

Memória para memória, através do soquete 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

Memória para / dev / null (descarte), através do soquete 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, através do soquete 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 você pode ver, a taxa de transferência de teste de "memória para disco" é de 545 MB / s (ou seja, ~ 4360MiB / s), muito acima da taxa de transferência teórica máxima para a conexão Ethernet de 1 GB (que é ~ 1000/8 = 125 MB / s, nem mesmo considerando qualquer sobrecarga de protocolo).

PS

Observe que este é apenas um teste simples, usando algumas ferramentas simples, e não uma referência real e adequada .

zepelim
fonte
1
Como digo abaixo - não confunda largura de banda com taxa de transferência. O socat informará a largura de banda em condições "ideais", informará se a largura de banda teórica não está sendo alcançada - mas não informará nada sobre atrasos que causam lentidão no aplicativo. Compare a E / S de disco em 8Gbit - teste de estresse. Esse é o máximo que você pode obter - seja qual for o X. Se o aplicativo atingir que "a mídia" pode ser seu gargalo. Se o aplicativo não atingir esse nível - o "gargalo" não é a mídia. Se o socat atinge o máximo de 1 Gbit, mas o aplicativo não - o socat não me diz o que está limitando a "taxa de transferência".
Michael Felt
3

Minha "resposta" é longa - a chave é não confundir 'taxa de transferência' com 'largura de banda' - embora 'largura de banda' possa ser um fator limitante

Em resumo, sua taxa de transferência pode ser limitada, mesmo que sua largura de banda não esteja saturada.


Eu tive que ajudar as pessoas a entender o impacto das pilhas de aplicativos de várias camadas.

Para o aspecto das comunicações TCP, uso diferenças no RTT (tempo de ida e volta).

Para camada única, você pode comparar o endereço IP local (em uma NIC) com lo0 (loopback).

Para multicamadas, você compara / computa os endereços "mais distantes"; por exemplo, multicamada pode ser duas VM no mesmo host ou diferentes hosts no mesmo datacenter ou em diferentes datacenters. (talvez apenas a 500 metros de distância, mas ainda diferente).

FYI: para muitos aplicativos, as diferenças de RTT são desprezíveis, mas para aplicativos que fazem de 10 a 100 de milhares de pequenas mensagens para o tempo de RTT do aplicativo podem se tornar um gargalo.

(Vi situações em que o lote "demorou quase 6 horas a mais em várias camadas quando o RTT era 0,25 milissegundo a mais, em comparação com a camada única)

Então, cama de teste simples:

o

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 meu programa de monitoramento é o tcpdump - com a opção -ttt

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

Um microssegundo é uma unidade de tempo do SI igual a um milionésimo (0,000001 ou 10−6 ou 1 / 1.000.000). Ou seja, 1000 microssegundos == 1 milissegundo.

Então, em duas janelas diferentes eu tenho o tcpdump em execução:

Para os horários "locais": porta 80 tcpdump -i lo0 -n -ttt E para a porta 80 "tcpdump -I en1 -n -ttt" remota "

Nos dados abaixo - o objetivo não é fazer nenhuma análise, mas mostrar como você pode identificar 'diferenças' no tempo necessário para a conclusão das transações. Quando uma taxa de transferência de aplicativo é uma transação serial - a taxa de transferência por "s | min | hora" é afetada pelo tempo total necessário para "respostas". Achei isso mais fácil de explicar usando o conceito de RTT - tempo de ida e volta.

Para uma análise real, há coisas adicionais a serem observadas. Portanto, as únicas linhas que mostrarei são o handshake TCP inicial e o primeiro pacote de saída e o ACK de retorno. Para a comparação, compare os tempos delta de quanto tempo antes da "resposta" voltar.

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

observe o 01.XXXXXX - por um segundo de suspensão na interface "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 no mesmo host - observe que o horário começa em 00.000000 - primeiro pacote exibido (e 01.XXXXXX nos outros dois endereços abaixo)

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

meu roteador - fora do host, não uma 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

mesma conexão que 192.168.129.72, mas está 'ocupado' enquanto '72' está ocioso. Eu espero que os apertos de mão iniciais sejam quase 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últiplos

este é o mesmo host, o mesmo resultado apache, mas agora via interface externa (6 saltos de IP, em vez de direto) - agora você pode ter o efeito de RTT de longa distância. (ps, modifiquei um pouco o endereço IP). Mais importante - observe que existem dois pacotes de saída após o handshake inicial antes do primeiro ACK após o retorno de um handshake.

Portanto, em vez do RTT de 25 ms, pense que o RTT é de 250 microssegundos, comparado a 25 microssegundos - e você tem transações de 500 mil (isso representa apenas 120 a 125 segundos a mais em comparação com o local, e o rendimento é, na verdade, comparável). Com transações de 50 milhões (como na situação real), você ganha 12500 segundos adicionais - o que adiciona cerca de 3,5 horas adicionais para "literalmente" o mesmo trabalho. (E parte da solução nesse caso era aumentar os pacotes - o o tamanho médio era originalmente de 400 a 450 bytes).

Lembre-se, o que eu quero mostrar aqui é uma maneira bastante simples de explicar as diferenças no tempo geral para um aplicativo (trabalho em lotes) concluir ao comparar arquiteturas multicamadas com arquiteturas de camada única.

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>

Outra coisa que eu "gosto" de usar o tcpdump é que é um programa geralmente disponível. Nada extra precisa ser instalado.

Michael Felt
fonte
2
e como isso tem algo a ver com soquetes unix?
nonchip