最近发现服务的逻辑完成时间很短,但是上游接收到的时间比较长,所以就怀疑是底层数据的序列化/反序列化、读写、传输有问题,然后怀疑是TCP的读写缓存是不是设置太小。现在就记录下TCP缓存的各配置项以及缓存大小的计算公式。

1.有关发送、接收缓存的配置

内核设置的套接字缓存

/proc/sys/net/core/rmem_default,net.core.rmem_default,套接字接收缓存默认值 (bit)

/proc/sys/net/core/wmem_default,net.core.wmem_default,套接字发送缓存默认值 (bit)

/proc/sys/net/core/rmem_max,net.core.rmem_max,套接字接收缓存最大值 (bit)

/proc/sys/net/core/wmem_max,net.core.wmem_max,发送缓存最大值 (bit)

tcp缓存

/proc/sys/net/ipv4/tcp_rmem:net.ipv4.tcp_rmem,接收缓存设置,依次代表最小值、默认值和最大值(bit)

4096    87380    4194304

/proc/sys/net/ipv4/tcp_wmem:net.ipv4.tcp_wmem,发送缓存设置,依次代表最小值、默认值和最大值(bit)

/proc/sys/net/ipv4/tcp_mem:

94500000    915000000    927000000

对应net.ipv4.tcp_mem,tcp整体缓存设置,对所有tcp内存使用状况的控制,单位是页,依次代表TCP整体内存的无压力值、压力模式开启阀值、最大使用值,用于控制新缓存的分配是否成功

tcp或者udp的设置会覆盖内核设置。其中只有tcp_mem是用于tcp整体内存的控制,其他都是针对单个连接的。

2.修改配置

sysctl -w net.core.rmem_max=8388608
...
sysctl -w net.ipv4.tcp_mem='8388608 8388608 8388608'

3.估算TCP缓存大小  

以tcp接收缓存为例(实际上发送窗口=对方的接收窗口),tcp接收缓存有2部分组成:接收窗口及应用缓存,应用缓存用于应用的延时读及一些调度信息。linux使用net.ipv4.tcp_adv_win_scale(对应文件/proc/sys/net/ipv4/tcp_adv_win_scale)指出应用缓存的比例。

if tcp_adv_win_scale > 0: 应用缓存 = buffer / (2^tcp_adv_win_scale),tcp_adv_win_scale默认值为2,表示缓存的四分之一用于应用缓存,可用接收窗口占四分之三。

if tcp_adv_win_scale <= 0: 应用缓存 = buffer - buffer/2^(-tcp_adv_win_scale),即接收窗口=buffer/2^(-tcp_adv_win_scale),如果tcp_adv_win_scale=-2,接收窗口占接收缓存的四分之一。

那如果能估算出接收窗口就能算出套接字缓存的大小。如何算接收窗口呢?

BDP(bandwidth-delay product,带宽时延积) = bandwith(bits/sec) * delay(sec),代表网络传输能力,为了充分利用网络,最大接收窗口应该等于BDP。delay = RTT/2。

receive_win = bandwith * RTT / 2
buffer = rec_win/(3/4) (上面知道tcp_adv_win_scale=2时表示接收窗口占buffer的3/4

以我们的机房为例,同机房的带宽为30Gbit/s,两台机器ping可获得RTT大概为0.1ms,那BDP=(30Gb/1000) * 0.1 / 2 = 1.5Mb,buffer = 1.5Mb * 4 / 3 = 2Mb

4.TCP缓存的综合考虑

如第三节我们真的能设置tcp最大缓存为2Mb吗?通常一台机器会部署多个服务,一个服务内部也往往会建立多个tcp连接。但系统内存是有限的,如果有4000个连接,满负荷工作,达到最大窗口。那么tcp整体消耗内存=4000 * 2Mb = 1GB。

并发连接越多,默认套接字缓存越大,则tcp占用内存越大。当套接字缓存和系统内存一定时,会影响并发连接数。对于高并发连接场景,系统资源不足,缩小缓存限制;并发连接少时,可以适当放大缓存限制。

linux自身引入了自动调整接收缓存的功能,来使吞吐量最大,(缓存最大值还是受限于tcp_rmem[2])。配置项如下。

net.ipv4.tcp_moderate_rcvbuf = 1 (/proc/sys/net/ipv4/tcp_moderate_rcvbuf)

Linux网络编程-tcp缓存设置的更多相关文章

  1. Linux网络编程——tcp并发服务器(poll实现)

    想详细彻底地了解poll或看懂下面的代码请参考<Linux网络编程——I/O复用之poll函数> 代码: #include <string.h> #include <st ...

  2. Linux 网络编程——TCP

    环境:Linux  C   一.协议介绍      TCP是面向连接的协议,提供可靠的数据传输:TCP协议的可靠传输基于三次握手.四次挥手以及确认重传机制实现.下面来具体展示下TCP的三次握手.四次挥 ...

  3. linux网络编程tcp

    之前学习的时候笔记没有保存好,这次重新编写一个案例. 客户端实现程序代码: #include <string.h> #include <stdlib.h> #include & ...

  4. Linux网络编程学习路线

    转载自:https://blog.csdn.net/lianghe_work/article 一.网络应用层编程   1.Linux网络编程01——网络协议入门 2.Linux网络编程02——无连接和 ...

  5. 【Linux网络编程】TCP网络编程中connect()、listen()和accept()三者之间的关系

    [Linux网络编程]TCP网络编程中connect().listen()和accept()三者之间的关系 基于 TCP 的网络编程开发分为服务器端和客户端两部分,常见的核心步骤和流程如下: conn ...

  6. TCP/UDP Linux网络编程详解

    本文主要记录TCP/UDP网络编程的基础知识,采用TCP/UDP实现宿主机和目标机之间的网络通信. 内容目录 1. 目标2.Linux网络编程基础2.1 嵌套字2.2 端口2.3 网络地址2.3.1 ...

  7. Python网络编程03 /缓存区、基于TCP的socket循环通信、执行远程命令、socketserver通信

    Python网络编程03 /缓存区.基于TCP的socket循环通信.执行远程命令.socketserver通信 目录 Python网络编程03 /缓存区.基于TCP的socket循环通信.执行远程命 ...

  8. 【linux草鞋应用编程系列】_5_ Linux网络编程

    一.网络通信简介   第一部分内容,暂时没法描述,内容实在太多,待后续专门的系列文章.   二.linux网络通信     在linux中继承了Unix下“一切皆文件”的思想, 在linux中要实现网 ...

  9. Linux 网络编程(IO模型)

    针对linux 操作系统的5类IO模型,阻塞式.非阻塞式.多路复用.信号驱动和异步IO进行整理,参考<linux网络编程>及相关网络资料. 阻塞模式 在socket编程(如下图)中调用如下 ...

随机推荐

  1. 完美判断iframe是否加载完成

    var iframe = document.createElement("iframe"); iframe.style.width = "265px"; ifr ...

  2. ASP.NET Core 中文文档 第四章 MVC(4.5)测试控制器逻辑

    原文: Testing Controller Logic 作者: Steve Smith 翻译: 姚阿勇(Dr.Yao) 校对: 高嵩(Jack) ASP.NET MVC 应用程序的控制器应当小巧并专 ...

  3. 应该是Angular2的一个bug?

    为了应对未来的趋势,及时赶上下一趟互联网技术,我最近也在通过具体项目研究angular2,首先必须要吐槽的是,学习angular2的成本本身不高,但是一堆的工具.配置实在让人 很是焦灼,就像asp.n ...

  4. bzoj3207--Hash+主席树

    题目大意: 给定一个n个数的序列和m个询问(n,m<=100000)和k,每个询问包含k+2个数字:l,r,b[1],b[2]...b[k],要求输出b[1]~b[k]在[l,r]中是否出现. ...

  5. 浅谈java异常[Exception]

    学习Java的同学注意了!!! 学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群,群号码:589809992 我们一起学Java! 一. 异常的定义 在<java编程思想 ...

  6. Visual Studio:error MSB8020(搬运)

    状况如下: error MSB8020: The builds tools for v120 (Platform Toolset = 'v120') cannot be found. To build ...

  7. PHP设计模式(八)桥接模式(Bridge For PHP)

    一.概述 桥接模式:将两个原本不相关的类结合在一起,然后利用两个类中的方法和属性,输出一份新的结果. 二.案例 1.模拟毛笔(转) 需求:现在需要准备三种粗细(大中小),并且有五种颜色的比 如果使用蜡 ...

  8. Kotlin类:功能更强、而更简洁(KAD 03)

    作者:Antonio Leiva 时间:Dec 7, 2016 原文链接:http://antonioleiva.com/classes-kotlin/ Kotlin类尽可能简单,这样用较少的代码完成 ...

  9. TabLayout + ViewPager

    一.实现思路 1.在build.gradle中添加依赖,例如: compile 'com.android.support:support-v4:23.4.0'compile 'com.android. ...

  10. atitit.细节决定成败的适合情形与缺点

    atitit.细节决定成败的适合情形与缺点 1. 在理论界有两种观点:一种是"细节决定成败",另一种是"战略决定成败".1 1.1. 格局决定成败,方向决定成败 ...