Eu estou rodando netio ( link ) em uma máquina (opensolaris) e contatando duas máquinas Linux diferentes (ambas em 2.6 .18-128.el5), máquina A e máquina B.
A máquina A tem uma taxa de transferência de rede de 10MB / seg com netio e a máquina B 100MB / seg com netio.
No solaris aberto eu localizei as conexões e todas as interações parecem as mesmas - mesmos tamanhos de janelas no recebimento e envio, mesmo ssthresh, mesmos tamanhos de janela de congestionamento, mas a máquina lenta está enviando e ACK para cada 2 ou 3 recebe enquanto o rápido máquina está enviando um ACK a cada 12 recebe.
Todas as três máquinas estão no mesmo switch.
Aqui está a saída do Dtrace:
Máquina rápida:
delta send recd
(us) bytes bytes swnd snd_ws rwnd rcv_ws cwnd ssthresh
122 1448 \ 195200 7 131768 2 128872 1073725440
37 1448 \ 195200 7 131768 2 128872 1073725440
20 1448 \ 195200 7 131768 2 128872 1073725440
18 1448 \ 195200 7 131768 2 128872 1073725440
18 1448 \ 195200 7 131768 2 128872 1073725440
18 1448 \ 195200 7 131768 2 128872 1073725440
18 1448 \ 195200 7 131768 2 128872 1073725440
19 1448 \ 195200 7 131768 2 128872 1073725440
18 1448 \ 195200 7 131768 2 128872 1073725440
18 1448 \ 195200 7 131768 2 128872 1073725440
57 1448 \ 195200 7 131768 2 128872 1073725440
171 1448 \ 195200 7 131768 2 128872 1073725440
29 912 \ 195200 7 131768 2 128872 1073725440
30 / 0 195200 7 131768 2 128872 1073725440
máquina lenta:
delta send recd
(us) bytes bytes swnd snd_ws rwnd rcv_ws cwnd ssthresh
161 / 0 195200 7 131768 2 127424 1073725440
52 1448 \ 195200 7 131768 2 128872 1073725440
33 1448 \ 195200 7 131768 2 128872 1073725440
11 1448 \ 195200 7 131768 2 128872 1073725440
143 / 0 195200 7 131768 2 128872 1073725440
46 1448 \ 195200 7 131768 2 130320 1073725440
31 1448 \ 195200 7 131768 2 130320 1073725440
11 1448 \ 195200 7 131768 2 130320 1073725440
157 / 0 195200 7 131768 2 130320 1073725440
46 1448 \ 195200 7 131768 2 131768 1073725440
18 1448 \ 195200 7 131768 2 131768 1073725440
código Dtrace
dtrace: 130717 drops on CPU 0
#!/usr/sbin/dtrace -s
#pragma D option quiet
#pragma D option defaultargs
inline int TICKS=$1;
inline string ADDR=$$2;
dtrace:::BEGIN
{
TIMER = ( TICKS != NULL ) ? TICKS : 1 ;
ticks = TIMER;
TITLE = 10;
title = 0;
walltime=timestamp;
printf("starting up ...\n");
}
tcp:::send
/ ( args[2]->ip_daddr == ADDR || ADDR == NULL ) /
{
nfs[args[1]->cs_cid]=1; /* this is an NFS thread */
delta= timestamp-walltime;
walltime=timestamp;
printf("%6d %8d \ %8s %8d %8d %8d %8d %8d %12d %12d %12d %8d %8d %d \n",
delta/1000,
args[2]->ip_plength - args[4]->tcp_offset,
"",
args[3]->tcps_swnd,
args[3]->tcps_snd_ws,
args[3]->tcps_rwnd,
args[3]->tcps_rcv_ws,
args[3]->tcps_cwnd,
args[3]->tcps_cwnd_ssthresh,
args[3]->tcps_sack_fack,
args[3]->tcps_sack_snxt,
args[3]->tcps_rto,
args[3]->tcps_mss,
args[3]->tcps_retransmit
);
flag=0;
title--;
}
tcp:::receive
/ ( args[2]->ip_saddr == ADDR || ADDR == NULL ) && nfs[args[1]->cs_cid] /
{
delta=timestamp-walltime;
walltime=timestamp;
printf("%6d %8s / %8d %8d %8d %8d %8d %8d %12d %12d %12d %8d %8d %d \n",
delta/1000,
"",
args[2]->ip_plength - args[4]->tcp_offset,
args[3]->tcps_swnd,
args[3]->tcps_snd_ws,
args[3]->tcps_rwnd,
args[3]->tcps_rcv_ws,
args[3]->tcps_cwnd,
args[3]->tcps_cwnd_ssthresh,
args[3]->tcps_sack_fack,
args[3]->tcps_sack_snxt,
args[3]->tcps_rto,
args[3]->tcps_mss,
args[3]->tcps_retransmit
);
flag=0;
title--;
}
Acompanhamento adicionado para incluir o número de bytes não reconhecidos e acontece que o código lento percorre seus bytes não reconhecidos até atingir a janela de congestionamento, enquanto a máquina rápida nunca atinge sua janela de congestionamento. Aqui está a saída da máquina lenta quando os bytes não reconhecidos atingem a janela de congestionamento:
unack unack delta bytes bytes send recieve cong ssthresh
bytes byte us sent recieved window window window
sent recieved
139760 0 31 1448 \ 195200 131768 144800 1073725440
139760 0 33 1448 \ 195200 131768 144800 1073725440
144104 0 29 1448 \ 195200 131768 146248 1073725440
145552 0 31 / 0 195200 131768 144800 1073725440
145552 0 41 1448 \ 195200 131768 147696 1073725440
147000 0 30 / 0 195200 131768 144800 1073725440
147000 0 22 1448 \ 195200 131768 76744 72400
147000 0 28 / 0 195200 131768 76744 72400
147000 0 18 1448 \ 195200 131768 76744 72400
147000 0 26 / 0 195200 131768 76744 72400
147000 0 17 1448 \ 195200 131768 76744 72400
147000 0 27 / 0 195200 131768 76744 72400
147000 0 18 1448 \ 195200 131768 76744 72400
147000 0 56 / 0 195200 131768 76744 72400
147000 0 22 1448 \ 195200 131768 76744 72400
código do dtrace:
#!/usr/sbin/dtrace -s
#pragma D option quiet
#pragma D option defaultargs
inline int TICKS=$1;
inline string ADDR=$$2;
tcp:::send, tcp:::receive
/ ( args[2]->ip_daddr == ADDR || ADDR == NULL ) /
{
nfs[args[1]->cs_cid]=1; /* this is an NFS thread */
delta= timestamp-walltime;
walltime=timestamp;
printf("%6d %6d %6d %8d \ %8s %8d %8d %8d %8d %8d %12d %12d %12d %8d %8d %d \n",
args[3]->tcps_snxt - args[3]->tcps_suna ,
args[3]->tcps_rnxt - args[3]->tcps_rack,
delta/1000,
args[2]->ip_plength - args[4]->tcp_offset,
"",
args[3]->tcps_swnd,
args[3]->tcps_snd_ws,
args[3]->tcps_rwnd,
args[3]->tcps_rcv_ws,
args[3]->tcps_cwnd,
args[3]->tcps_cwnd_ssthresh,
args[3]->tcps_sack_fack,
args[3]->tcps_sack_snxt,
args[3]->tcps_rto,
args[3]->tcps_mss,
args[3]->tcps_retransmit
);
}
tcp:::receive
/ ( args[2]->ip_saddr == ADDR || ADDR == NULL ) && nfs[args[1]->cs_cid] /
{
delta=timestamp-walltime;
walltime=timestamp;
printf("%6d %6d %6d %8s / %-8d %8d %8d %8d %8d %8d %12d %12d %12d %8d %8d %d \n",
args[3]->tcps_snxt - args[3]->tcps_suna ,
args[3]->tcps_rnxt - args[3]->tcps_rack,
delta/1000,
"",
args[2]->ip_plength - args[4]->tcp_offset,
args[3]->tcps_swnd,
args[3]->tcps_snd_ws,
args[3]->tcps_rwnd,
args[3]->tcps_rcv_ws,
args[3]->tcps_cwnd,
args[3]->tcps_cwnd_ssthresh,
args[3]->tcps_sack_fack,
args[3]->tcps_sack_snxt,
args[3]->tcps_rto,
args[3]->tcps_mss,
args[3]->tcps_retransmit
);
}
Agora, ainda é uma questão de por que uma máquina fica para trás e a outra não
...