如何理性的调整「rwnd」和「cwnd」的大小

很多人常常对TCP优化有一种雾里看花的感觉,实际上只要理解了TCP的运行方式就能掀开它的神秘面纱。Ilya Grigorik 在「High Performance Browser Networking」中做了很多细致的描述,让人读起来醍醐灌顶,我大概总结了一下,以期更加通俗易懂。

流量控制

传输数据的时候,如果发送方传输的数据量超过了接收方的处理能力,那么接收方会出现丢包。为了避免出现此类问题,流量控制要求数据传输双方在每次交互时声明各自的接收窗口「rwnd」大小,用来表示自己最大能保存多少数据,这主要是针对接收方而言的,通俗点儿说就是让发送方知道接收方能吃几碗饭,如果窗口衰减到零,那么就说明吃饱了,必须消化消化,如果硬撑的话说不定会大小便失禁,那就是丢包了。

Flow Control

Flow Control

接收方和发送方的称呼是相对的,如果站在用户的角度看:当浏览网页时,数据以下行为主,此时客户端是接收方,服务端是发送方;当上传文件时,数据以上行为主,此时客户端是发送方,服务端是接收方。

慢启动

虽然流量控制可以避免发送方过载接收方,但是却无法避免过载网络,这是因为接收窗口「rwnd」只反映了服务器个体的情况,却无法反映网络整体的情况。

为了避免过载网络的问题,慢启动引入了拥塞窗口「cwnd」的概念,用来表示发送方在得到接收方确认前,最大允许传输的未经确认的数据。「cwnd」同「rwnd」相比不同的是:它只是发送方的一个内部参数,无需通知给接收方,其初始值往往比较小,然后随着数据包被接收方确认,窗口成倍扩大,有点类似于拳击比赛,开始时不了解敌情,往往是次拳试探,慢慢心里有底了,开始逐渐加大重拳进攻的力度。

Slow Start

Slow Start

在慢启动的过程中,随着「cwnd」的增加,可能会出现网络过载,其外在表现就是丢包,一旦出现此类问题,「cwnd」的大小会迅速衰减,以便网络能够缓过来。

Congestion Avoidance

Congestion Avoidance

说明:网络中实际传输的未经确认的数据大小取决于「rwnd」和「cwnd」中的小值。

拥塞避免

从慢启动的介绍中,我们能看到,发送方通过对「cwnd」大小的控制,能够避免网络过载,在此过程中,丢包与其说是一个网络问题,倒不如说是一种反馈机制,通过它我们可以感知到发生了网络拥塞,进而调整数据传输策略,实际上,这里还有一个慢启动阈值「ssthresh」的概念,如果「cwnd」小于「ssthresh」,那么表示在慢启动阶段;如果「cwnd」大于「ssthresh」,那么表示在拥塞避免阶段,此时「cwnd」不再像慢启动阶段那样呈指数级整整,而是趋向于线性增长,以期避免网络拥塞,此阶段有多种算法实现,通常保持缺省即可,这里就不一一说明了,有兴趣的读者可以自行查阅。

如何调整「rwnd」到一个合理值

有很多人都遇到过网络传输速度过慢的问题,比如说明明是百兆网络,其最大传输数据的理论值怎么着也得有个十兆,但是实际情况却相距甚远,可能只有一兆。此类问题如果剔除奸商因素,多半是由于接收窗口「rwnd」设置不合理造成的。

实际上接收窗口「rwnd」的合理值取决于BDP的大小,也就是带宽和延迟的乘积。假设带宽是 100Mbps,延迟是 100ms,那么计算过程如下:

BDP = 100Mbps * 100ms = (100 / 8) * (100 / 1000) = 1.25MB

此问题下如果想最大限度提升吞度量,接收窗口「rwnd」的大小不应小于 1.25MB。说点引申的内容:TCP使用16位来记录窗口大小,也就是说最大值是64KB,如果超过它,就需要使用tcp_window_scaling机制。参考:TCP Windows and Window Scaling

Linux中通过配置内核参数里接收缓冲的大小,进而可以控制接收窗口的大小:

shell> sysctl -a | grep mem
net.ipv4.tcp_rmem = <MIN> <DEFAULT> <MAX>

如果我们出于传输性能的考虑,设置了一个足够大的缓冲,那么当大量请求同时到达时,内存会不会爆掉?通常不会,因为Linux本身有一个缓冲大小自动调优的机制,窗口的实际大小会自动在最小值和最大值之间浮动,以期找到性能和资源的平衡点。

通过如下方式可以确认缓冲大小自动调优机制的状态(0:关闭、1:开启):

shell> sysctl -a | grep tcp_moderate_rcvbuf

如果缓冲大小自动调优机制是关闭状态,那么就把缓冲的缺省值设置为BDP;如果缓冲大小自动调优机制是开启状态,那么就把缓冲的最大值设置为BDP。

实际上这里还有一个细节问题是:缓冲里除了保存着传输的数据本身,还要预留一部分空间用来保存TCP连接本身相关的信息,换句话说,并不是所有空间都会被用来保存数据,相应额外开销的具体计算方法如下:

Buffer / 2^tcp_adv_win_scale

依照Linux内核版本的不同,net.ipv4.tcp_adv_win_scale 的值可能是 1 或者 2,如果为 1 的话,则表示二分之一的缓冲被用来做额外开销,如果为 2 的话,则表示四分之一的缓冲被用来做额外开销。按照这个逻辑,缓冲最终的合理值的具体计算方法如下:

BDP / (1 – 1 / 2^tcp_adv_win_scale)

此外,提醒一下延迟的测试方法,BDP中的延迟指的就是RTT,通常使用ping命令很容易就能得到它,但是如果 ICMP 被屏蔽,ping也就没用了,此时可以试试synack

如何调整「cwnd」到一个合理值

一般来说「cwnd」的初始值取决于MSS的大小,计算方法如下:

min(4 * MSS, max(2 * MSS, 4380))

以太网标准的MSS大小通常是1460,所以「cwnd」的初始值是3MSS。

当我们浏览视频或者下载软件的时候,「cwnd」初始值的影响并不明显,这是因为传输的数据量比较大,时间比较长,相比之下,即便慢启动阶段「cwnd」初始值比较小,也会在相对很短的时间内加速到满窗口,基本上可以忽略不计。

不过当我们浏览网页的时候,情况就不一样了,这是因为传输的数据量比较小,时间比较短,相比之下,如果慢启动阶段「cwnd」初始值比较小,那么很可能还没来得及加速到满窗口,通讯就结束了。这就好比博尔特参加百米比赛,如果起跑慢的话,即便他的加速很快,也可能拿不到好成绩,因为还没等他完全跑起来,终点线已经到了。

举例:假设网页20KB,MSS大小1460B,如此说来整个网页就是15MSS。

先让我们看一下「cwnd」初始值比较小(等于4MSS)的时候会发生什么:

Small Window

Small Window

再看一下「cwnd」初始值比较大(大于15MSS)的时候又会如何:

Big Window

Big Window

明显可见,除去TCP握手和服务端处理,原本需要三次RTT才能完成的数据传输,当我们加大「cwnd」初始值之后,仅用了一次RTT就完成了,效率提升非常大。

推荐:大拿 mnot 写了一个名叫 htracr 的工具,可以用来测试相关的影响。

既然加大「cwnd」初始值这么好,那么到底应该设置多大为好呢?Google在这方面做了大量的研究,权衡了效率和稳定性之后,最终给出的建议是10MSS。如果你的Linux版本不太旧的话,那么可以通过如下方法来调整「cwnd」初始值:

shell> ip route | while read r; do
           ip route change $r initcwnd 10;
       done

需要提醒的是片面的提升发送端「cwnd」的大小并不一定有效,这是因为前面我们说过网络中实际传输的未经确认的数据大小取决于「rwnd」和「cwnd」中的小值,所以一旦接收方的「rwnd」比较小的话,会阻碍「cwnd」的发挥。

推荐:相关详细的描述信息请参考:Tuning initcwnd for optimum performance

有时候我们可能想检查一下目标服务器的「cwnd」初始值设置,此时可以数包:

Test Initcwnd

Test Initcwnd

通过握手阶段确认RTT为168,开始传输后得到第一个数据包的时间是409,加上RTT后就是577,从409到577之间有两个数据包,所以「cwnd」初始值是2MSS。

需要额外说明的是,单纯数包可能并不准确,因为网卡可能会对包做点手脚,具体说明信息请参考:Segmentation and Checksum Offloading: Turning Off with ethtool

补充:有人写了一个名叫 initcwnd_check 的脚本,可以帮你检查「cwnd」初始值。

实践是检验真理的唯一标准,希望大家多动手,通过实验来检验结果,推荐一篇不错的文章:Impact of Bandwidth Delay Product on TCP Throughput,此外知乎上的讨论也值得一看:为什么多 TCP 连接分块下载比单连接下载快,大家有货的话也请告诉我。

  • 10
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
计算机网络作业七及解答 "计算机网络作业七及解答 " "计算机网络作业〔7〕 " "一、单项选择题 " " 1.TCP规定HTTP( )进程的端口号为80。 " " A.客户 B.解析 " " C.效劳器 D.主机 " " 2.A和B建立了TCP连接,当A收到确认号为100确实认报文段时,表示( " ")。 " " A.报文段99已收到 " " B.报文段100已收到 " " C.末字节序号为99的报文段已收到 " " D.末字节序号为100的报文段己收到 " " " "3.在采用TCP连接的数据传输阶段,如果发送端的发送窗口值由1000变为20" "00,那么发送端在收到一个确认之前可以发送( )。 " " A.2000个TCP报文段 B.2000B " " C.1 000B D.1 000个TCP报文段 " " 4.为保证数据传输的可靠性,TCP采用了对( )确认的机制。 " " A.报文段 B.分组 " " C.字节 D.比特 " " 5.以下关于TCP报头格式的描述中,错误的选项是( )。 " " A.报头长度为20"~60B,其中固定局部为20B " " B.端口号字段依次表示源端口号与目的端口号 " " C.报头长度总是4的倍数个字节 " " D.TCP校验和伪首部中IP分组头的协议字段为1 7 " " 6.滑动窗口的作用是( )。 " " A.流量控制 B.拥塞控制 " " C.路由控制 D.过失控制 " " 7.在TCP中,发送方的窗口大小取决于( )。 " " A.仅接收方允许的窗口 " " B.接收方允许的窗口和发送方允许的窗口 " " C.接收方允许的窗口和拥塞窗口 " " D.发送方允许的窗口和拥塞窗口 " " 8.以下关于TCP 作原理与过程的描述中,错误的选项是( )。 " " A.TCP连接建立过程需要经过"三次握手〞的过程 " " " "B.当TCP传输连接建立之后,客户端与效劳器端的应用进程进行全双工的字" "节流传输 " " " "C.TCP传输连接的释放过程很复杂,只有客户端可以主动提出释放连接的请" "求 " " D.TCP连接的释放需要经过"四次挥手〞的过程 " " 9.以下关于TCP窗口与拥塞控制概念的描述中,错误的选项是( )。 " " A.接收端窗(rwnd)通过TCP首部中的窗口字段通知数据的发送方 " " B.发送窗口确定的依据是:发送窗El=Min[接收端窗口,拥塞窗口 " " C.拥塞窗口是接收端根据网络拥塞情况确定的窗口值 " "D.拥塞窗口大小在开始时可以按指数规律增长 " " 10.TCP使用三次握手协议来建立连接,设A、B双方发送报文的初始序列 " "号分别为X和Y,A发送( )的报文给B,B接收到报文后发送( )的报文给A,然" "后A发送一个确认报文给B便建立了连接。(注:ACK的下标为捎带的序号) " " A.SYN=1,序号=X B.SYN=1,序号=X+1,ACKx=I " " C.SYN=1,序号:Y D.SYN=1,序号=Y,ACKy+1=1 " " A.SYN=1,序号=X+1 B.SYN=1,序号=X+1,ACKx=l " " C.SYN=1,序号=Y,ACKx+1=1 D.SYN=1,序号=Y,ACKy+1=1 " "11.TCP"三次握手〞过程中,第二次"握手〞时,发送的报文段中( )标 " "志位被置为1。 " " A.SYN B.ACK " " C.ACK 和RST D.SYN和ACK " "12.A和B之间建立了TCP连接,A向B发送了一个报文段,其中序号字段seq=2" "00确认号字段ACK=201,数据局部有2个字节,那么在B对该报文确实认报文 " "段中( ) " " A.seq=202,ACK=200 B.seq=201,ACK=201 " " C.seq=201,ACK=202 D.seq=202,ACK=201 " "13.一个TCP连接的数据传输阶段,如果发送端的发送窗口值由2000变为300" "0,意昧着发送端可以( )。 " " A.在收到一个确认之前可以发送3000个TCP报文段 " " B.在收到一个确认之前可以发送1000B " " C.在收到一个确认之前可以发送3000B " " D.在收到一个确认之前可以发送2000个TCP报文段 " "14.在一个TCP连接中,MSS为1 " "KB,当拥塞窗口为34KB时发生了超时事件。如果在接下来的4个RTT内报文段" "传输都是成功的,那么当这些报文段均得到确认后,拥塞窗口的大小是( " ")。 " " A.8KB B.9KB " " C.1 6KB D.1 7KB " "1 5.在一个TCP连接中,MSS为1 KB,当拥塞窗口为34KB " "H寸收到了3个冗余
数据来源:中经数据库 主要指标110多个(全部都是纯粹的 市辖区 指标),大致是: GDP GDP增速 第一产业增加值占GDP比重 第二产业增加值占GDP比重 第三产业增加值占GDP比重 人均GDP 社会消费品零售总额 固定资产投资(不含农户) 新设外商投资企业数_外商直接投资 实际利用外资金额(美元) 一般公共预算收入 一般公共预算支出 一般公共预算支出_教育 一般公共预算支出_科学技术 金融机构人民币各项存款余额_个人储蓄存款 金融机构人民币各项存款余额 金融机构人民币各项贷款余额 规模以上工业企业单位数 规模以上工业企业单位数_内资企业 规模以上工业企业单位数_港澳台商投资企业 规模以上工业企业单位数_外商投资企业 规模以上工业总产值 规模以上工业总产值_内资企业 规模以上工业总产值_港澳台商投资企业 规模以上工业总产值_外商投资企业 规模以上工业企业流动资产合计 规模以上工业企业固定资产合计 规模以上工业企业利润总额 规模以上工业企业应交增值税 规模以上工业企业主营业务税金及附加 户籍人口数 年均户籍人口数 户籍人口自然增长率 第一产业就业人员占全部城镇单位就业人员比重 第二产业就业人员占全部城镇单位就业人员比重 第三产业就业人员占全部城镇单位就业人员比重 城镇非私营单位就业人员数 城镇非私营单位就业人员数_第一产业 城镇非私营单位就业人员数_第二产业 城镇非私营单位就业人员数_第三产业 城镇非私营单位就业人员数_农、林、牧、渔业 城镇非私营单位就业人员数_采矿业 城镇非私营单位就业人员数_制造业 城镇非私营单位就业人员数_电力、热力、燃气及水生产和供应业 城镇非私营单位就业人员数_建筑业 城镇非私营单位就业人员数_批发和零售业 城镇非私营单位就业人员数_交通运输、仓储和邮政业 城镇非私营单位就业人员数_住宿和餐饮业 城镇非私营单位就业人员数_信息传输、软件和信息技术服务业 城镇非私营单位就业人员数_金融业 城镇非私营单位就业人员数_房地产业 城镇非私营单位就业人员数_租赁和商务服务业 城镇非私营单位就业人员数_科学研究和技术服务业 城镇非私营单位就业人员数_水利、环境和公共设施管理业 城镇非私营单位就业人员数_居民服务、修理和其他服务业 城镇非私营单位就业人员数_教育 城镇非私营单位就业人员数_卫生和社会工作 城镇非私营单位就业人员数_文化、体育和娱乐业 城镇非私营单位就业人员数_公共管理、社会保障和社会组织 城镇非私营单位在岗职工平均人数 城镇就业人员数_私营企业和个体 城镇非私营单位在岗职工工资总额 城镇非私营单位在岗职工平均工资 城镇登记失业人员数 建成区面积 建设用地面积 建设用地面积_居住用地 液化石油气供气总量 液化石油气供气总量_居民家庭 人工煤气、天然气供气总量 人工煤气、天然气供气总量_居民家庭 液化石油气用气人口 人工煤气、天然气用气人口 城市公共汽电车运营车辆数 城市出租汽车运营车辆数 城市公共汽电车客运总量 道路面积 排水管道长度 建成区绿化覆盖面积 建成区绿化覆盖率 绿地面积 公园绿地面积 维护建设资金支出 土地面积 生活用水供水量 供水总量 全社会用电量 城乡居民生活用电量 工业生产用电量 房地产开发投资 房地产开发投资_住宅 限额以上批发和零售业法人单位数 限额以上批发和零售业商品销售总额 普通中学学校数 中等职业教育学校数 普通小学学校数 普通高等学校专任教师数 普通中学专任教师数 中等职业教育专任教师数 普通小学专任教师数 普通高等学校在校生数 普通中学在校生数 中等职业教育在校生数 普通小学在校生数 电视节目综合人口覆盖率 公共图书馆总藏量_图书 医疗卫生机构数_医院和卫生院 卫生人员数_执业(助理)医师 医疗卫生机构床位数_医院和卫生院 城镇职工基本养老保险参保人数 职工基本医疗保险参保人数 失业保险参保人数
一、进程之间的通信分为有连接和无连接两种方式。有连接方式需要先建立连接,然后进行数据传输,传输完成后再释放连接。无连接方式则不需要建立连接,直接进行数据传输。 二、UDP协议是一种无连接的传输协议,数据传输前不需要建立连接,也不保证数据传输的可靠性。UDP首部数据格式包括源端口、目的端口、长度和校验和等字段。 三、TCP协议是一种面向连接的传输协议,数据传输前需要先建立连接,并保证数据传输的可靠性。TCP首部数据格式包括源端口、目的端口、序号、确认号、数据偏移、标志位、窗口大小、校验和等字段。MSS是指TCP报文段中的最大数据段长度。 四、TCP可靠传输是通过滑动窗口实现的,滑动窗口是指接收端和发送端的缓存区大小。滑动窗口向前滑动的条件是接收端已经成功接收到一部分数据。滑动窗口大小和两个窗口(rwndcwnd)的关系是发送端的窗口大小不能超过接收端的窗口大小。RTO是指重传超时时间,是根据网络延迟和丢包率等因素计算得出的一个时间值。 五、TCP流量控制是通过接收端的rwnd窗口实现的,rwnd窗口大小表示接收端的缓存区大小。发送端的数据大小不能超过接收端的rwnd窗口大小。 六、TCP拥塞控制是为了避免网络拥塞而采取的一系列措施,包括满开始和拥塞避免两个阶段。在满开始阶段,发送端的cwnd窗口大小为1,每次传输一个数据包。在拥塞避免阶段,发送端逐渐增加cwnd窗口大小,以适应网络负载。 七、TCP连接管理采用三次握手过程。客户端向服务端发送一个SYN包,服务端回复一个SYN+ACK包,最后客户端回复一个ACK包,建立连接。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值