【发布时间】:2020-07-22 09:06:02
【问题描述】:
我们的系统内存占用逐渐增加。 在使用分析器进行太多调试后,没有达到确切的问题点。 现在在验证了系统上的随机事物之后,它就被我们使用的 websockets 逼到了墙角。
那些套接字的队列中有很多未读消息。内存使用量与消息数量成正比。通过清理队列中的消息,回收了巨大的内存。
问题:
测试操作系统版本:CentOS 7.5
-
我尝试使用 '/proc/net/sockstat' 检查套接字占用的内存 mem 列显示内存约为 300mb
-
使用 netstat -tunp 测量的 recv-Q 的总内存约为 6mb(将 recv-Q 中的数字视为字节)
但是当我清理未读消息时,我回收了大约 1.5gb 的内存。 (使用 free 命令)
还有什么要检查以获得正确的套接字内存使用情况?
这是 linux 对内存的不必要使用吗?如何进一步调试socket使用的内存?
为什么像 top 这样的 linux 工具没有列出套接字的内存使用情况?它向我们展示了进程、缓存和缓冲区的内存,但为什么不展示套接字。
其他细节: 将内存分配器更改为 jemalloc 并没有阻止这种内存增长。所以这不是与 glibc 相关的问题。
================================================ ===================
编辑信息:使用测试应用程序完成一些工作后
将我们的问题转化为一个简单的测试程序,并在不同内核版本的服务器上运行。
测试程序:每分钟有 5000 个套接字和 4 个传入消息(每条消息 3 个字节)到该套接字。还做了一些使用 ss -tm 来清楚地了解缓冲内存行为的工作。
机器 1:内核:2.6.32 /proc/sys/net/core/rmem_max=124928
开始时:免费内存:2.5gb 对于每条传入消息, ss -tm 中的 mem 每个套接字增长 512 字节。 在某些时候,套接字的内存使用量突然下降。
内存下降之前:
free -m : 空闲内存:1.1G
sockstat: TCP: inuse 6 orphan 1 tw 161 alloc 5265 mem 114138
ss -tm : mem:(r112784,w0,f1904,t0)
内存下降后:
free -m 空闲内存:2.3G
sockstat TCP: inuse 6 orphan 1 tw 157 alloc 5266 mem 8042
ss -tm mem:(r9528,w0,f952,t0)
recv-Q 中的值随着预期值不断增加。
这是“r”值达到大约等于 core/rmem_max 的点 似乎那里发生了压缩过程。
机器 2:内核:3.10.0 /proc/sys/net/core/rmem_max=212992
在这里,我预计内存将在 ~212992 时下降。但是这台机器有升级版 ss,它本身显示 rb=367360 大小。所以等待确切的压缩过程发生。
开始时:
ss -tm : skmem:(r0,rb367360,t0,tb87040,f53248,w0,o0,bl0)
sockstat: TCP: inuse 4 orphan 0 tw 97 alloc 5042 mem 4992
这里的内存也在以预期的速度不断增加。在特定时间点出现内存下降。
在内存下降点 1: 内存下降前:
free:空闲内存:2.1gb
sockstat : TCP: inuse 4 orphan 0 tw 89 alloc 5097 mem 354398
ss -tm : skmem:(r290560,rb367360,t0,tb87040,f256,w0,o0,bl0)
内存下降后:
free : 可用内存:3.1gb
sockstat : TCP: inuse 4 orphan 0 tw 93 alloc 5099 mem 187542
来到 ss -tm,这次看到了不一样的行为:
50% 的套接字具有压缩值,
skmem:(r4352,rb367360,t0,tb87040,f3840,w0,o0,bl0)
其余的有实际值(未压缩)
skmem:(r291072,rb367360,t0,tb87040,f3840,w0,o0,bl0)
所以紧缩发生在“r”值达到“rb”之前不久
接下来,等待“r”值达到“rb”
内存下降点 2 那里发生了下一个内存下降点。所有的套接字缓冲区都被压缩。(除了 100 个套接字)并回收了巨大的内存。
================================================ ===================
现在我的理解:
我们在服务器中面临的实际问题:内存占用不断增长,机器开始使用交换空间并变慢。现在在运行测试程序后,我了解到我们服务器中的可用空间不足以保持到压缩点。
我的问题:
-
这种压缩是套接字缓冲区的内置行为吗?
-
如果是,那什么时候会发生,在机器 2 中,我的体验与机器 1 中的不同?应该调整哪个值以提早进行压缩?
-
sockstat 中的“mem”值和 ss 中的“r”值加起来得出套接字占用的总内存?或者它们是不同工具列出的相同值。
(根据我的测试,我看到 (mem value sockstat + skmem buffer value) 等于释放的内存。)
【问题讨论】:
-
@stark 我想,我已经发布了那里讨论的两个类别。来自 sockstat 和队列相关内存的内存。如有遗漏请指出。谢谢。
-
正如链接帖子中所说,内存是内核内存,而不是进程内存。因此它不会显示在顶部,并且与 glibc 或其分配器无关。
-
好的,知道了。 “ss -m 是最大值(受 tcp_rmem 和 `tcp_wmem 约束),而不是当前分配的值”。我得到了一些与此信息相矛盾的输出。 skmem:(r64768,rb367360,t0,tb87040,f768,w0,o0,bl0) 这是我的套接字内存。 r64768 以字节为单位。随着这个 r 值的增加,可用内存正在减少。这是否与 /proc/sys/net/core/rmem_max. value: 212992 还知道内核将分配比 rmem_max 更多的空间来容纳额外的内核数据结构。
-
在另一台机器上使用 /proc/sys/net/core/rmem_max。值:124928,内存增长到 mem:(r111888,w0,f2800,t0) r ~= rmem_max,然后突然下降到 mem:(r9432,w0,f2856,t0) 。这是释放缓冲区中可用内存的压缩过程吗?发生这种情况时,Recv-Q 只有 7473 个字节。
标签: linux sockets memory linux-kernel centos