使用Sysctl进行Linux网络(TCP)性能调优

时间:2020-03-21 11:46:05  来源:igfitidea点击:

在Linux内核1.3.57版之前,如果要修改某些系统参数,除了重新编译内核外,没有其他机制。

对于每个需要的修改,重新编译内核都不是一个好主意。
仅仅是因为它没有提供灵活性,并且普通用户无法坐下来重新编译,而是一个内核,用于将值修改为其所需的值。

因此,需要提供一种用户界面,用户可以使用该界面在运行时轻松地修改内核参数,而无需重新编译内核。
因此引入了Sysctl。
在Linux中引入sysctl之前。
几乎所有内核参数都被定义为常量。
但是,使用sysctl可以修改这些常量以适合需求。

在本文中,我们将讨论一些sysctl参数,这些参数会影响网络的性能。
在进入细节之前,我们首先来看一些可以使用sysctl进行修改的东西。

  • 设备参数
  • 网络参数
  • 防火墙行为
  • 文件系统
  • NFS
  • 工艺流程
  • 版本详细信息等等。

通过运行以下命令,可以找到所有sysctl参数的完整列表。

[root@www kernel]# sysctl -a

讨论所有这些都不在本文的讨论范围之内。
但是,在以后的日子里,我一定会写一些有关sysctl中可用选项的信息。

我们将在sysctl中讨论与网络相关的交换机,对其进行修改可以大大提高网络速度。

大多数Linux用户都知道,无论我们在sysctl中进行什么修改,它最终都会修改/proc目录中的某些文件。
在正在运行的系统上,我们可以将所需的值重定向到/proc文件系统中的文件,该文件将立即应用。
但是最好总是使用sysctl来修改内核参数。

本文的主要目的是了解sysctl中与这些网络相关的选项,以及就网络和通信而言它们的确切作用。
我们将逐一讨论这些选项中的每个选项,并了解它们如何适合Linux中的网络连接。

在继续并在Linux机器上微调这些参数之前,让我们了解网络和TCP的一些基础知识。

1.往返时间(RTT Round Trip Time)

这不过是将数据包发送到接收器所花费的时间,以及从接收器获得确认所花费的时间。
因此,往返时间是发送IP数据包然后从另一端接收和确认所花费的时间。
在网络中,可以使用非常常用的称为PING的命令进行测试。

C:\Users\sarath>ping theitroad.com
Pinging theitroad.com [212.71.233.103] with 32 bytes of data:
Reply from 212.71.233.103: bytes=32 time=130ms TTL=51
Reply from 212.71.233.103: bytes=32 time=130ms TTL=51

时间= 130毫秒(毫秒),显示了从我的计算机到达theitroad.com的往返时间。
我的服务器位于伦敦的Linode数据中心。
IP数据包从我目前在荷兰海得拉巴的位置到达我的服务器,然后从伦敦得到回执的时间花费了130毫秒。

2.TCP及其连接类型

传输控制协议(TCP)是面向连接的协议。
现在为什么将其称为面向连接?
这是因为在任何数据传输发生之前,发送方和接收方之间都建立了可靠的连接。
建立连接非常重要,因为发送方需要正确地将其数据传递给接收方,然后还要确认数据已正确传递。

阅读:如何建立TCP连接

一旦建立了可靠的连接,数据就可以在两个方向上流动。
从发送者到接收者,再从接收者到发送者。
发送者还需要通过等待接收者的确认来确认数据的正确传送。
请记住以下事实:“谁发送数据与谁发起了连接无关”。

3.什么是网段,数据包和帧

人们在网络中可以互换使用这些术语(段,数据包和帧)。
但是它们是完全不同的。
我们可能已经知道,在网络中有5个不同的层。
第一个是应用程序层,传输层,网络层,数据链路层,最后是物理层(此物理层是数据流经电线的层)。

每当任何应用程序将数据发送到远程服务器时(例如,我们正在使用喜欢的Mozilla Firefox浏览器浏览此网页)。
浏览时,Web浏览器和操作系统会负责应用程序层,操作系统中的TCP套件会负责传输层,而IP地址和接收器地址详细信息来自网络层(也要小心) (通过操作系统中安装的网络堆栈),然后进入涉及硬件部分(例如MAC地址等)的数据链路层,然后进入物理层,在最终传输数据线上制作最终数据。

因此,无论我们从系统发送到服务器的任何内容都经过这些不同的层(每个层都将自己的信息添加到上一层所提交的数据中。
)。

  • 传输层的数据称为段
  • 网络层的数据称为数据包
  • 最后一层的数据称为帧(准备通过有线传输)

现在我们前面讨论了TCP是一种可靠的协议。
之所以可靠,是因为无论我们发送什么,接收者都必须确认它已经收到了我们发送的东西。
我必须说,我们发送的所有字节都必须由接收方确认。
现在,如果接收方不确认该怎么办?
如果接收方不确认,则发送方将重新发送未确认的字节。

当我们谈论发送和获取确认时,这似乎非常简单。
然而,着手以可靠的方式实现这一目标是一项艰巨的任务,我们需要考虑很多事情。

诸如在发件人获得确认之前将基于连续的基础发送多少数据之类的事情。
接收方在最终由接收应用程序处理之前可以处理多少数据。

与实现这种可靠的通信协议有关的那些问题可以通过称为TCP中的流控制的方法来解决。
现在让我们了解什么是流控制(不用担心,一旦我们了解了这些概念,我们将在Linux中配置和微调设置。

TCP中的流控制

因此,使用TCP中的流控制将解决的问题是将发送和接收的数据量正确。
发送方发送的数据一定不能大到足以使接收方不堪重负。

现在,对通信的这种控制非常重要,因为我们拥有彼此通信的不同速度的网络。

TCP使用称为“滑动窗口协议”的东西来管理此流控制。
它的工作很容易理解。
接收方和发送方都将相互告知其可以接受的数据量。
现在的问题是,这些信息如何彼此共享。
每个TCP段中都有一个被发送和接收的字段,称为“接收窗口”(请注意,我们在谈论的是段,因此在传输层中)。
接收方将在“接收窗口”字段中提及其可以接受或者说愿意接受的数据量。

发送方在看到接收方发送的段中提到的接收窗口大小时,将对此进行记录。
现在,发送者在确认之前不能发送超过接收者提到的接收窗口大小的消息。
一旦接收到确认,并且接收方发送了新的接收窗口值,发送方现在就可以发送下一组数据(同样,接收方在接收方窗口大小中提到的那部分数据也是如此)。

如果接收方发送的接收窗口大小为0,则发送方将无法再发送任何数据,直到接收到其先前发送的数据的确认,并且接收方发送了新的接收窗口大小。

除非并且除非接收方发送了新的接收窗口大小,否则发送方无法再发送任何数据。

我们可以在IP数据包或者TCP段中包含的内容始终受到限制。
限制是由于协议规范中定义的,分配给TCP段中每个字段的标准大小所致。
TCP并不是一项非常新的技术,它是在网络速度比我们今天拥有的高速网络慢的时候制造的。

因此,就性能而言,有必要修改或者说包括和修改一些其他功能。
因此RFC 1323诞生了。

它包含有关TCP性能改进的详细信息。

限制是,TCP帧中可以包含的最大接收窗口大小为65,535字节。
如果考虑到当今的网络速度,那么这是一个非常低的数字。

新的修改方案称为窗口缩放,将接收窗口大小的限制从65535字节增加到最大1,073,725,440字节(非常接近1 Giga字节)。
为了更深入地了解这一点,让我们深入一点计算。
该计算称为带宽延迟乘积。

带宽延迟积

术语“带宽延迟乘积”本身很容易解释。
它是两个端点之间通信时引起的带宽和延迟的乘积。
现在,让我们看看它是什么。

我们将与带宽相乘的第二个值不过是发送数据包然后返回确认所引起的延迟。
我们在往返时间部分中了解了如何确定该值。

现在,如果带宽为10Mbps,并且到达目标接收器的RTT(往返时间)约为200毫秒,那么带宽延迟乘积将为。

带宽延迟乘积= 2 x 106 b/s x 200 x 10-3 s = 244.14千字节

我们可以从下面显示的链接计算带宽延迟乘积。

计算带宽延迟积

带宽延迟乘积结果显示必须传输的字节数,以有效使用连接速度。
但是,由于我们的操作系统具有65535字节(65千字节)窗口大小的默认值,因此根本没有有效地使用连接。

如果我们计算244.14 65 = 179千字节未使用。
因此,往返时间越长,我们需要发送的数据就越多,以充分利用链接速度(因为更多的延迟意味着我们需要一次发送更多的数据以利用带宽。
)如果延迟(往返时间)更长,则“带宽延迟”乘积将继续增加。

因此,要解决此问题,我们需要使用更大的窗口大小。
如前所述,TCP以RFC 1323的形式进行了新的修改,从而提高了性能。

为了提高性能而增加窗口大小是通过称为TCP窗口缩放的形式实现的。

如果带宽延迟乘积超过65千字节,则在TCP中使用“窗口缩放”选项将提高网络吞吐量和速度。

让我们继续修改Linux系统的TCP参数,默认情况下使用称为TCP Window Scaling的选项。
正如我们在本文开头所讨论的,启用此窗口缩放选项是通过修改sysctl.conf文件来完成的。

net.ipv4.tcp_window_scaling = 1

即使在启用窗口缩放选项之后,在没有得到确认的情况下可以发送到接收器的最大数据量取决于另一个因素。
它称为接收窗口大小。
这是接收方在被接收应用程序处理之前可以缓冲的最大数据量。

现在,如果接收器的接收窗口大小较小,则即使在设置了窗口缩放选项之后,发送器也只能发送等于在接收器端配置的接收窗口大小的最大数据大小。

因此,我们需要将接收窗口的大小修改为更大的最大值。
还可以使用sysctl.conf文件(带有以下选项)进行此配置。

net.core.rmem_max = 16777216

除了接收窗口大小以外,发送者还必须在最大发送窗口大小中具有较高的值。
我们可能在想为什么对发送和接收窗口的大小要求固定值。
这是因为发送方必须跟踪其发送的字节,直到获得确认为止。
因为如果没有收到确认,则发送方必须重新发送整个字节(如果它在缓冲区中,它可以重新发送。
因此,直到确认到来,才会刷新此缓冲区数据。

修改最大发送窗口大小,也类似于我们修改最大接收窗口大小的方法。

net.core.wmem_max = 16777216

现在,除了上述接收窗口大小和发送窗口大小的最大值外,操作系统还使用了另一项设置,这些设置针对不同的情况设置这些值。
让我们看看该选项(这也在sysctl.conf文件中设置)。
首先让我们看一下接收窗口的大小值。

net.ipv4.tcp_rmem = 4096 87380 16777216

那里有三个值。

  • 第一个值是将为每个TCP连接设置的最小接收窗口量,即使系统处于极高的压力下也是如此。
  • 分配给每个tcp连接的默认值
  • 第三个是可分配给TCP连接的最大值

请不要忘记我们使用窗口缩放选项的事实,因此窗口大小将是动态的,并且会不断增加,直到达到最大接收窗口大小为止

同样,还有发送窗口设置,如下所示。
(“发送”窗口设置中的三个值也表示我们上面讨论的三件事)

net.ipv4.tcp_wmem = 4096        16384   16777216

因此,将所有这些东西组合在一起,我们的sysctl.conf文件将如下所示。

net.ipv4.tcp_window_scaling = 1
net.core.rmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096        16384   16777216

使用上述必需的设置修改完sysctl.conf文件后,可以通过以下命令重新加载配置并将其永久化。

sysctl -p /etc/sysctl.conf

或者,我们也可以通过将所需的值重定向到/proc中的所需文件来即时修改上述值。
可以如下所示进行。

echo '16777216' > /proc/sys/net/core/rmem_max

echo '16777216' > /proc/sys/net/core/wmem_max