大并发下TCP内存消耗优化小记(86万并发业务正常服务)

2024-05-26 07:18

本文主要是介绍大并发下TCP内存消耗优化小记(86万并发业务正常服务),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

    最近在做一个大并发服务的测试(目前测到86万,当然有大量长连接,每天打的日志高到170多g,不打算继续测了),业务系统为反向代理ATS,服务的内容为动态域名,大部分的url很长,不过打开后的值只是0或1这样的标记。

    当服务器在几万并发时,一般不需要考虑TCP连接消耗内存的问题,但当服务器承载几十万并发时,会暴漏出各种的问题,因此不得不考虑TCP连接对内存资源的消耗,当然跑到86万的并发需要对业务系统、Centos做各种参数优化,牵涉面太多,今天只说TCP内存占用(由于线上系统干扰条件很多,无法特定的对某个参数去调试,只分享一下做过程的心得,抛砖引玉),出现的问题如下:


wKiom1bspJvBEOeHAABuFNFUs4I951.png

(内存不够用,kernel直接把ats的进程给杀掉了,然后out of socket memory)


wKiom1brzk-yZjfiAABDbo0h_z8458.png

 (跑着跑着,直接out of socket memory)


wKioL1bwpQeS0S8gAAAn85tOIXo230.png

(tsar的内存监控数据) 


    每一个TCP连接都会有对应的socket封装,而每个socket都要占用一个fd,现在的业务系统大都采用epoll的网络I/O模型,他可以高效的处理大批量socket句柄,而这个socket句柄的对应的TCP读写缓存再加上一个TCP控制块就是单个TCP连接所消耗的内存,当然这个读写缓存的大小是根据系统的需要动态变化的,和TCP的滑动窗口大小成正相关。

对于tcp能够使用多少缓存,centos是会有全局控制的,例如我线上的服务器(内存62G,有15个G做内存cache使用)。

 

TCP能够使用的内存:这三个值就是TCP使用内存的大小,单位是页,每个页是4K的大小,如下:


wKioL1brz0PycydHAAAJQKtWQW0638.png


这三个值分别代表

Low6179424   6179424*4/1024/1024大概23g

Pressure8239232 8239232*4/1024/1024大概31g

High12358848   echo 12358848*4/1024/1024大概47g

这个也是系统装后的默认取值,也就是说最大有47g75%的内存)可以用作TCP连接,这三个量也同时代表了三个阀值,TCP的使用小于第二个值时kernel不会有任何提示操作,当大于第二个值时进入压力模式,当高于第三个值时将不接受新的TCP连接,同时会报出“Out  of  socket memory”或者TCP:too many of orphaned sockets”。

 

TCP读缓存大小,单位是字节:第一个是最小值4K,第二个是默认值85K,第三个是最大值16M,如下:


wKioL1brz-vA-pohAAAJ6zc3ROE318.png


这个可以在sysctl.conf中net.ipv4.tcp_rmem中进行调整。

 

TCP写缓存大小,单位是字节:第一个是最小值4K,第二个是默认值64K,第三个是最大值16M,如下:


wKioL1brz_6gQCgPAAAMO0VkVyE066.png


这个可以在sysctl.conf中net.ipv4.tcp_wmem中进行调整。

 

    也就是说一个TCP在三次握手建立连接后,最小的内存消耗在8K左右,最大的内存消耗在32M左右,你可以通过MTU估算MSS,然后算出一个滑动窗口有多少个MSS。现在可以进行简单计算了,按照系统TCP的全局控制,有47个g可用作内存缓存,假设按照默认的读写缓存计算,一个TCP连接占用149K加1K的tcp控制块共150K的内存,那么系统能承受最大的并发为 47*1024*1024/150 = 32万,当然这只是理论,一个TCP连接占用的内存实际是大小混用的,根据传输的文件大小以及网络状况动态调整。那么当前是什么情况呢,是有很多的长连接,而且每个请求的数据都很小,也就是说很有大量TCP连接只占了10K左右的内存,所以可以尝试更大的并发。

 好了,我顺着思路往下想,“Out  of  socket memory”除了业务系统恶意丢弃请求、或者孤儿套接字太多、或者fd(已经优化的很大了,不存在)用完了,就可能是为新的soket分配内存资源内存不够用了,因为在之前测试到30万左右的连接的时候出过这个问题,查看内存基本跑满,当时是把ats的logbuffer改小(动态连接一个url有时到45K的长度,于是当时把log buffer改的特别大)后就不报了,后来继续跑到50万左右又报错了,内存基本跑满,后把内存cache从30G调到了15G,再腾出15G给TCP连接及其与资源使用,跑到70万左右又不行了,大量这个错误。因为当前内存使用的很杂,有ats的内存缓存,有大量的孤儿Orphan soket(占用64K左右内存),还有大量的没有释放的TCP连接,还有ats的log等线程使用的内存,七七八八算下来,TCP能使用的内存不多,长连接、小链接、大链接的比例也不好计算,只能按照经验去尝试,目前看跑到70万已经到头了吧。

可是后来又想,系统对于刚开始建连接的时候可能是默认的内存占用,之后再动态调整,按照当前域名质量情况,大多数都是小的不能再小的请求,我是否可以更改默认TCP的读写缓存呢,于是调整,读写默认缓存各变为原来的一半分别是43K和32K,第二天晚高峰检查,跑到86万,没有出现问题,好了到此为止,不再测了。


 wKiom1bsp33gERxMAAAom0_Ntus222.png


总结:其实系统单纯能跑多大并发在乎全局fd和内存,但大并发下还能继续保持业务正常服务就是技术活儿了,每个业务系统的参数、操作系统的参数都得琢磨尝试,其余方面的优化小记有空再写。


本文出自 “奔跑的linux” 博客,请务必保留此出处http://benpaozhe.blog.51cto.com/10239098/1752675

这篇关于大并发下TCP内存消耗优化小记(86万并发业务正常服务)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1003796

相关文章

Linux创建服务使用systemctl管理详解

《Linux创建服务使用systemctl管理详解》文章指导在Linux中创建systemd服务,设置文件权限为所有者读写、其他只读,重新加载配置,启动服务并检查状态,确保服务正常运行,关键步骤包括权... 目录创建服务 /usr/lib/systemd/system/设置服务文件权限:所有者读写js,其他

Java服务实现开启Debug远程调试

《Java服务实现开启Debug远程调试》文章介绍如何通过JVM参数开启Java服务远程调试,便于在线上排查问题,在IDEA中配置客户端连接,实现无需频繁部署的调试,提升效率... 目录一、背景二、相关图示说明三、具体操作步骤1、服务端配置2、客户端配置总结一、背景日常项目中,通常我们的代码都是部署到远程

Python内存管理机制之垃圾回收与引用计数操作全过程

《Python内存管理机制之垃圾回收与引用计数操作全过程》SQLAlchemy是Python中最流行的ORM(对象关系映射)框架之一,它提供了高效且灵活的数据库操作方式,本文将介绍如何使用SQLAlc... 目录安装核心概念连接数据库定义数据模型创建数据库表基本CRUD操作创建数据读取数据更新数据删除数据查

Java JUC并发集合详解之线程安全容器完全攻略

《JavaJUC并发集合详解之线程安全容器完全攻略》Java通过java.util.concurrent(JUC)包提供了一整套线程安全的并发容器,它们不仅是简单的同步包装,更是基于精妙并发算法构建... 目录一、为什么需要JUC并发集合?二、核心并发集合分类与详解三、选型指南:如何选择合适的并发容器?在多

Java 结构化并发Structured Concurrency实践举例

《Java结构化并发StructuredConcurrency实践举例》Java21结构化并发通过作用域和任务句柄统一管理并发生命周期,解决线程泄漏与任务追踪问题,提升代码安全性和可观测性,其核心... 目录一、结构化并发的核心概念与设计目标二、结构化并发的核心组件(一)作用域(Scopes)(二)任务句柄

k8s容器放开锁内存限制问题

《k8s容器放开锁内存限制问题》nccl-test容器运行mpirun时因NCCL_BUFFSIZE过大导致OOM,需通过修改docker服务配置文件,将LimitMEMLOCK设为infinity并... 目录问题问题确认放开容器max locked memory限制总结参考:https://Access

Docker多阶段镜像构建与缓存利用性能优化实践指南

《Docker多阶段镜像构建与缓存利用性能优化实践指南》这篇文章将从原理层面深入解析Docker多阶段构建与缓存机制,结合实际项目示例,说明如何有效利用构建缓存,组织镜像层次,最大化提升构建速度并减少... 目录一、技术背景与应用场景二、核心原理深入分析三、关键 dockerfile 解读3.1 Docke

sysmain服务可以禁用吗? 电脑sysmain服务关闭后的影响与操作指南

《sysmain服务可以禁用吗?电脑sysmain服务关闭后的影响与操作指南》在Windows系统中,SysMain服务(原名Superfetch)作为一个旨在提升系统性能的关键组件,一直备受用户关... 在使用 Windows 系统时,有时候真有点像在「开盲盒」。全新安装系统后的「默认设置」,往往并不尽编

Web服务器-Nginx-高并发问题

《Web服务器-Nginx-高并发问题》Nginx通过事件驱动、I/O多路复用和异步非阻塞技术高效处理高并发,结合动静分离和限流策略,提升性能与稳定性... 目录前言一、架构1. 原生多进程架构2. 事件驱动模型3. IO多路复用4. 异步非阻塞 I/O5. Nginx高并发配置实战二、动静分离1. 职责2

Redis实现高效内存管理的示例代码

《Redis实现高效内存管理的示例代码》Redis内存管理是其核心功能之一,为了高效地利用内存,Redis采用了多种技术和策略,如优化的数据结构、内存分配策略、内存回收、数据压缩等,下面就来详细的介绍... 目录1. 内存分配策略jemalloc 的使用2. 数据压缩和编码ziplist示例代码3. 优化的