memory tracker 限制内存不起作用,无法防止OOM和内存上涨

  • nebula 版本:3.6.0
  • 部署方式:K8s
  • 安装方式:helm
  • 是否上生产环境:预研中
  • 硬件信息
    • 磁盘:机械硬盘
    • CPU、内存信息:332C128G,
  • 问题的具体描述:
    给storaged和graphd配置memory_tracker_limit_ratio参数,希望限制这两个服务的内存,实际无法限制住,截图如下:

graphd的配置:
image

memory tracker的日志,显示可用1.25G,已用500M:
image
看K8s的日志,内存超过limit 2G,OOM:

storaged的配置:


storaged的memory tracker日志显示可用1.25G,实际使用300Mi,使用top看,已用1.2G:

为啥。。内存不给高点呢?机器不是 128 GB 的内存么?memory tracker ratio 只给 0.01 的话,storage 和 graph 能用的总内存就 1.28 G 啊。- -,感觉还不如我的笔记本。

你看下这个参数是多少。

我看好像只有graphd有这个参数,storaged从3.6.0的文档里面没找到这个参数,我没配,应当是用的默认的0.8:

关于为什么limit_radio要设置成0.01,理由很简单,机器又不是专门跑图数据库的,当前K8s集群只能给这么点资源

刚刚确认了下,这个参数确实是使用的默认值0.8:

理论上 ratio 即便是超过了,应该是报错,而不是 OOM 的。我找研发看看啊。

现在你的模式是混的,就是nebula服务取到的系统可用内存是node的而不是容器的,这样也许会有些问题。
参考官方文档中链接的这篇文章:图数据库 NebulaGraph 的内存管理实践之 Memory Tracker
你试试改下containerized=1,然后相应的这个ratio是针对容器内可用的内存来设置,比如0.95

你说的这个我可以通过下面的例子进行反驳:
在另一台32C128G的设备上,直接宿主机使用rpm单机部署3.6.0的nebula,配置memory_track_limit_radio为0.08,换算就是1G,查看memory track的日志,显示只使用了400Mi,可用1G,然而使用top看,已经用了1.2G了,早就超过1G了

然后按照你说的,把FLAG_containerized改为true,好,我试了,还是不行,读的还是系统的,至于能不能够限制内存,我估计还是跟上面设置成0.01一样,没有任何效果:

conf里配置是:
--containerized=true
不要前面的FLAG

按照你说的,去掉了FLAG,好像确实读到的变成了K8S里limit的数值了:

我想请教下,这里的4个数值分别代表什么意思?限制内存看的是sys,还是usr,还是什么呢?

接下来我会验证下内存限制是否会生效(希望不要在出其他岔子了)

最后提个建议,这个containered参数,3.6.0的文档完全没提到,你刚刚发的那个文章里面写的也是FLAG_containered,我建议最好放到K8s部署那里进行说明下,不然碰到我这个问题后,真的很难查下去

1 个赞

sys就是系统的已用内存和总内存。
usr就是当前服务(graphd/storaged)已用内存和通过memtracker限制的可用内存。
按说是看usr来限制,你看下能否限制住吧。

文档问题,召唤 @steam 来传达

1 个赞

当我把containered =true加上之后,我发现

sys指的是当前进程(graphd或storaged)占用内存 / K8S的limit内存

usr中的使用内存这个值从哪来的我很好奇,这个值比top看到的进程实际内存要小很多,usr的总内存是
K8s的limit值 * limit_radio

所以目前我就是想弄清楚2点:

  1. 限制内存OOM是通过sys的占比限制还是usr的占比限制的
  2. usr中的已用内存数值从哪来的,很明显不是当前进程占用的内存

1 个赞
  1. 是通过usr的占比限制的;
  2. usr的已用内存值是当前正在进行的查询占用的内存的统计值,这里的确会与top看到的不一致,原因包括一下:
    1. 主要是因为这里是统计了只是查询的内存占用,除此此外,比如网络rpc,其他一些常驻服务,(比如http服务),rocksdb block cache(如果是存储节点)等也会占用内存,这些内存usr这个指标不统计;
    2. 这里统计的有一定时间间隔的,通过这个日志,可以大概了解系统/memory tracker模块观测到的内存状态,但有一定延迟 (1是主要原因,2只是理论上)
1 个赞

sys还是容器已使用的内存/limit,只是容器里主要就是nebula-storaged进程。
如codesigner所说,usr是基于进程中主要的alloc()和free()做统计的,没法精确匹配上进程实际占用内存,所以还有那个reserved的参数。我觉得你先重点关注下能否限制住。

1 个赞

好的好的,我大致理解了,我现在测一下能否限制住内存,不要超过K8s的limit资源限制

1 个赞

当前还是无法防止OOM,主要是usr的比例一直都是小于sys的比例,如图:

当前测试场景就是,K8s给graphd一个比较小的资源,然后搞个客户端,频繁执行查询操作

看上去这个sys和usr内存增长的gap有点大,截图上sys从402M到了1.6G,usr才涨到554MB不成比例, @codesigner 看看?

oom的时候,graphd进程实际占了多少内存?容器中还有其他占内存的进程吗?

为了快速验证是否OOM,K8s给graphd的资源limit为2G,因为触发了OOM,graphd进程占用肯定超过了2G,容器内部就1个graphd进程

你好,能否发下你发的query是什么类型的query?

这个我是参考这个链接里的弄的: 基于图数据库的推荐系统 - siwei.io

查询就是把这里的查询全部循环执行一遍,qps大概在4左右

用电影推荐的数据集,查询都是从这个链接里面抄的,另外还有1个写入操作,具体逻辑为循环执行:
1)创建图空间test_x
2)创建点和边
3)插入点(2W*4),边(20W*4)
4)增加点的属性 (给4个tag都alter加上2个属性)
5)更新点的属性 (给上面的8W个点更新属性)
6)删除这个图空间