FE节点内存溢出

Viewed 16

版本:4.1.2
内容:

  1. Doris 集群中, Arrow Flight SQL 流量的 FE 节点(如 fe-03),其 Direct Memory(堆外直接内存)单调递增,几个小时到一天内涨满 12GB,最终报错并拒绝服务:
java.lang.OutOfMemoryError: Cannot reserve 4194304 bytes of direct buffer memory... (Internal; Prepare)
  1. 单次泄漏量:FE 只要收到一条需要 Prepare 的新 SQL,就会在堆外分配约 4MBio.netty.buffer.PoolSubpage且这块内存在查询结束、甚至会话关闭后,都不会被释放

已验证无效的干预路径

  1. 缩减连接池大小(arrow_maxconnections = 4:无效。泄漏的内存挂在 FE 进程全局,并非被特定活跃连接独占。
  2. 强制高频关闭与重建连接池(recycle_seconds / recycle_queries:无效。证明 Doris 内部并未在会话(Session)销毁时联动销毁泄露的 Statement 内存。
  3. 彻底禁用连接池(arrow_use_pool = false:无效。每次查询新建独立连接、查完即断开,堆外内存依然单调上涨。
  4. 修改 Netty 分配器(unpooled):治标不治本。泄漏源自业务代码层面对 Buffer 的强引用未释放,更改 Netty 的池化策略无法回收被强引用的对象。
  5. 做了定时重启,但是又突然出现:
    1306176:
    num #instances #bytes class name (module)

1: 376158 117217360 [B (java.base@17.0.19)
2: 265337 19104264 io.netty.buffer.PoolSubpage
3: 71006 17041440 org.apache.doris.catalog.LocalReplica
4: 113024 12929744 [I (java.base@17.0.19)
5: 407213 9773112 java.lang.Long (java.base@17.0.19)
6: 121650 9707304 [Ljava.lang.Object; (java.base@17.0.19)
7: 267870 8847560 [J (java.base@17.0.19)
8: 364653 8751672 java.lang.String (java.base@17.0.19)
9: 204601 8184040 java.util.LinkedHashMap$Entry (java.base@17.0.19)
10: 3175 6355568 [Lio.netty.buffer.PoolSubpage;
11: 262144 6291456 org.apache.logging.log4j.core.async.AsyncLoggerConfigDisruptor$Log4jEventWrapper
12: 80234 5872360 [Ljava.util.HashMap$Node; (java.base@17.0.19)
13: 88895 4978120 java.util.LinkedHashMap (java.base@17.0.19)
14: 20000 4800000 org.apache.doris.statistics.AnalysisInfo
15: 28705 3446368 java.lang.Class (java.base@17.0.19)
16: 83679 2677728 java.util.concurrent.ConcurrentHashMap$Node (java.base@17.0.19)
17: 55623 2669904 com.google.gson.internal.LinkedTreeMap$Node
18: 110957 2662968 java.util.ArrayList (java.base@17.0.19)
19: 36670 2640240 java.lang.reflect.Field (java.base@17.0.19)
20: 81550 2609600 java.util.HashMap$Node (java.base@17.0.19)
21: 61208 2448320 java.util.TreeMap$Entry (java.base@17.0.19)
22: 98464 2363136 io.netty.buffer.IntPriorityQueue
23: 23702 2085776 org.apache.doris.catalog.LocalTablet
24: 16202 1685008 org.apache.doris.catalog.Column
25: 1238 1428888 [C (java.base@17.0.19)
26: 25168 1409408 com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1
27: 28309 1358832 java.util.HashMap (java.base@17.0.19)

(注:JVM 层面的 -XX:+ExplicitGCInvokesConcurrent 与调大 MaxMetaspaceSize 是有效的,它们消除了 FE 因 Full GC 风暴导致的假死卡顿,让问题单纯聚焦到了堆外内存泄漏上。)

详情:https://github.com/apache/doris/issues/65305

1 Answers

265337 19104264 io.netty.buffer.PoolSubpage
就是连接无法释放,然后在程序中的异常捕捉显示:INTERNAL: [FlightSQL] Unknown error: java.lang.OutOfMemoryError: Cannot reserve 4194304 bytes of direct buffer memory (allocated: 12881834929, limit: 12884901888) (Internal; Prepare)