[问题排查]内存相关

背景

我们经常会遇到fe或者be服务内存占用比较多的情况,本文分享下怎么排查内存被哪些对象占用

排查思路

fe 内存分析

因为fe是java程序,所以一般分析内存占用,可以使用以下指令

查看 gc 是否频繁

jstat -gcutil $pid 1000 1000

S0 — 新生代中Survivor space 0区已使用空间的百分比
S1 — 新生代中Survivor space 1区已使用空间的百分比
E — 新生代已使用空间的百分比
O — 老生代已使用空间的百分比
M — 元数据区使用比例
YGC — 从应用程序启动到当前,发生Yang GC 的次数
YGCT — 从应用程序启动到当前,Yang GC所用的时间【单位秒】
FGC — 从应用程序启动到当前,发生Full GC的次数
FGCT — 从应用程序启动到当前,Full GC所用的时间
GCT — 从应用程序启动到当前,用于垃圾回收的总时间【单位秒】

如果 S0 S1 E 这三个空间都有值的时候说明可能存在问题。因为正常情况下是每次GC后,S0区、S1区中的空间总有一个是会被完全清空(根据GC垃圾回收算法),因此S0 S1一直存在被占用时则回收不彻底,导致内存泄漏现象,随之时间拉长,甚至出现OOM

如果 FGC 一直在持续增长,说明有内存一直在申请或者没有释放,这个时候需要获取dump分析是哪些对象占用内存多
jmap -histo pid 是一个比较轻量的命令,用于查看各个对象的内存统计。

注:如果只看常驻内存的对象,要加 :live 参数: jmap -histo:live pid ,但是加上 :live 之后会触发full gc,对于内存使用比较大的进程,卡顿会很明显,生产环境慎用

be 内存分析

:warning:2.0以后的版本,一般不会再出现be服务oom的问题,如果出现则一般是因为以下两个问题

  • 基础环境参数配置不正确,例如swap未关闭、overcommit配置不正确,详情见 https://docs.starrocks.io/zh/docs/deployment/environment_configurations/
  • be服务和其他服务混合部署,BE 的配置文件 (be.conf) 中 mem_limit 配置不合理,默认是机器内存的90%,如果和其他服务混合部署,需要配置mem_limit=(机器总内存-其他服务占用内存-1~2g(系统预留))
    比如机器内存40G,上面有个Mysql,理论上限会用4G,那么配置下mem_limit=34G (40-4-2)

建议配置 prometheus+grafana监控,可以很直观的看到各个模块内存变化的趋势,参考 StarRocks监控报警配置指南

另外be也可以通过如下几个手段分析当前内存占用情况

1.metrics接口

curl -XGET -s http://BE_IP:BE_HTTP_PORT/metrics | grep "^starrocks_be_.*_mem_bytes\|^starrocks_be_tcmalloc_bytes_in_use"

主要关注以下指标

starrocks_be_clone_mem_bytes 0 ## clone tablet 使用的内存, 内存使用一般比较小
starrocks_be_compaction_mem_bytes 0 ## Compaction 内存使用
starrocks_be_load_mem_bytes 0 ## 导入内存使用
starrocks_be_process_mem_bytes 95674408 ## 我们内存统计的 BE 进程内存使用
starrocks_be_query_mem_bytes 0 ## 查询内存使用
starrocks_be_schema_change_mem_bytes 0 ## SchemaChange 内存使用
starrocks_be_storage_page_cache_mem_bytes 0 ## BE 自有 StoragePageCache 内存使用
starrocks_be_tablet_meta_mem_bytes 14249776 ## Tablet 元数据内存使用
starrocks_be_update_mem_bytes 0 ## PrimaryKey 模型内存使用

2.mem_tracker接口

http://be_ip:8040/mem_tracker

进一步查看当前有哪些查询占比高

http://be_ip:8040/mem_tracker?type=query_pool&upper_level=5

进一步查看主键模型哪些占用高

http://be_ip:8040/mem_tracker?type=update&upper_level=4

3.be日志

目前be.INFO中会每间隔15s统计当前各个模块内存占用

grep "Current memory statistics" be.INFO|less

,这是FE,leder节点top以后的占内存大小,这是统计后占用内存大小image ,单位换算总共占的内存是2.4,那fe的内存还可以怎么分析,谢谢

下面的图是 jmap -histo pid 后统计结果哈

有jvm监控吗

这边top后有很大

你好,可以出个FE内存只增不减,或者处理FE内存的文档么,上面的FE内存问题说实话帮助不大

这个应该怎么解决老师

这个文档写得有问题,即我看到了的是一大堆的内存情况,那我怎么解决?特别是内存占用高的是be和fe节点,fe节点的解决方案没给这就很让人失望。
比如我今天出现了fe节点内存飚高导致fe节点所在的机器内存告警(一直98%),我最后却只能重启fe节点,并停掉跑数任务。(我们是新上的集群,还在测试阶段)

内存问题是最要命的,导致一些数据同步任务卡死,这要是后面生产,也太危险了!

jmap -histo:live pid 老师我想触发下GC,但是触发不了 看/tmp 下的隐藏文件也没了,是代码层有什么更新么,另外我想触发这个命令,有什么办法么

刚上的时候我也是,FE内存突然飙高,然后重启才解决

fe内存当前需要借助jvm dump文件来分析看是哪部分占用。一般是因为tablet创建不合理,创建的太多导致。tablet个数和jvm的关系
100w以下,jvm 16g
100w-200w,jvm 32g
200w-500w,jvm 64g
500w-1kw,jvm 128g

老师,麻烦解决下这个问题,想要触发下GC,降下内存,着急

按照提示加下-F试试?

fe挂了!还有其他的办法么,能执行起来这个命令

还没上上产,应该到不了100W吧

挂了肯定执行不了了,
show proc ‘/statistic’;看下有多少个talet

另外如果是3.1以后的版本的话,看下fe的memory是否打开的,打开的话关闭掉

admin show frontend config like "memory_tracker_enable";

admin set frontend config ("memory_tracker_enable" = "false");
fe.conf中添加
memory_tracker_enable = false

是加了-F执行命令后挂了。。。版本是2.5.17存算一体 3FE 5BE ,三个FE都不能执行手动GC那个命令