网络栈内存不足引发进程挂起问题
我们知道TCP socket有发送缓冲区和接收缓冲区,这二个缓冲区都可以透过setsockopt设置SO_SNDBUF,SO_RCVBUF来修改,但是这些值设多大呢?这些值和协议栈的内存控制相关的值什么关系呢?
我们来解释下:
$ sysctl net|grep mem
net.core.wmem_max = 131071
net.core.rmem_max = 131071
net.core.wmem_default = 124928
net.core.rmem_default = 124928
net.core.optmem_max = 20480
net.ipv4.igmp_max_memberships = 20
net.ipv4.tcp_mem = 4631520 6175360 9263040
net.ipv4.tcp_wmem = 4096 16384 4194304
net.ipv4.tcp_rmem = 4096 87380 4194304
net.ipv4.udp_mem = 4631520 6175360 9263040
net.ipv4.udp_rmem_min = 4096
net.ipv4.udp_wmem_min = 4096
下面的图很好的解释了上面的问题:
这里要记住的是:TCP协议栈内存是不可交换物理内存,用一字节少一字节。
也正是由于这一点,操作系统出厂的时候上面的默认的内存设置都不算太大。对于一个不是网络密集型的服务器问题不大,但是对于如承担C1M链接的服务器来讲,问题就来了。我们在实践中会发现tcp服务经常超时,有时候超过100ms. 那么这个问题如何定位呢?
我们知道当协议栈缺少内存的时候会调用sk_stream_wait_memory等待其他进程释放出内存,所以这个函数的等待时间就是我们的进程被阻塞的时间。
下面我们来验证下:
$ cat /usr/share/doc/systemtap-1.6/examples/network/sk_stream_wait_memory.stp #!/usr/bin/stap # Simple probe to detect when a process is waiting for more socket send # buffer memory. Usually means the process is doing writes larger than the # socket send buffer size or there is a slow receiver at the other side. # Increasing the socket's send buffer size might help decrease application # latencies, but it might also make it worse, so buyer beware. # # Typical output: timestamp in microseconds: procname(pid) event # # 1218230114875167: python(17631) blocked on full send buffer # 1218230114876196: python(17631) recovered from full send buffer # 1218230114876271: python(17631) blocked on full send buffer # 1218230114876479: python(17631) recovered from full send buffer probe kernel.function("sk_stream_wait_memory") { printf("%u: %s(%d) blocked on full send buffer\n", gettimeofday_us(), execname(), pid()) } probe kernel.function("sk_stream_wait_memory").return { printf("%u: %s(%d) recovered from full send buffer\n", gettimeofday_us(), execname(), pid()) } $ sudo stap sk_stream_wait_memory.stp 1218230114875167: python(17631) blocked on full send buffer 1218230114876196: python(17631) recovered from full send buffer 1218230114876271: python(17631) blocked on full send buffer 1218230114876479: python(17631) recovered from full send buffer
如果我们观察到了进程由于缺少内存被阻塞,那么是时候调整协议栈的内存限制了。
小结:网络很复杂,需要定量分析!
建议继续学习:
- Linux内存点滴 用户进程内存空间 (阅读:11423)
- ps - 按进程消耗内存多少排序 (阅读:11244)
- Linux Used内存到底哪里去了? (阅读:9951)
- Linux操作系统的内存使用方法详细解析 (阅读:8858)
- linux内核研究笔记(一)内存管理 – page介绍 (阅读:8562)
- 几个内存相关面试题(c/c++) (阅读:8007)
- 内存越界的概念和调试方法 (阅读:6279)
- Innodb分表太多或者表分区太多,会导致内存耗尽而宕机 (阅读:6148)
- 必看!linux系统如何查看内存使用情况 (阅读:6143)
- 如何查看Linux 硬件配置信息 (阅读:5863)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:Yu Feng 来源: 系统技术非业余研究
- 标签: 内存
- 发布时间:2013-03-11 13:40:08
- [53] IOS安全–浅谈关于IOS加固的几种方法
- [52] 如何拿下简短的域名
- [51] 图书馆的世界纪录
- [50] android 开发入门
- [50] Oracle MTS模式下 进程地址与会话信
- [49] Go Reflect 性能
- [46] 【社会化设计】自我(self)部分――欢迎区
- [46] 读书笔记-壹百度:百度十年千倍的29条法则
- [36] 程序员技术练级攻略
- [29] 视觉调整-设计师 vs. 逻辑