searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

使用iperf3进行CTyunOS网络参数优化

2024-07-24 09:43:45
48
0

一、理解TCP缓冲区

        为了更好地理解TCP缓冲区是如何工作的,让我们研究这样一个场景:“应用程序A”(客户端)希望通过TCP将数据发送给应用程序B”(服务器)(如下所示)

 

发送方

        在上图中,我们可以看到应用程序A想要向应用程序B发送4000字节的数据。要做到这一点,应用程序A将使用write()send()系统调用将数据附加套接字(socket)。从应用程序的角度来看,数据已经被写入套接字,但实际上数据首先被追加到该套接字的Send Buffer中。一旦数据在发送缓冲区中可用,内核将把数据分解成一个或多个TCP包。通常,Linux系统上一个包的默认大小是1500字节,前24字节(包含扩展选项)TCP包头;这意味着单个数据包可以容纳1476字节的应用程序数据。要发送4000字节的应用程序数据,内核需要发送三个包。

        作为一个应用程序,我们不关心一个数据包中包含多少数据。应用程序将数据写入缓冲区。内核从缓冲区中获取数据并将其发送到目标系统,不管这个过程中需要多少数据包。

        内核还会将应用程序数据保存在发送缓冲区中,直到服务器确认发送的数据包。它这样做是为了在包丢失的情况下需要重新传输包。

接收方

        在服务器上,存在另一个称为接收缓冲区的缓冲区。当内核接收并处理数据包时,来自这些数据包的数据被写入接收缓冲区。

        正如应用程序不关心发送缓冲区一样,应用程序也不会和接收缓冲区进行交互。通常,应用程序将使用recv()系统调用从套接字读取数据。但实际上,应用程序是从套接字的接收缓冲区读取可用数据。

增加缓冲区大小

        发送和接收缓冲区的大小是可调的; 它们可以在Linux中通过修改/etc/sysctl.conf文件进行调整。要查看当前值,我们将使用sysctl命令。

 $ sysctl net.ipv4.tcp_wmem

net.ipv4.tcp_wmem = 4096 16384 4194304 

从上面的命令输出中,我们可以看到当前存在三个值。

        第一个4096 (4KB)是最小缓冲区大小。默认情况下,这个最小值设置为与系统页大小相同的大小。设置这个最小值是为了确保即便在低内存机器上或者存在内存压力情况下也有缓存。

        第二个值16384 (16KB)是默认大小。系统上的所有TCP套接字缓冲区默认大小。值得注意的注意是net.ipv4.tcp_wmem将覆盖net.core.wmem_default, net.core.wmem_default是所有网络协议(TCP, UDP)的默认发送缓冲区大小。

        第三个值4194304 (4MB)是最大缓冲区大小。与默认大小不同,该值不能覆盖net.core.wmem_max

        当建立新的TCP连接时,将使用默认值(16KB)创建一个发送缓冲区; 然后,缓冲区大小将根据需要和使用情况自动在最大和最小边界内进行调整。

        对于大多数情况,调整最大值就足够了,很少需要更改默认值或最小值。

调整发送缓冲区

        要更改发送缓冲区大小,可以再次使用sysctl命令。

$ sysctl -w net.ipv4.tcp_wmem="4096 16384 8388608"

        上面的命令将发送缓冲区调整为8 MB; 但是,在重新启动后,更改会丢失。要使此更改持久化,我们可以将更改添加到/etc/sysctl.conf文件中。

调整接收缓冲区

        接收缓冲区也是可调的,就像发送缓冲区一样。要查看当前值,可以使用sysctl命令。

$ sysctl net.ipv4.tcp_rmem

net.ipv4.tcp_rmem = 4096 131072 6291456

        与前面的发送缓冲区参数一样,这三个值表示TCP的最小、默认和最大接收缓冲区大小。同样,TCP接收缓冲区的最大值不能超过net.core.rmem_maxnet.core.rmem_max定义所有网络协议的最大接收缓冲区大小。

        在上面的例子中,最大缓冲区大小设置为6 MB; 我们可以使用sysctl命令将其调整为12mb

$ sysctl -w net.ipv4.tcp_rmem="4096 131072 12582912"

         与前面的示例一样,要使此更改永久生效,必须将设置添加到/etc/sysctl.conf文件中。

何时调整缓冲区大小 

        既然我们知道了如何调整发送和接收缓冲区,那么什么时候应该更改它们呢? 对于大多数系统,默认值都比较大。然而,在某些情况下,调整这些缓冲区是有必要的。

        一个主要的例子是TCP客户端通过不可靠的网络发送数据。由于发送缓冲区必须为未被确认的数据包保留数据,因此高丢包率的连接可能会导致发送缓冲区满。当发送缓冲区已满时,应用程序不能再向缓冲区添加数据,并且通常会阻塞(等待)尝试添加数据。

        这种情况在物联网领域很普遍,设备更有可能利用不可靠的网络。然而,不可靠的网络只是这些缓冲区大小可能需要调整的情况之一。

        正如本文开头所述,服务器应用程序不断地从接收缓冲区读取数据。但是,如果程序读取速度不能跟上输入数据的速度,Receive Buffer可能会满。当这种情况发生时,服务器将开始通过减少TCP数据包中的窗口大小字段来通知客户端降低数据发送。当应用程序从缓冲区读取数据时,TCP首部中的窗口大小和报文确认号将增加。从而通知客户端它可以恢复发送数据。

查看缓冲区利用率

        当应用程序性能变坏(写入缓冲区时大量阻塞)或者通过某些TCP窗口变更监控,我们怀疑可能需要调整TCP缓冲区的时候,可以使用netstat命令验证缓冲区的使用情况。

$ netstat -n

Active Internet connections (w/o servers)

Proto Recv-Q Send-Q Local Address Foreign Address State

tcp 0 0 10.0.2.15:22 10.0.2.2:60570 ESTABLISHED

        netstat命令的输出中,有两列表示缓冲区利用率。Recv-Q列表示接收缓冲区中等待接收应用程序读取的字节数。Send- Q列表示发送缓冲区中等待远程系统发送和确认的字节数。

        典型的健康应用程序应该具有较低的发送和接收缓冲区利用率。如果应用程序持续显示不正常,则需要具体调查下。

小结


        在这里中,我们探讨了Linux如何为基于tcp的通信使用tcp_wmem(发送)tcp_rmem(接收)缓冲区,如何使用sysctl命令调整这些缓冲区,以及如何使用netstat命令确定当前的利用率。

        虽然在本文中,我描述了从客户机到服务器的单向通信,但必须记住TCP套接字是双向的。客户端和服务器都有一个发送缓冲区和接收缓冲区分配给连接。

 

         每个应用程序都是独一无二的,但根据我的经验,每当我不得不更改接收缓冲区时,我还需要调整系统上的发送缓冲区大小。

 

二、安装测试软件iperf3

 

三、参数修改示例

临时修改参数验证:参数1
sysctl -w net.core.wmem_max=16777216
sysctl -w net.core.wmem_default=8388608
sysctl -w net.core.rmem_max=16777216
sysctl -w net.core.rmem_default=8388608
sysctl -w net.ipv4.tcp_mem='6157500 8210003 12315000'
sysctl -w net.ipv4.tcp_rmem='4096 87380 6291456'
sysctl -w net.ipv4.tcp_wmem='4096 16384 4194304'

修改后效果明显,

对于此数据库集群网络交互流量高的主机,修改内核参数:
vi /etc/sysctl.conf
net.core.wmem_max=16777216
net.core.wmem_default=8388608
net.core.rmem_max=16777216
net.core.rmem_default=8388608
net.ipv4.tcp_mem='6157500 8210003 12315000'
net.ipv4.tcp_rmem='4096 87380 6291456'
net.ipv4.tcp_wmem='4096 16384 4194304'

例如:net.ipv4.tcp_mem=32768 262144 786432

#tcp_memudp_mem是用内存页表示, ,一页即4KB,内存页转换示例:(262144*4/1024/1024=1GB),如:"32768 262144 786432" (128MB, 1GB, 3GB)

四、进行测试

1、运行server端:iperf3 -s

 

2、运行客户端:iperf3 -c 192.168.122.252,其中192.168.122.252 serverip

 

server端结果:

 

测试结果显示有19.3Gbits/sec

 

其中典型能力说明:

本机虚拟机内同主机,能达到:30.8 Gbits/sec
正式环境,内网同网段,能达到:13 Gbits/sec

五、继续修改参数

临时修改参数验证:参数2
sysctl -w net.core.rmem_default=536870912
sysctl -w net.core.wmem_default=268435456
sysctl -w net.core.rmem_max=536870912
sysctl -w net.core.wmem_max=268435456 
sysctl -w net.ipv4.tcp_mem="32768 262144 786432"
sysctl -w net.ipv4.tcp_rmem="134217728 268435456 536870912"
sysctl -w net.ipv4.tcp_wmem="4194304 268435456 536870912"

 

然后重复四的测试

 

测试结果显示只有15.8Gbits/sec

从两次结果来看,第一次的参数明显把第二次参数的测试结果要好,所以优先使用参数一。

多测试几次找到最优的结果。

 

0条评论
0 / 1000
胡建忠
17文章数
0粉丝数
胡建忠
17 文章 | 0 粉丝
原创

使用iperf3进行CTyunOS网络参数优化

2024-07-24 09:43:45
48
0

一、理解TCP缓冲区

        为了更好地理解TCP缓冲区是如何工作的,让我们研究这样一个场景:“应用程序A”(客户端)希望通过TCP将数据发送给应用程序B”(服务器)(如下所示)

 

发送方

        在上图中,我们可以看到应用程序A想要向应用程序B发送4000字节的数据。要做到这一点,应用程序A将使用write()send()系统调用将数据附加套接字(socket)。从应用程序的角度来看,数据已经被写入套接字,但实际上数据首先被追加到该套接字的Send Buffer中。一旦数据在发送缓冲区中可用,内核将把数据分解成一个或多个TCP包。通常,Linux系统上一个包的默认大小是1500字节,前24字节(包含扩展选项)TCP包头;这意味着单个数据包可以容纳1476字节的应用程序数据。要发送4000字节的应用程序数据,内核需要发送三个包。

        作为一个应用程序,我们不关心一个数据包中包含多少数据。应用程序将数据写入缓冲区。内核从缓冲区中获取数据并将其发送到目标系统,不管这个过程中需要多少数据包。

        内核还会将应用程序数据保存在发送缓冲区中,直到服务器确认发送的数据包。它这样做是为了在包丢失的情况下需要重新传输包。

接收方

        在服务器上,存在另一个称为接收缓冲区的缓冲区。当内核接收并处理数据包时,来自这些数据包的数据被写入接收缓冲区。

        正如应用程序不关心发送缓冲区一样,应用程序也不会和接收缓冲区进行交互。通常,应用程序将使用recv()系统调用从套接字读取数据。但实际上,应用程序是从套接字的接收缓冲区读取可用数据。

增加缓冲区大小

        发送和接收缓冲区的大小是可调的; 它们可以在Linux中通过修改/etc/sysctl.conf文件进行调整。要查看当前值,我们将使用sysctl命令。

 $ sysctl net.ipv4.tcp_wmem

net.ipv4.tcp_wmem = 4096 16384 4194304 

从上面的命令输出中,我们可以看到当前存在三个值。

        第一个4096 (4KB)是最小缓冲区大小。默认情况下,这个最小值设置为与系统页大小相同的大小。设置这个最小值是为了确保即便在低内存机器上或者存在内存压力情况下也有缓存。

        第二个值16384 (16KB)是默认大小。系统上的所有TCP套接字缓冲区默认大小。值得注意的注意是net.ipv4.tcp_wmem将覆盖net.core.wmem_default, net.core.wmem_default是所有网络协议(TCP, UDP)的默认发送缓冲区大小。

        第三个值4194304 (4MB)是最大缓冲区大小。与默认大小不同,该值不能覆盖net.core.wmem_max

        当建立新的TCP连接时,将使用默认值(16KB)创建一个发送缓冲区; 然后,缓冲区大小将根据需要和使用情况自动在最大和最小边界内进行调整。

        对于大多数情况,调整最大值就足够了,很少需要更改默认值或最小值。

调整发送缓冲区

        要更改发送缓冲区大小,可以再次使用sysctl命令。

$ sysctl -w net.ipv4.tcp_wmem="4096 16384 8388608"

        上面的命令将发送缓冲区调整为8 MB; 但是,在重新启动后,更改会丢失。要使此更改持久化,我们可以将更改添加到/etc/sysctl.conf文件中。

调整接收缓冲区

        接收缓冲区也是可调的,就像发送缓冲区一样。要查看当前值,可以使用sysctl命令。

$ sysctl net.ipv4.tcp_rmem

net.ipv4.tcp_rmem = 4096 131072 6291456

        与前面的发送缓冲区参数一样,这三个值表示TCP的最小、默认和最大接收缓冲区大小。同样,TCP接收缓冲区的最大值不能超过net.core.rmem_maxnet.core.rmem_max定义所有网络协议的最大接收缓冲区大小。

        在上面的例子中,最大缓冲区大小设置为6 MB; 我们可以使用sysctl命令将其调整为12mb

$ sysctl -w net.ipv4.tcp_rmem="4096 131072 12582912"

         与前面的示例一样,要使此更改永久生效,必须将设置添加到/etc/sysctl.conf文件中。

何时调整缓冲区大小 

        既然我们知道了如何调整发送和接收缓冲区,那么什么时候应该更改它们呢? 对于大多数系统,默认值都比较大。然而,在某些情况下,调整这些缓冲区是有必要的。

        一个主要的例子是TCP客户端通过不可靠的网络发送数据。由于发送缓冲区必须为未被确认的数据包保留数据,因此高丢包率的连接可能会导致发送缓冲区满。当发送缓冲区已满时,应用程序不能再向缓冲区添加数据,并且通常会阻塞(等待)尝试添加数据。

        这种情况在物联网领域很普遍,设备更有可能利用不可靠的网络。然而,不可靠的网络只是这些缓冲区大小可能需要调整的情况之一。

        正如本文开头所述,服务器应用程序不断地从接收缓冲区读取数据。但是,如果程序读取速度不能跟上输入数据的速度,Receive Buffer可能会满。当这种情况发生时,服务器将开始通过减少TCP数据包中的窗口大小字段来通知客户端降低数据发送。当应用程序从缓冲区读取数据时,TCP首部中的窗口大小和报文确认号将增加。从而通知客户端它可以恢复发送数据。

查看缓冲区利用率

        当应用程序性能变坏(写入缓冲区时大量阻塞)或者通过某些TCP窗口变更监控,我们怀疑可能需要调整TCP缓冲区的时候,可以使用netstat命令验证缓冲区的使用情况。

$ netstat -n

Active Internet connections (w/o servers)

Proto Recv-Q Send-Q Local Address Foreign Address State

tcp 0 0 10.0.2.15:22 10.0.2.2:60570 ESTABLISHED

        netstat命令的输出中,有两列表示缓冲区利用率。Recv-Q列表示接收缓冲区中等待接收应用程序读取的字节数。Send- Q列表示发送缓冲区中等待远程系统发送和确认的字节数。

        典型的健康应用程序应该具有较低的发送和接收缓冲区利用率。如果应用程序持续显示不正常,则需要具体调查下。

小结


        在这里中,我们探讨了Linux如何为基于tcp的通信使用tcp_wmem(发送)tcp_rmem(接收)缓冲区,如何使用sysctl命令调整这些缓冲区,以及如何使用netstat命令确定当前的利用率。

        虽然在本文中,我描述了从客户机到服务器的单向通信,但必须记住TCP套接字是双向的。客户端和服务器都有一个发送缓冲区和接收缓冲区分配给连接。

 

         每个应用程序都是独一无二的,但根据我的经验,每当我不得不更改接收缓冲区时,我还需要调整系统上的发送缓冲区大小。

 

二、安装测试软件iperf3

 

三、参数修改示例

临时修改参数验证:参数1
sysctl -w net.core.wmem_max=16777216
sysctl -w net.core.wmem_default=8388608
sysctl -w net.core.rmem_max=16777216
sysctl -w net.core.rmem_default=8388608
sysctl -w net.ipv4.tcp_mem='6157500 8210003 12315000'
sysctl -w net.ipv4.tcp_rmem='4096 87380 6291456'
sysctl -w net.ipv4.tcp_wmem='4096 16384 4194304'

修改后效果明显,

对于此数据库集群网络交互流量高的主机,修改内核参数:
vi /etc/sysctl.conf
net.core.wmem_max=16777216
net.core.wmem_default=8388608
net.core.rmem_max=16777216
net.core.rmem_default=8388608
net.ipv4.tcp_mem='6157500 8210003 12315000'
net.ipv4.tcp_rmem='4096 87380 6291456'
net.ipv4.tcp_wmem='4096 16384 4194304'

例如:net.ipv4.tcp_mem=32768 262144 786432

#tcp_memudp_mem是用内存页表示, ,一页即4KB,内存页转换示例:(262144*4/1024/1024=1GB),如:"32768 262144 786432" (128MB, 1GB, 3GB)

四、进行测试

1、运行server端:iperf3 -s

 

2、运行客户端:iperf3 -c 192.168.122.252,其中192.168.122.252 serverip

 

server端结果:

 

测试结果显示有19.3Gbits/sec

 

其中典型能力说明:

本机虚拟机内同主机,能达到:30.8 Gbits/sec
正式环境,内网同网段,能达到:13 Gbits/sec

五、继续修改参数

临时修改参数验证:参数2
sysctl -w net.core.rmem_default=536870912
sysctl -w net.core.wmem_default=268435456
sysctl -w net.core.rmem_max=536870912
sysctl -w net.core.wmem_max=268435456 
sysctl -w net.ipv4.tcp_mem="32768 262144 786432"
sysctl -w net.ipv4.tcp_rmem="134217728 268435456 536870912"
sysctl -w net.ipv4.tcp_wmem="4194304 268435456 536870912"

 

然后重复四的测试

 

测试结果显示只有15.8Gbits/sec

从两次结果来看,第一次的参数明显把第二次参数的测试结果要好,所以优先使用参数一。

多测试几次找到最优的结果。

 

文章来自个人专栏
CTyunOS专栏
14 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0