排查内存溢出 (OOM) 循环
当运行中的进程消耗的内存不断增加,直到操作系统被迫终止并重启该进程时,就会出现内存溢出 (OOM) 循环。当进程被终止时,分配给该进程的内存会被释放,但重启后,它会继续占用越来越多的内存,直到周期再次重复。
在监控仪表板中,OOM 循环会显示在内存使用率 %指标中,看起来类似于下图

潜在原因
OOM 循环的原因多种多样,取决于您对 TICK 堆栈的具体使用情况,但以下是最常见的原因
未优化的查询
查询的内容和方式会极大地影响 InfluxDB 的内存使用和性能。重复执行耗尽内存的查询会导致 OOM 循环。例如,一个设置为每 30 秒刷新的仪表板单元。
选择测量指标时未指定时间范围
当从一个测量指标中进行选择而未指定时间范围时,InfluxDB 会尝试从 UNIX 纪元时间(1970 年 1 月 1 日 00:00:00 UTC)开始提取数据点,并将返回的数据存储在内存中,直到准备好输出。由于内存占用过高,操作系统最终会终止该进程。
选择测量指标时未指定时间范围的示例
SELECT * FROM "telegraf"."autogen"."cpu"解决方案
识别并更新未优化的查询
InfluxDB 中 OOM 循环最常见的原因是查询未优化,但要确定哪些查询可以进一步优化可能具有挑战性。InfluxQL 包含一些工具,可以帮助您确定查询的“成本”,并深入了解哪些查询有优化空间。
查看您的 InfluxDB 日志
如果查询被终止,InfluxDB 会将其记录下来。查看您的 InfluxDB 日志,了解哪些查询正在被终止。
估算查询成本
InfluxQL 的 EXPLAIN 语句可以解析并规划查询,然后输出预估成本的摘要。这使您能够在实际运行查询之前,估算出查询对资源的消耗程度。
EXPLAIN 语句示例
> EXPLAIN SELECT * FROM "telegraf"."autogen"."cpu"
QUERY PLAN
----------
EXPRESSION: <nil>
AUXILIARY FIELDS: cpu::tag, host::tag, usage_guest::float, usage_guest_nice::float, usage_idle::float, usage_iowait::float, usage_irq::float, usage_nice::float, usage_softirq::float, usage_steal::float, usage_system::float, usage_user::float
NUMBER OF SHARDS: 12
NUMBER OF SERIES: 108
CACHED VALUES: 38250
NUMBER OF FILES: 1080
NUMBER OF BLOCKS: 10440
SIZE OF BLOCKS: 23252999
EXPLAIN仅输出查询引擎创建的迭代器。它不会捕获查询引擎内的任何其他信息,例如实际将处理多少个点。
分析实际查询成本
InfluxQL 的 EXPLAIN ANALYZE 语句会实际执行查询并在运行时计算成本。
EXPLAIN ANALYZE 语句示例
> EXPLAIN ANALYZE SELECT * FROM "telegraf"."autogen"."cpu" WHERE time > now() - 1d
EXPLAIN ANALYZE
---------------
.
└── select
├── execution_time: 104.608549ms
├── planning_time: 5.08487ms
├── total_time: 109.693419ms
└── build_cursor
├── labels
│ └── statement: SELECT cpu::tag, host::tag, usage_guest::float, usage_guest_nice::float, usage_idle::float, usage_iowait::float, usage_irq::float, usage_nice::float, usage_softirq::float, usage_steal::float, usage_system::float, usage_user::float FROM telegraf.autogen.cpu
└── iterator_scanner
├── labels
│ └── auxiliary_fields: cpu::tag, host::tag, usage_guest::float, usage_guest_nice::float, usage_idle::float, usage_iowait::float, usage_irq::float, usage_nice::float, usage_softirq::float, usage_steal::float, usage_system::float, usage_user::float
└── create_iterator
├── labels
│ ├── measurement: cpu
│ └── shard_id: 317
├── cursors_ref: 0
├── cursors_aux: 90
├── cursors_cond: 0
├── float_blocks_decoded: 450
├── float_blocks_size_bytes: 960943
├── integer_blocks_decoded: 0
├── integer_blocks_size_bytes: 0
├── unsigned_blocks_decoded: 0
├── unsigned_blocks_size_bytes: 0
├── string_blocks_decoded: 0
├── string_blocks_size_bytes: 0
├── boolean_blocks_decoded: 0
├── boolean_blocks_size_bytes: 0
└── planning_time: 4.523978ms扩展可用内存
如果可能,请增加分配给 InfluxDB 的内存量。如果您在虚拟化或云环境中运行,可以动态扩展资源,这样做会更容易。在资源固定的环境中,这可能是一个非常难以克服的挑战。
此页面是否有帮助?
感谢您的反馈!