TCP级别的NFS性能问题

I / O对NFS的请求和更具体地与Oracle会发生什么? NFS如何影响性能以及可以提高性能的事情?

当我请求DD的NFS安装文件系统中的DD为8k块双色球计算器时,TCP层会发生什么?

这是一个例子:

我做了一个

dd if = / dev / zer = foo bs = 8k count = 1

当我的输出文件位于NFS安装时,我看到TCP发送并从NFS服务器发送到客户端,如下所示:

(代码在DTrace中,并在服务器端运行,请参阅 TCP.D. for the code)

这个简单的8k请求中有很多活动。什么是沟通?坦率地说,我不确定。我没有看出双色球计算器包的内容,但我猜一些与获取文件属性有关。也许我们将在未来的帖子中进入这些细节。

目前我感兴趣的是吞吐量和延迟以及延迟,概念,难以在花费时间。

我对延迟最感兴趣。我对查询的响应时间发生的事情感兴趣,当它读取NFS的I / O OFF而不是没有NFS的同一磁盘。大多数NFS博客似乎都在解决吞吐量。

在我们跳入实际网络堆栈和操作系统运营延迟之前,让我们来看看双色球计算器传输的物理。

如果我们在1GE上,我们可以在122MB / s中完成Toin理论,但实际上最大值更像是115 MB / s,对于大多数系统100 MB / s很好),因此

100 MB / s
100 KB / MS
每01毫秒1 kb(即10us)

15US(0.015毫秒)传输1500字节的网络双色球计算器包(即MTU或最大传输单元)

1500字节传输具有IP框架,仅传输1448字节的实际双色球计算器

因此,Oracle的8k块将需要5.7个双色球计算器包,其中舍入为6个双色球计算器包

每个双色球计算器包需要15us,所以8k的6个双色球计算器包需要90us(有趣的是,这部分转移到10GE上的9US - 如果全部完美地工作)

现在一个良好的调整8K转移需要大约350us(从测试,更稍后更多),所以另一个〜260美国来自哪里? (260us + 90us传输时间= 350us总延迟)

好吧,如果我看上面的图表,总转移时间从开始完成时需要4776美元(或4.7ms),但这种转移有很多建立。

实际的8K传输(5 x 1448字节双色球计算器包加上1088字节双色球计算器包)需要780 US或大约两倍,只要最佳。

 

比较好的吞吐量吞吐量

我没有答案到以下两台机器之间的TCP性能差异,但以为我会张贴我认为我认为这是有趣的,也许别人有想法。
我正在运行netio(http://freshmeat.net/projects/netio/)在一台机器(OpenSolaris)上并接触两个不同的Linux机器(两者在2.6.18-128.el5),机器A和机B.
机器A具有10MB / SEC的网络吞吐量,带有Netio和机器B 100MB / SEC。 Netio设置为发送32K块:

Linux.机器:Netio -s -b 32k -t -p 1234
OpenSolaris:Netio -b 32k -t -p 1234 Linuxmachine

在OpenSolaris机器上,我使用DTrace来跟踪连接。从DTRACE,所有交互TCP设置都看起来与接收和发送相同的Windows大小相同,同样的SSTHRESH,相同的拥塞窗口大小,但慢速机器每2或3个接收到每2或3的ACK,而快速机器正在发送每12个接收一次。
所有三台机器都在同一开关上。

以下是DTrace输出:

快机:

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

慢机:

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

DTrace Code.

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--;
}

后续,自从我做到了上面,我已经改变了DTrace代码来包括未被判建的字节的数量,而且它掉了慢速代码,它会恢复它是未甲基的字节,直到它击中拥塞窗口,在速机中从未击中它拥塞窗口:

unack    unack    delta  bytes   bytes       send   receive  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

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
      );
}

因此,它看起来像慢速机器的事实每隔一秒或第三次发送是因为接收者已经落后于确认先前的双色球计算器包。

现在问题仍然是为什么接收者到目前为止一台机器落后于另一台机器。

我已经检查了两台机器上的RMEM值并将其设置为同样:

net.core.rmem_default = 4194304
net.core.rmem_max = 4194304.

我展示了一些代码,将在Solaris 10上显示的发送和接收大小和TCP的时间与DTrace命令(见 TCP.D. 对于代码)。我在另一台机器上拍了这个代码,并获得错误

“DTRACE:启用探测器ID 29的错误(ID 5461:TCP:IP:TCP_INPUT_DATA:接收):DIF偏移136谓词中的谓词无效对齐(0xFFFFFF516EB5E83A)”

不确定为什么会发生这种情况,而是通过消除过程,我发现在TCP :::接收中访问args [4]导致这些错误。

幸运的是,args [4]中的许多值也在args [3]中找到。

要找到TCP :::接收的参数,首先运行以下命令(或者在Wiki上查看TCP探测http://wikis.sun.com/display/DTrace/tcp+Provider)

(对于命令行标志退房 http://compute.cnr.berkeley.edu/cgi-bin/man-cgi?dtrace+7

  • -l =列表而不是启用探针
  • -n =指定追踪或列表的探针名称
  • -v =设置冗长模式

即,列出有关命名探针的详细信息,并不启用这些探测器,只需列出它们)

$ dtrace -lvn tcp:::receive
 5473        tcp                ip                        tcp_output send

        Argument Types
                args[0]: pktinfo_t *
                args[1]: csinfo_t *
                args[2]: ipinfo_t *
                args[3]: tcpsinfo_t *
                args[4]: tcpinfo_t *

(顺便说一下,有许多谓词匹配TCP :::接收,但它们都有相同的参数,我没有注意到所有这些不同的TCP :::接收,直到我实际运行上面的命令。在运行之前我依赖于维基的命令。现在我想知道这些TCP :::接收和TCP :::发送探针之间的区别是什么区别

找到探测器的args后,您可以查找结构的定义  http://cvs.opensolaris.org/source/

TCP :::发送和TCP :::接收既具有相同的参数

  • args [3]是tcpsinfo_t
  • args [4]是tcpinfo_t

仰望结构 http://cvs.opensolaris.org/source/,我发现结构的内容如下:

tcpsinfo_t(args [3])

     111 typedef struct tcpsinfo {
    112 	uintptr_t tcps_addr;
    113 	int tcps_local;			/* is delivered locally, boolean */
    114 	int tcps_active;		/* active open (from here), boolean */
    115 	uint16_t tcps_lport;		/* local port */
    116 	uint16_t tcps_rport;		/* remote port */
    117 	string tcps_laddr;		/* local address, as a string */
    118 	string tcps_raddr;		/* remote address, as a string */
    119 	int32_t tcps_state;		/* TCP state */
    120 	uint32_t tcps_iss;		/* Initial sequence # sent */
    121 	uint32_t tcps_suna;		/* sequence # sent but unacked */
    122 	uint32_t tcps_snxt;		/* next sequence # to send */
    123 	uint32_t tcps_rack;		/* sequence # we have acked */
    124 	uint32_t tcps_rnxt;		/* next sequence # expected */
    125 	uint32_t tcps_swnd;		/* send window size */
    126 	int32_t tcps_snd_ws;		/* send window scaling */
    127 	uint32_t tcps_rwnd;		/* receive window size */
    128 	int32_t tcps_rcv_ws;		/* receive window scaling */
    129 	uint32_t tcps_cwnd;		/* congestion window */
    130 	uint32_t tcps_cwnd_ssthresh;	/* threshold for congestion avoidance */
    131 	uint32_t tcps_sack_fack;	/* SACK sequence # we have acked */
    132 	uint32_t tcps_sack_snxt;	/* next SACK seq # for retransmission */
    133 	uint32_t tcps_rto;		/* round-trip timeout, msec */
    134 	uint32_t tcps_mss;		/* max segment size */
    135 	int tcps_retransmit;		/* retransmit send event, boolean */

tcpinfo_t(args [4])

     95 typedef struct tcpinfo {
     96 	uint16_t tcp_sport;		/* source port */
     97 	uint16_t tcp_dport;		/* destination port */
     98 	uint32_t tcp_seq;		/* sequence number */
     99 	uint32_t tcp_ack;		/* acknowledgment number */
    100 	uint8_t tcp_offset;		/* data offset, in bytes */
    101 	uint8_t tcp_flags;		/* flags */
    102 	uint16_t tcp_window;		/* window size */
    103 	uint16_t tcp_checksum;		/* checksum */
    104 	uint16_t tcp_urgent;		/* urgent data pointer */
    105 	tcph_t *tcp_hdr;		/* raw TCP header */
    106 } tcpinfo_t;

在脚本中,我访问了arg [4]中的TCP SEQ和ACK,它在TCP :::接收中给了我错误,所以我只需在arg [3]中的等价物切换这些。现在我并不完全清楚等价,但似乎

  • args [4] - >tcp_seq  ?= args[3]->tcps_suna
  • args [4] - >tcp_ack  ?= args[3]->tcps_rack

ACK =机架似乎是TCPS_RACK =“我们已收到并发送确认的最高序列号”。

SEQ = TCPS_SUNA对我不太清楚,因为TCPS_SUNA =“我们已发送双色球计算器但未收到确认的最低序列号”

但是,为了我的目的,随着我停止看SEQ和ACK的,这些区别可能是不重要的,现在看看接收者和发件人的出色的未经承认字节,这是

  • TCPS_SNXT-TCPS_SUNA“给出了待处理确认的字节数”
  • tcps_rsnxt - tcps_rack“给出了我们收到但尚未承认的字节数”

但更稍后更多。让我们来看看程序的新版本和输出

#!/usr/sbin/dtrace -s
#pragma D option defaultargs
#pragma D option quiet
inline string ADDR=$$1;
dtrace:::BEGIN
{       TITLE = 10;
       title= 0;
       walltime=timestamp;
       printf("starting up ...n");
}
tcp:::send, tcp:::receive
/   title== 0 /
{   printf("%9s %8s %6s %8s %8s %12s %s n",
        "delta"    ,
        "cid"    ,
        "pid"    ,
        "send" ,
        "recd"  ,
        "seq",
        "ack"
      );
     title=TITLE;
}
tcp:::send
/     ( args[3]->tcps_raddr == ADDR || ADDR == NULL ) /
{    nfs[args[1]->cs_cid]=1; /* this is an NFS thread */
    delta= timestamp-walltime;
    walltime=timestamp;
    printf("%9d %8d %6d %8d --> %8s %8d %8d %12s > %s n",
        delta/1000,
        args[1]->cs_cid  % 100000,
        args[1]->cs_pid ,
        args[2]->ip_plength - args[4]->tcp_offset,
        "",
        args[4]->tcp_seq  -
        args[3]->tcps_suna ,
        args[4]->tcp_ack -
        args[3]->tcps_rack ,
        args[3]->tcps_raddr,
        curpsinfo->pr_psargs
      );
    title--;
}
tcp:::receive
/ ( args[3]->tcps_raddr == ADDR || ADDR == NULL ) && nfs[args[1]->cs_cid] /
{     delta=timestamp-walltime;
      walltime=timestamp;
      printf("%9d %8d %6d %8s <-- %-8d %8d %8d %12s < %s n",
        delta/1000,
        args[1]->cs_cid  % 100000,
        args[1]->cs_pid ,
        "",
        args[2]->ip_plength - args[4]->tcp_offset,
        args[3]->tcps_rack % 10000,
        args[3]->tcps_suna % 10000,
        args[3]->tcps_raddr,
        curpsinfo->pr_psargs
      );
    title--;
}

输出

starting up ...
    delta      cid    pid     send     recd
      570     3904    845          <-- 0
       34     3904    845          <-- 140
      455     3904    845          <-- 0
       24     3904    845          <-- 0
  4789720     3904    845      124 -->
       82     3904    845      244 -->
       99     3904    845      132 -->
    delta      cid    pid     send     recd
       52     3904    845     1448 -->
       28     3904    845     1448 -->
       24     3904    845     1448 -->
       36     3904    845     1448 -->
       33     3904    845     1448 -->
       26     3904    845      952 -->
       86     3904    845      244 -->
      212     3904    845          <-- 140
      501     3904    845          <-- 132
       60     3904    845      124 -->
      256     3904    845          <-- 140
       72     3904    845          <-- 0
    39658     3904    845          <-- 0

哎呀,大大时间4789720我们? IE 4秒?整个操作花了我不到1秒。
没有Adam Levanthal的帮助,我不会找到答案。事实证明,输出仅按CPU按顺序排列,但不同的CPU可以以不同的顺序输出双色球计算器。每个CPU缓冲双色球计算器然后将缓冲区传递回userland dtrace,所以在一个CPU机器上,此代码将始终按顺序输出,但在多CPU机器上没有GuAlentee在输出的顺序上。让我们将CPU#添加到输出:

#!/usr/sbin/dtrace -s
#pragma D option defaultargs
#pragma D option quiet
inline string ADDR=$$1;
dtrace:::BEGIN
{       TITLE = 10;
       title= 0;
       walltime=timestamp;
       printf("starting up ...n");
}
tcp:::send, tcp:::receive
/   title== 0 /
{   printf("%9s %8s %6s %8s %8s %4s n",
        "delta"    ,
        "cid"    ,
        "pid"    ,
        "send" ,
        "recd"  ,
        "cpu#"
      );
     title=TITLE;
}
tcp:::send
/     ( args[3]->tcps_raddr == ADDR || ADDR == NULL ) /
{    nfs[args[1]->cs_cid]=1; /* this is an NFS thread */
    delta= timestamp-walltime;
    walltime=timestamp;
    printf("%9d %8d %6d %8d --> %8s %d n",
        delta/1000,
        args[1]->cs_cid  % 100000,
        args[1]->cs_pid ,
        args[2]->ip_plength - args[4]->tcp_offset,
        "",
        cpu
      );
    title--;
}
tcp:::receive
/ ( args[3]->tcps_raddr == ADDR || ADDR == NULL ) && nfs[args[1]->cs_cid] /
{     delta=timestamp-walltime;
      walltime=timestamp;
      printf("%9d %8d %6d %8s <-- %-8d %d n",
        delta/1000,
        args[1]->cs_cid  % 100000,
        args[1]->cs_pid ,
        "",
        args[2]->ip_plength - args[4]->tcp_offset,
        cpu
      );
    title--;
}

输出

  delta      cid    pid     send     recd cpu#
       42     3904    845      244 -->          0
       66     3904    845      124 -->          0
     6091     3904    845      124 -->          2
       81     3904    845      244 -->          2
       96     3904    845      132 -->          2
       31     3904    845     1448 -->          2
       20     3904    845     1448 -->          2
       18     3904    845     1448 -->          2
       17     3904    845     1448 -->          2
       16     3904    845     1448 -->          2
  8910406     3904    845        0 -->          3
      375     3904    845          <-- 0        3
       24     3904    845          <-- 140      3
       34     3904    845        0 -->          3
      470     3904    845          <-- 140      3
      410     3904    845          <-- 132      3
    delta      cid    pid     send     recd cpu#
      491     3904    845          <-- 140      3
      393     3904    845          <-- 0        3
       15     3904    845      952 -->          3
       36     3904    845          <-- 0        3
    delta      cid    pid     send     recd cpu#
       19     3904    845          <-- 0        3
    40167     3904    845          <-- 0        3

我们看到的是CPU订购的双色球计算器。换句话说,每个CPU都订购了双色球计算器,但首先打印的CPU是未知的。在DTrace中,每个CPU缓冲它的双色球计算器,然后将其发送到Userland DTrace进程。
现在唯一的“修复”是添加时间戳并按时间戳订购双色球计算器。
未缺陷,看起来像:

607858102997348       281     3904    845      124 -->          2
607858103608856        84     3904    845      244 -->          2
607858104125414     delta      cid    pid     send     recd cpu#
607858104143731       116     3904    845      132 -->          2
607858104176769        33     3904    845     1448 -->          2
607858104198187        21     3904    845     1448 -->          2
607858104215813        17     3904    845     1448 -->          2
607858104233004        17     3904    845     1448 -->          2
607858104267629        34     3904    845     1448 -->          2
607858104287379        19     3904    845      952 -->          2
607858102716187  11569935     3904    845          <-- 132      3
607858103245377       248     3904    845          <-- 0        3
607858103282421        37     3904    845          <-- 140      3
607858103339076        56     3904    845      244 -->          3
607858103524093       185     3904    845          <-- 140      3
607858103774417       165     3904    845          <-- 132      3
607858103823145        48     3904    845      124 -->          3
607858104027216       204     3904    845          <-- 140      3
607858104387780       100     3904    845          <-- 0        3
607858104401487        13     3904    845          <-- 0        3
607858104520815       119     3904    845          <-- 0        3
607858144436175     delta      cid    pid     send     recd cpu#
607858144454625     39933     3904    845          <-- 0        3

他们看起来像

607858102716187  11569935     3904    845          <-- 132      3
607858102997348       281     3904    845      124 -->          2
607858103245377       248     3904    845          <-- 0        3
607858103282421        37     3904    845          <-- 140      3
607858103339076        56     3904    845      244 -->          3
607858103524093       185     3904    845          <-- 140      3
607858103608856        84     3904    845      244 -->          2
607858103774417       165     3904    845          <-- 132      3
607858103823145        48     3904    845      124 -->          3
607858104027216       204     3904    845          <-- 140      3
607858104125414     delta      cid    pid     send     recd cpu#
607858104143731       116     3904    845      132 -->          2
607858104176769        33     3904    845     1448 -->          2
607858104198187        21     3904    845     1448 -->          2
607858104215813        17     3904    845     1448 -->          2
607858104233004        17     3904    845     1448 -->          2
607858104267629        34     3904    845     1448 -->          2
607858104287379        19     3904    845      952 -->          2
607858104387780       100     3904    845          <-- 0        3
607858104401487        13     3904    845          <-- 0        3
607858104520815       119     3904    845          <-- 0        3
607858144436175     delta      cid    pid     send     recd cpu#
607858144454625     39933     3904    845          <-- 0        3

所以现在奇怪的长时间三角洲在我期待它的开始。

我不太确定如何处理这个问题。通过对时间戳列进行分类,处理双色球计算器的后处理,但交互地处理双色球计算器,以便在正确的顺序中获取它似乎有问题。

 

巨型框架

巨型帧可能对延迟产生重大影响,但巨型帧通常很困难。在机器上实现JUMBO帧可能导致机器网络通信挂起,如果机器或打开该连接不会’t支持巨型框架。修改开关以支持Jumbo帧通常需要将开关脱机,这可能是不可行的。

下面是标准MTU的1500字节和巨型帧MTU的标准MTU之间的比较。在n个本例中,Jumbo帧连接是快速的两倍。

屏幕截图2014-05-07在11.38.29 AM

3 thoughts on “TCP级别的NFS性能问题

  • 2014年5月7日在上午1:33
    永久链接

    我认为使用吞吐量除以块作为延迟测量的基础目标,以危险充满了延迟。
    吞吐量只是作为一定量的双色球计算器从A到B的速度进行测量。它省略了所有其他双色球计算器“niceties”MTU的TCP / IP是最相关的。
    当我们处理1KB / 10US潜在的时间框架时,像实际控制器硬件可以确认和后续的速度一样,每个MTU块都变得非常相关。在网卡控制器中使用CPU循环速度,10US是正确的(不,它们不是英特尔酷睿i7s…)在参加下一个周期之前,需要相当多的周期来处理每个MTU。

    大型框架(较大的MTU)网络配置的影响在这里不能夸大。如果该目的是传输大量双色球计算器,则更大的帧使MTU处理时间的干扰较少在整体时间内。虽然在纯延迟术语(对少量传输双色球计算器的最快响应)中,标准MTU远远不可取。相互冲突的要求!

    让’否则忘记,选择1400 MTU的整体目的是当默认大小的默认大小恢复到它的时间过去,当块大小为512字节时“huge”!
    现在远远超过了,但很少发生变化。此处或多或少的推断作为现代趋势到磁盘扇区块尺寸为4k而不是512字节–尺寸是SCSI技术的第一天,与当前双色球计算器和磁盘尺寸完全不成比例。使用巨大页面的背后也是相同的推理,以避免TLA延迟虚拟内存分页。

    感谢一个非常思想的挑衅性帖子,非常感谢。

  • 2014年5月7日晚上7:32
    永久链接

    嗨nons,
    谢谢你停下来。是的,巨型框架可以产生很大的不同。发布您的评论后,我添加了一个和没有巨型帧的示例,以展示通信如何变化以及它影响延迟的程度。在特定情况下,Jumbo帧的速度快两倍。

  • 2014年5月8日在上午12:03
    永久链接

    的确。感谢更新。但是,用巨型框架谨慎一句话。
    遗憾的是,当我们将DB服务器设置为单独的VLAN时,我去年遭到了这个,并且在其中的防火墙中。
    当使用Jumbo帧时,并非所有路由器,桥梁和防火墙都可以正常运行。很多功能都减少了。和CNAMES这样的事情,如此难以变得更加艰难。
    网络仍然在胚胎阶段,灵活的框架尺寸,并且有很多“hidden features”(如果你抓住我的漂移)当普通的普通vanilla mtu设置外的一个步骤。
    远非说法“do not use them”, 尽管。简单地警告它可能导致意外的侧面。

评论被关闭。