@fx-data/ai-diagnostics 0.1.20261026070913 → 0.1.20261107142011
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENT_SETUP.md +9 -6
- package/README.md +5 -5
- package/bin/core-ai.mjs +241 -25
- package/content/AGENTS.md +37 -57
- package/content/README.md +10 -41
- package/content/docs/architecture.md +45 -74
- package/content/docs/diagnostic-feedback.md +20 -38
- package/content/docs/diagnostic-report.md +19 -46
- package/content/docs/index.md +40 -128
- package/content/docs/scenario-guide.md +34 -52
- package/content/knowledge/README.md +49 -0
- package/content/knowledge/cases/README.md +60 -0
- package/content/knowledge/cases/dashboard-parameter-deep-binding.md +32 -0
- package/content/knowledge/common/README.md +31 -0
- package/content/knowledge/common/concepts.md +49 -0
- package/content/knowledge/common/{knowledge-applicability.md → conclusions.md} +10 -6
- package/content/knowledge/common/queries.md +98 -0
- package/content/knowledge/common/signals.md +58 -0
- package/content/knowledge/common/topics/baseline-comparison.md +23 -0
- package/content/knowledge/common/topics/large-results.md +12 -0
- package/content/knowledge/common/topics/linked-traces.md +11 -0
- package/content/knowledge/common/topics/query-budget.md +18 -0
- package/content/knowledge/common/topics/query-example.md +69 -0
- package/content/knowledge/common/topics/setup-signoz-mcp.md +102 -0
- package/content/knowledge/common/topics/start-and-anchors.md +19 -0
- package/content/knowledge/common/workflow.md +22 -0
- package/content/knowledge/component/README.md +26 -0
- package/content/knowledge/component/concepts.md +22 -0
- package/content/knowledge/component/conclusions.md +11 -0
- package/content/knowledge/component/queries.md +7 -0
- package/content/knowledge/component/signals.md +75 -0
- package/content/knowledge/component/workflow.md +23 -0
- package/content/knowledge/dashboard/README.md +31 -0
- package/content/knowledge/dashboard/concepts.md +26 -0
- package/content/knowledge/dashboard/conclusions.md +21 -0
- package/content/knowledge/dashboard/queries.md +69 -0
- package/content/knowledge/dashboard/signals.md +76 -0
- package/content/knowledge/dashboard/topics/component-comparison.md +9 -0
- package/content/knowledge/dashboard/topics/dynamic-fields.md +21 -0
- package/content/knowledge/dashboard/topics/filter-tree.md +35 -0
- package/content/knowledge/dashboard/topics/name-binding.md +9 -0
- package/content/knowledge/dashboard/workflow.md +35 -0
- package/content/knowledge/dataset/README.md +27 -0
- package/content/knowledge/dataset/concepts.md +30 -0
- package/content/knowledge/dataset/conclusions.md +11 -0
- package/content/knowledge/dataset/queries.md +7 -0
- package/content/knowledge/dataset/signals.md +61 -0
- package/content/knowledge/dataset/topics/steps.md +59 -0
- package/content/knowledge/dataset/workflow.md +27 -0
- package/content/knowledge/engine/README.md +27 -0
- package/content/knowledge/engine/concepts.md +80 -0
- package/content/knowledge/engine/conclusions.md +49 -0
- package/content/knowledge/engine/queries.md +117 -0
- package/content/knowledge/engine/signals.md +73 -0
- package/content/knowledge/engine/topics/metric-fields.md +104 -0
- package/content/knowledge/engine/topics/patterns.md +50 -0
- package/content/knowledge/engine/workflow.md +20 -0
- package/content/knowledge/signal-index.md +117 -0
- package/content/knowledge/update/README.md +39 -0
- package/content/knowledge/update/concepts.md +93 -0
- package/content/knowledge/update/conclusions.md +59 -0
- package/content/knowledge/update/queries.md +103 -0
- package/content/knowledge/update/signals.md +57 -0
- package/content/knowledge/update/topics/correlations.md +63 -0
- package/content/knowledge/update/topics/discover-executions.md +31 -0
- package/content/knowledge/update/topics/events-execution.md +136 -0
- package/content/knowledge/update/topics/events-intake.md +102 -0
- package/content/knowledge/update/topics/events-outcome.md +163 -0
- package/content/knowledge/update/topics/lifecycle.md +58 -0
- package/content/knowledge/update/topics/scene-producers.md +258 -0
- package/content/knowledge/update/workflow.md +29 -0
- package/content-manifest.json +73 -192
- package/package.json +2 -2
- package/content/.agents/skills/analyze-analysis-table-update-runtime/SKILL.md +0 -35
- package/content/.agents/skills/analyze-analysis-table-update-runtime/agents/openai.yaml +0 -7
- package/content/.agents/skills/analyze-analysis-table-update-runtime/references/discover-update-executions.md +0 -34
- package/content/.agents/skills/analyze-analysis-table-update-runtime/references/update-diagnostic-contract.md +0 -101
- package/content/.agents/skills/analyze-engine-metric/SKILL.md +0 -76
- package/content/.agents/skills/analyze-engine-metric/agents/openai.yaml +0 -13
- package/content/.agents/skills/analyze-engine-metric/scripts/analyze_engine_metric.py +0 -270
- package/content/.agents/skills/analyze-engine-metric/scripts/engine_metric_analysis/__init__.py +0 -11
- package/content/.agents/skills/analyze-engine-metric/scripts/engine_metric_analysis/metric_analyzer.py +0 -791
- package/content/.agents/skills/analyze-engine-metric/scripts/engine_metric_analysis/signoz_extract.py +0 -278
- package/content/.agents/skills/diagnose-component-performance/SKILL.md +0 -52
- package/content/.agents/skills/diagnose-component-performance/agents/openai.yaml +0 -7
- package/content/.agents/skills/diagnose-component-performance/references/experience.md +0 -34
- package/content/.agents/skills/diagnose-dashboard-performance/SKILL.md +0 -92
- package/content/.agents/skills/diagnose-dashboard-performance/agents/openai.yaml +0 -7
- package/content/.agents/skills/diagnose-dashboard-performance/references/experience.md +0 -63
- package/content/.agents/skills/diagnose-dataset-performance/SKILL.md +0 -52
- package/content/.agents/skills/diagnose-dataset-performance/agents/openai.yaml +0 -7
- package/content/.agents/skills/diagnose-dataset-performance/references/experience.md +0 -33
- package/content/.agents/skills/diagnose-performance/SKILL.md +0 -77
- package/content/.agents/skills/diagnose-performance/agents/openai.yaml +0 -7
- package/content/.agents/skills/diagnose-update-performance/SKILL.md +0 -55
- package/content/.agents/skills/diagnose-update-performance/agents/openai.yaml +0 -7
- package/content/.agents/skills/diagnose-update-performance/references/experience.md +0 -47
- package/content/.agents/skills/setup-signoz-mcp/SKILL.md +0 -30
- package/content/.agents/skills/setup-signoz-mcp/agents/openai.yaml +0 -7
- package/content/.agents/skills/setup-signoz-mcp/references/installation.md +0 -75
- package/content/.agents/skills/setup-signoz-mcp/references/windows-artifact.md +0 -14
- package/content/docs/npm-cli.md +0 -202
- package/content/docs/roadmap.md +0 -44
- package/content/docs/skill-writing-guide.md +0 -65
- package/content/knowledge/common/signoz-environments.json +0 -52
- package/content/knowledge/common/signoz-environments.md +0 -55
- package/content/knowledge/common/signoz-query-example.md +0 -41
- package/content/knowledge/common/signoz-query-policy.md +0 -145
- package/content/knowledge/common/trace-routing.md +0 -63
- package/content/knowledge/component/observability.md +0 -60
- package/content/knowledge/dashboard/observability.md +0 -168
- package/content/knowledge/dashboard/query-examples.md +0 -63
- package/content/knowledge/dataset/observability.md +0 -68
- package/content/knowledge/engine/metric-artifacts.md +0 -25
- package/content/knowledge/engine/metric-retrieval.md +0 -107
- package/content/knowledge/engine/metric-semantics.md +0 -172
- package/content/knowledge/engine/performance-patterns.md +0 -86
- package/content/knowledge/update/diagnostic/manifest.json +0 -209
- package/content/knowledge/update/diagnostic/observability/edges/edge-attempt-to-capacity-deferral.json +0 -17
- package/content/knowledge/update/diagnostic/observability/edges/edge-attempt-to-lock-requeue.json +0 -18
- package/content/knowledge/update/diagnostic/observability/edges/edge-attempt-to-merge.json +0 -17
- package/content/knowledge/update/diagnostic/observability/edges/edge-candidate-to-effective-root.json +0 -16
- package/content/knowledge/update/diagnostic/observability/edges/edge-capacity-deferral-to-attempt.json +0 -16
- package/content/knowledge/update/diagnostic/observability/edges/edge-chain-node-to-execution-detail.json +0 -18
- package/content/knowledge/update/diagnostic/observability/edges/edge-dlx-recovery-to-attempt.json +0 -16
- package/content/knowledge/update/diagnostic/observability/edges/edge-effective-execution-to-listener-before.json +0 -21
- package/content/knowledge/update/diagnostic/observability/edges/edge-effective-root-to-chain.json +0 -17
- package/content/knowledge/update/diagnostic/observability/edges/edge-engine-task-to-primary-result.json +0 -17
- package/content/knowledge/update/diagnostic/observability/edges/edge-execution-detail-to-publication.json +0 -16
- package/content/knowledge/update/diagnostic/observability/edges/edge-init-recovery-to-publication.json +0 -16
- package/content/knowledge/update/diagnostic/observability/edges/edge-listener-complete-to-child-release.json +0 -21
- package/content/knowledge/update/diagnostic/observability/edges/edge-listener-to-derived-chain.json +0 -21
- package/content/knowledge/update/diagnostic/observability/edges/edge-load-decision-to-load-operation.json +0 -16
- package/content/knowledge/update/diagnostic/observability/edges/edge-load-operation-to-engine-task.json +0 -17
- package/content/knowledge/update/diagnostic/observability/edges/edge-lock-requeue-to-attempt.json +0 -16
- package/content/knowledge/update/diagnostic/observability/edges/edge-logical-parent-to-child.json +0 -18
- package/content/knowledge/update/diagnostic/observability/edges/edge-merge-member-to-effective-execution.json +0 -18
- package/content/knowledge/update/diagnostic/observability/edges/edge-merge-to-load-decision.json +0 -17
- package/content/knowledge/update/diagnostic/observability/edges/edge-no-load-to-primary-result.json +0 -16
- package/content/knowledge/update/diagnostic/observability/edges/edge-primary-result-to-child-frontier.json +0 -18
- package/content/knowledge/update/diagnostic/observability/edges/edge-primary-result-to-listener.json +0 -23
- package/content/knowledge/update/diagnostic/observability/edges/edge-publication-to-attempt.json +0 -16
- package/content/knowledge/update/diagnostic/observability/edges/edge-ready-recovery-to-publication.json +0 -16
- package/content/knowledge/update/diagnostic/observability/edges/edge-request-to-candidate-root.json +0 -16
- package/content/knowledge/update/diagnostic/observability/identity-units/candidate-root.json +0 -13
- package/content/knowledge/update/diagnostic/observability/identity-units/dag-node.json +0 -14
- package/content/knowledge/update/diagnostic/observability/identity-units/effective-root.json +0 -14
- package/content/knowledge/update/diagnostic/observability/identity-units/engine-task.json +0 -13
- package/content/knowledge/update/diagnostic/observability/identity-units/execution-attempt.json +0 -12
- package/content/knowledge/update/diagnostic/observability/identity-units/execution-detail.json +0 -13
- package/content/knowledge/update/diagnostic/observability/identity-units/listener-invocation.json +0 -11
- package/content/knowledge/update/diagnostic/observability/identity-units/load-decision.json +0 -12
- package/content/knowledge/update/diagnostic/observability/identity-units/load-operation.json +0 -11
- package/content/knowledge/update/diagnostic/observability/identity-units/logical-dag-edge.json +0 -11
- package/content/knowledge/update/diagnostic/observability/identity-units/merge-decision.json +0 -12
- package/content/knowledge/update/diagnostic/observability/identity-units/node-primary-result.json +0 -12
- package/content/knowledge/update/diagnostic/observability/identity-units/queue-publication.json +0 -11
- package/content/knowledge/update/diagnostic/observability/identity-units/requeue.json +0 -11
- package/content/knowledge/update/diagnostic/observability/identity-units/update-chain.json +0 -13
- package/content/knowledge/update/diagnostic/observability/identity-units/update-request.json +0 -12
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-after-commit-delivery.json +0 -131
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-attempt-consumed.json +0 -175
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-candidate-root-filter.json +0 -119
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-capacity-deferred.json +0 -121
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-child-release.json +0 -146
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-dlx-recovery.json +0 -100
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-effective-root-selection.json +0 -111
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-engine-handoff.json +0 -171
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-execution-frontier-persisted.json +0 -115
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-init-recovery.json +0 -93
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-intent-accepted.json +0 -151
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-listener-derived-chain.json +0 -112
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-listener-invocation.json +0 -154
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-load-decision.json +0 -155
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-load-operation.json +0 -108
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-lock-requeued.json +0 -108
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-logical-dependency-expansion.json +0 -129
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-merge-decision.json +0 -174
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-primary-node-result.json +0 -318
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-ready-recovery.json +0 -92
- package/content/knowledge/update/diagnostic/observability/performance-segments/analysis-update-segment-business-attempt.json +0 -33
- package/content/knowledge/update/diagnostic/observability/performance-segments/analysis-update-segment-capacity-cycle.json +0 -31
- package/content/knowledge/update/diagnostic/observability/performance-segments/analysis-update-segment-child-release.json +0 -32
- package/content/knowledge/update/diagnostic/observability/performance-segments/analysis-update-segment-commit-publication.json +0 -29
- package/content/knowledge/update/diagnostic/observability/performance-segments/analysis-update-segment-control-planning.json +0 -30
- package/content/knowledge/update/diagnostic/observability/performance-segments/analysis-update-segment-engine-task.json +0 -27
- package/content/knowledge/update/diagnostic/observability/performance-segments/analysis-update-segment-listener-callback.json +0 -27
- package/content/knowledge/update/diagnostic/observability/performance-segments/analysis-update-segment-load-operation.json +0 -27
- package/content/knowledge/update/diagnostic/observability/performance-segments/analysis-update-segment-lock-cycle.json +0 -31
- package/content/knowledge/update/diagnostic/observability/performance-segments/analysis-update-segment-main-queue-wait.json +0 -32
- package/content/knowledge/update/diagnostic/observability/performance-segments/analysis-update-segment-merge-evaluation.json +0 -29
- package/content/knowledge/update/diagnostic/observability/performance-segments/analysis-update-segment-parent-dependency-wait.json +0 -31
- package/content/knowledge/update/diagnostic/observability-index.json +0 -558
- package/content/knowledge/update/diagnostic/recipe-index.json +0 -85
- package/content/knowledge/update/diagnostic/recipes/dag-chain.json +0 -676
- package/content/knowledge/update/diagnostic/recipes/performance-window.json +0 -1128
- package/content/knowledge/update/diagnostic/recipes/scene-origin-async-message-or-callback.json +0 -438
- package/content/knowledge/update/diagnostic/recipes/scene-origin-derived-update-chain.json +0 -510
- package/content/knowledge/update/diagnostic/recipes/scene-origin-direct-service-call.json +0 -438
- package/content/knowledge/update/diagnostic/recipes/scene-origin-http.json +0 -438
- package/content/knowledge/update/diagnostic/recipes/scene-origin-internal-event.json +0 -438
- package/content/knowledge/update/diagnostic/recipes/scene-origin-job.json +0 -438
- package/content/knowledge/update/diagnostic/recipes/scene-origin-recovery-or-migration.json +0 -438
- package/content/knowledge/update/diagnostic/recipes/table-history.json +0 -508
- package/content/knowledge/update/diagnostic/recipes/table-in-chain.json +0 -595
- package/content/knowledge/update/diagnostic/scene-index.json +0 -252
- package/content/knowledge/update/diagnostic/scenes/active.json +0 -47
- package/content/knowledge/update/diagnostic/scenes/add.json +0 -140
- package/content/knowledge/update/diagnostic/scenes/agent.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/archive.json +0 -32
- package/content/knowledge/update/diagnostic/scenes/auth-change.json +0 -116
- package/content/knowledge/update/diagnostic/scenes/call-back.json +0 -32
- package/content/knowledge/update/diagnostic/scenes/case-install.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/case-replace.json +0 -7
- package/content/knowledge/update/diagnostic/scenes/cdc-schedule.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/compute-model.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/copy-data.json +0 -32
- package/content/knowledge/update/diagnostic/scenes/corp-linked.json +0 -7
- package/content/knowledge/update/diagnostic/scenes/corp-member-add.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/corp-member-del.json +0 -7
- package/content/knowledge/update/diagnostic/scenes/corp-member-modify.json +0 -32
- package/content/knowledge/update/diagnostic/scenes/corp-member-sync.json +0 -152
- package/content/knowledge/update/diagnostic/scenes/corp-setting-member-rename.json +0 -152
- package/content/knowledge/update/diagnostic/scenes/corp-setting.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/cross-project-allow.json +0 -32
- package/content/knowledge/update/diagnostic/scenes/default.json +0 -32
- package/content/knowledge/update/diagnostic/scenes/del.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/dynamic-time.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/edit.json +0 -92
- package/content/knowledge/update/diagnostic/scenes/excel-append.json +0 -44
- package/content/knowledge/update/diagnostic/scenes/excel-save.json +0 -32
- package/content/knowledge/update/diagnostic/scenes/folder-copy.json +0 -32
- package/content/knowledge/update/diagnostic/scenes/global.json +0 -56
- package/content/knowledge/update/diagnostic/scenes/handover.json +0 -32
- package/content/knowledge/update/diagnostic/scenes/history-handle.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/manual-update.json +0 -44
- package/content/knowledge/update/diagnostic/scenes/migration.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/param-change.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/polars-error.json +0 -32
- package/content/knowledge/update/diagnostic/scenes/preview-exception.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/preview-invalid.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/project-excel-move.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/re-check.json +0 -7
- package/content/knowledge/update/diagnostic/scenes/replace.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/rollback.json +0 -68
- package/content/knowledge/update/diagnostic/scenes/save-as.json +0 -44
- package/content/knowledge/update/diagnostic/scenes/schedu.json +0 -56
- package/content/knowledge/update/diagnostic/scenes/table-move-other-workspace.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/user-holder-to-normal.json +0 -20
- package/content/knowledge/update/observability.md +0 -16
- package/content/knowledge/update/runtime-evidence.md +0 -32
- package/content/scripts/receive_tool_result.py +0 -57
- /package/content/{.agents/skills/setup-signoz-mcp/scripts → scripts}/install_signoz_mcp.ps1 +0 -0
- /package/content/{.agents/skills/setup-signoz-mcp/scripts → scripts}/install_signoz_mcp.py +0 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# 分析表 · 排查入口
|
|
2
|
+
|
|
3
|
+
分析表预览或步骤计算慢、失败时从这里下手。要判断的是:问题出在这次预览或步骤计算本身、依赖的资源、上游更新,还是引擎执行。概念看[概念](concepts.md),入口和信号看[信号](signals.md),能下什么结论看[结论](conclusions.md),写查询看[查询](queries.md)。
|
|
4
|
+
|
|
5
|
+
## 入手
|
|
6
|
+
|
|
7
|
+
- 先分清编辑预览、查看结果和后台更新,这三种不是同一次执行。用户已经说了 OOM、内存超限或失败,先按同一张表、同一时间窗和失败签名把精确命中的执行都找出来,再标是哪一种;不因执行类型不同而请求消歧。
|
|
8
|
+
- 记下表、选中的步骤、环境、时间窗和配置版本。手上有精确的 trace 或请求,就围绕它分析。
|
|
9
|
+
- 现象比较笼统时,把候选执行按类型和成功、失败粗分一下。不要从最慢的成功预览直接推断用户目标。
|
|
10
|
+
- 报错落在引擎里(内存超限、行数超限、超时)时,引擎只说明撞了什么线,原因要回到步骤里找:哪一步把数据放大了,或者要攒齐整批数据,见[分析步骤](topics/steps.md#哪些步骤容易慢或爆内存)。
|
|
11
|
+
- 慢或失败的分析表查询,可以看[引擎知识](../engine/workflow.md)解释物理上怎么算的;线索指向后台更新或组件、仪表板,就转到[更新](../update/workflow.md)或对应的域。
|
|
12
|
+
|
|
13
|
+
## 常见现象与候选假设
|
|
14
|
+
|
|
15
|
+
下面这些经验用来提假设,根因还得靠这次的日志和 trace 确认。
|
|
16
|
+
|
|
17
|
+
- **预览里某个步骤突然变慢**:先按 `operatorType` 在[分析步骤](topics/steps.md)里看这一步是什么类型、会不会放大行数或要攒齐整批数据。可能是加了分组很多的分类汇总、排序、左右合并,或累积值、排名这类新增字段;可能预览用的配置版本和用户说的不一样;也可能是引擎阶段占了大头。对比一下相邻步骤的耗时,再确认真正选中的步骤和配置版本。
|
|
18
|
+
- **预览或更新报内存超限、行数超限**:多半是某一步把数据放大了。在 Metric 计划树里从读表往下看各节点的输出行数,行数突然变多的 `JoinNode`(左右合并、同环比)、`UnnestNode`(拆分到行、列转行),或者内存很大的窗口、汇总节点,就是放大点,再对回页面上的第几步。建议落在这一步上,比如检查连接键是否有重复、把筛选挪到前面。
|
|
19
|
+
- **整张分析表一直很慢**:慢点可能在基础数据读取或共享上游,而不在最后一个操作;可能上游更新没完成、失败了或者产物是旧的;也可能同一个 tableId 在问题时间窗里有好几次执行。先分清前台预览和后台更新,再看依赖表的状态和资源版本。
|
|
20
|
+
|
|
21
|
+
## 易错点
|
|
22
|
+
|
|
23
|
+
- 静态配置只能说明可能怎么算,说明不了这一次怎么算的。
|
|
24
|
+
- 前台预览和后台更新可能共享计算逻辑,但不是同一次运行。失败签名和计算链路一样时可以放在一起分析,但每条记录要带着自己的执行类型、trace 和 task,避免串线。
|
|
25
|
+
- 时间挨着的成功 trace 不能拿来替用户报告的那次问题执行。
|
|
26
|
+
- 资源链接只能确定调查对象,判断不了用户关心的是预览慢、更新失败还是资源超限。
|
|
27
|
+
- 表状态异常时,要有对应的更新运行记录,才能说更新是根因。
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# 引擎知识
|
|
2
|
+
|
|
3
|
+
引擎执行统计(Metric):怎样定位执行并取得正文,字段含义,以及怎样解读耗时、内存和数据规模。
|
|
4
|
+
|
|
5
|
+
## 槽位
|
|
6
|
+
|
|
7
|
+
每个知识域都按同样的槽位组织。按要做的事选槽位,只读命中的章节。
|
|
8
|
+
|
|
9
|
+
| 要做什么 | 读 | 包含 |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| 拿到一次引擎执行,从哪里入手 | [workflow.md](workflow.md) | 引擎排查入口:获取、读取 Metric 正文、解释时的提示 |
|
|
12
|
+
| 弄清概念是什么、怎么关联 | [concepts.md](concepts.md) | Metric 的适用范围与执行结构(Pipeline、Operator 及其关系) |
|
|
13
|
+
| 认出入口,看懂 span、attribute、日志和字段 | [signals.md](signals.md) | 时间、内存、数据规模与 Operator 信号的含义 |
|
|
14
|
+
| 看完日志和 trace,能下什么结论 | [conclusions.md](conclusions.md) | 变化原因与失败原因怎样判断;推荐分析顺序;怎样读取和引用原文 |
|
|
15
|
+
| 写查询、选取证路径 | [queries.md](queries.md) | 由问题选择执行、关联 trace 与 task、获取 Metric 正文、处理响应 |
|
|
16
|
+
|
|
17
|
+
## 展开明细
|
|
18
|
+
|
|
19
|
+
| 文件 | 何时读 | 内容 |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| [topics/metric-fields.md](topics/metric-fields.md) | 拿到 Metric 正文、不知道某个字段什么意思或该先看哪层时 | Metric 正文结构;任务、Pipeline、算子、读表和输出各层字段及诊断用法 |
|
|
22
|
+
| [topics/patterns.md](topics/patterns.md) | 按现象判断引擎机制时(扫描、Join、聚合、排序窗口、Spill、Exchange、编译等) | 常见引擎性能问题与反证 |
|
|
23
|
+
|
|
24
|
+
## 关联
|
|
25
|
+
|
|
26
|
+
- 相关知识域:[分析表](../dataset/README.md)、[组件](../component/README.md)、[仪表板](../dashboard/README.md)、[更新](../update/README.md):从各场景进入引擎排查
|
|
27
|
+
- 相关知识域:[通用](../common/README.md):MetricOuts 的服务过滤与查询规则
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# 引擎 · 概念与关联
|
|
2
|
+
|
|
3
|
+
回答“这是什么、彼此怎么关联”。
|
|
4
|
+
|
|
5
|
+
## 作用与适用范围
|
|
6
|
+
|
|
7
|
+
说明 MPP 节点 Metric 里执行结构、耗时、内存和数据规模的含义。怎么取 Metric 见[获取方法](queries.md);具体异常查[常见性能问题](topics/patterns.md);引用口径见[能下什么结论](conclusions.md#读取与引用原文的口径)。只解释这次 Metric 里出现的字段,不补造数值或执行关系;没有执行明细(`stage_infos`)的 Metric 不套用 Pipeline/Operator 规则。
|
|
8
|
+
|
|
9
|
+
## 执行结构
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
analyzed info(逻辑计划)
|
|
13
|
+
-> SubPlans(物理计划,按片段分)
|
|
14
|
+
-> stage_infos -> task@...(本次运行实例)
|
|
15
|
+
-> pipeline@N
|
|
16
|
+
-> Operator(<scan> / <proc> / <sink>)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
- Operator 名字后的 `[编号]` 对应物理计划节点的 `nodeId`,不是页面上的步骤编号。
|
|
20
|
+
- 同一物理节点常拆成多条 Pipeline(如关联的建表和探测),不同 Task 也可能执行同一节点。先按 Stage、Task、Pipeline 分清运行实例;名字或编号相同、文本相邻都证明不了是同一实例或数据直连。
|
|
21
|
+
- 跨片段的数据交换看 `sourceFragmentId`、`sinkFragmentId` 和明确的 remote input,SubPlan 的层级本身说明不了输入来源。
|
|
22
|
+
- 并行 Pipeline 的时间会重叠,没有时间线时不能把耗时排名当成串行关键路径。
|
|
23
|
+
|
|
24
|
+
### Metric 里常见的名字
|
|
25
|
+
|
|
26
|
+
线上查询和更新都跑在 MPP 节点上。一个任务的 Metric 是一条日志,从上到下依次是任务摘要、逻辑计划、物理计划、查询汇总,耗时或内存超过门槛的任务后面还有 `stage_infos` 执行明细(结构和字段见[Metric 字段速查](topics/metric-fields.md))。名字分三层,按层看:
|
|
27
|
+
|
|
28
|
+
1. **逻辑计划**(`analyzed info:` 下面,名字以 `Node` 结尾,缩进越深越靠近读表):
|
|
29
|
+
|
|
30
|
+
| 节点 | 大致是什么 |
|
|
31
|
+
|---|---|
|
|
32
|
+
| `DataSourceNode [dataSource=PolarsLakeTableDataSource[<表>]]` | 读一张表;`dataSource=CTE_1` 表示读的是复用的中间结果 |
|
|
33
|
+
| `ProjectNode` | 选列、改名、算表达式(公式类新增字段、字段设置、脱敏大多在这) |
|
|
34
|
+
| `FilterNode` | 筛选 |
|
|
35
|
+
| `JoinNode [type=LEFT on=[...]]` | 关联,`type` 是合并方式,`on` 是连接键 |
|
|
36
|
+
| `AggregateNode [group=[...] agg=[...]]` | 分组汇总 |
|
|
37
|
+
| `UnionNode` | 上下合并 |
|
|
38
|
+
| `SortNode` | 排序 |
|
|
39
|
+
| `UnnestNode` | 一行拆成多行(拆分到行、列转行) |
|
|
40
|
+
| `WindowNode` | 窗口计算,带 `over(partition by ... order by ...)`,比如累计 |
|
|
41
|
+
| `WindowBINode` | 窗口计算,`groupingKeys`、`orders` 指定分组和排序,常见的是整组汇总 |
|
|
42
|
+
| `LimitNode [limit: ..., offset: ...]` | 截取行数,预览、组件只取一页就在这里 |
|
|
43
|
+
| `OutputNode` / `Destination Node [...(WRITE)]` | 返回结果 / 写入目标表(更新任务) |
|
|
44
|
+
|
|
45
|
+
同一份中间结果被引用多次时,计划里会多出一段 `CTE [CTE_1]`,后面的 `DataSourceNode [dataSource=CTE_1]` 读它。
|
|
46
|
+
|
|
47
|
+
2. **物理计划**(`SubPlans:` 下面,名字是 `PHYSICAL_*`,按片段 `SubPlan: [Id: F00]` 分):优化器会改写、合并逻辑节点,个数对不上是正常的。每个节点带 `nodeId`,和下面 Operator 名字后方括号里的编号对应(如 `LakeConnectorSource@... [30]` 就是 `nodeId: 30` 那个读表节点)。
|
|
48
|
+
|
|
49
|
+
| 节点 | 大致是什么 |
|
|
50
|
+
|---|---|
|
|
51
|
+
| `PHYSICAL_TABLE_SCAN` | 读表,`predicate` 是下推到读表时的条件 |
|
|
52
|
+
| `PHYSICAL_FILTER`、`PHYSICAL_PROJECT` | 过滤、算表达式 |
|
|
53
|
+
| `PHYSICAL_HASH_JOIN` | 等值关联,`joinType`、`eqOnPredicate` 是方式和连接键 |
|
|
54
|
+
| `PHYSICAL_NEST_LOOP_JOIN` | 按名字看是逐行比对的关联,一般出现在没有等值连接键时;数据大时很重 |
|
|
55
|
+
| `PHYSICAL_HASH_AGGREGATE` | 分组汇总 |
|
|
56
|
+
| `PHYSICAL_AGGREGATE_TOPN`、`PHYSICAL_TOPN` | 汇总后排序取前 N 合成一步 / 排序取前 N |
|
|
57
|
+
| `PHYSICAL_UNION`、`PHYSICAL_UNNEST` | 上下合并、拆行 |
|
|
58
|
+
| `PHYSICAL_UNSORTED_WINDOW` | 不排序的窗口计算 |
|
|
59
|
+
| `PHYSICAL_CTE_PRODUCE` / `PHYSICAL_CTE_CONSUME` / `PHYSICAL_CTE_ANCHOR` | 中间结果算一次、多处读取 |
|
|
60
|
+
| `PHYSICAL_ROW_RESTRICT [rowRestrict: N]` | 行数上限保护:优化器插在读表、合并、汇总、关联等节点后面,中间结果超过 N 行就失败。N 按企业配置,以计划里写的为准;不是预览分页 |
|
|
61
|
+
| `PHYSICAL_LIMIT`、`PHYSICAL_OUTPUT`、`PHYSICAL_DESTINATION` | 截取、返回结果、写表 |
|
|
62
|
+
|
|
63
|
+
3. **Pipeline 里的 Operator**(`<scan>`、`<proc>`、`<sink>` 开头,下面带 `output_rows_num`、内存等指标;只有记录了执行明细的任务才有)。一个物理节点常拆成 sink 和 scan 两端,分在前后两条 Pipeline 里:
|
|
64
|
+
|
|
65
|
+
| Operator | 大致是什么 |
|
|
66
|
+
|---|---|
|
|
67
|
+
| `LakeConnectorSource` | 读表数据 |
|
|
68
|
+
| `Filter`、`Project`、`RowRestrict`、`Union`、`Unnest`、`Limit` | 同名的物理节点 |
|
|
69
|
+
| `ParallelHashJoinSink` → `ParallelHashJoin` | 关联:前者把一边建成哈希表(看 `hash_table_size`),后者拿另一边去探测并输出 |
|
|
70
|
+
| `CrossJoin` | 没有等值键的关联 |
|
|
71
|
+
| `FinalPreHashAggregate` → `FinalMergeHashAggregate` | 汇总:先在各线程局部汇总,再合并成最终结果 |
|
|
72
|
+
| `AggregateTopNSink` → `AggregateTopNMerge`、`TopNSink` → `TopNMerge`、`ParallelSortSink` → `ParallelSortPreSort` | 汇总取前 N、取前 N、排序 |
|
|
73
|
+
| `WindowBiAggregateUnnest` | 不排序的窗口计算 |
|
|
74
|
+
| `Cte` | 中间结果复用:sink 端写、scan 端读,`temp_table_*_allocated` 是它占的内存 |
|
|
75
|
+
| `BlockOutput`、`BlockOutputFlush` | 查询结果输出 |
|
|
76
|
+
| `LakeConnectorSink`、`ConnectorSinkFlush` | 更新任务写表 |
|
|
77
|
+
|
|
78
|
+
上面是按名字和线上 MPP Metric 的大致理解,没列出的名字按字面理解即可;判断时以这个节点或 Operator 自己的行数、内存和耗时为准。
|
|
79
|
+
|
|
80
|
+
先定位异常任务和 Pipeline,再查看其中的 Operator、物理节点和数据条件。不要因为某个 Operator 名称看起来昂贵,就跳过本次运行指标直接判定根因。
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# 引擎 · 能下什么结论
|
|
2
|
+
|
|
3
|
+
回答“手上的日志、trace 和 Metric 能说明什么、不能说明什么,结论能下到哪一步”。
|
|
4
|
+
|
|
5
|
+
## 变化原因与失败原因
|
|
6
|
+
|
|
7
|
+
用户问“为什么这次失败、之前却成功”时,分五层说:
|
|
8
|
+
|
|
9
|
+
1. 本次变化:和成功执行或基线比,进入某个 Operator 的数据或输出规模变了多少;
|
|
10
|
+
2. 膨胀位置:哪个 Operator 把输入放大成更大的中间结果;
|
|
11
|
+
3. 资源压力位置:哪些 Pipeline 或 Operator 的状态承接了这份工作量;
|
|
12
|
+
4. 直接失败条件:同 task 错误确认的内存上限、超时、行数上限等;
|
|
13
|
+
5. 根因层次:只到执行层,还是已经对上了具体业务计算(哪个步骤、哪个绑定)。
|
|
14
|
+
|
|
15
|
+
单份失败 Metric 只能说明第 2~4 层,证明不了第 1 层。两侧 Metric 都完整、同一 Operator 能稳定对齐时,输入输出的变化才能当作这次的触发因素。资源上限是原因链末端,Operator 放大是执行机制,都不单独叫根因。
|
|
16
|
+
|
|
17
|
+
| Operator 类别 | 常见候选机制 | 这次至少要看到什么 |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| 读表 | IO 慢、文件多、读得多 | 扫描行列和字节、读取耗时、任务分布 |
|
|
20
|
+
| 筛选 / 表达式 | 表达式计算量大、列宽、没有下推 | 输入输出规模、物理计划里的表达式、CPU |
|
|
21
|
+
| 汇总 | 分组多、状态大、落盘 | 输入输出行数、哈希表、内存或 spill |
|
|
22
|
+
| 关联 | 建表侧过大、输出放大、分支不均 | 两侧规模、哈希表、输出规模、连接方式 |
|
|
23
|
+
| 排序 / TopN / 窗口 | 状态随数据增长 | 输入规模、排序或窗口配置、内存 |
|
|
24
|
+
| 上下合并 / 交换 / 输出 | 某个分支慢、交换等待、下游背压 | 所有输入分支、blocked、输出信号 |
|
|
25
|
+
|
|
26
|
+
表里的机制只用来选方向,不能按 Operator 名字直接认定根因。
|
|
27
|
+
|
|
28
|
+
## 推荐分析顺序
|
|
29
|
+
|
|
30
|
+
1. 确认是完整明细还是只有摘要,先报任务状态和阶段耗时;
|
|
31
|
+
2. 找出少量异常 Pipeline,分清 wall、blocked、内存各是什么口径;
|
|
32
|
+
3. 读 Pipeline 里 Operator 的数据规模和专项指标;
|
|
33
|
+
4. 用 Operator 后面的编号对上物理计划节点,说明是什么计算;
|
|
34
|
+
5. 把热点和这次的数据条件、资源上限、用户现象连起来;
|
|
35
|
+
6. 分开写“看到的事实”“关联判断”“待验证的候选机制”。
|
|
36
|
+
|
|
37
|
+
排名靠前只决定先查谁,不等于已经证明是根因。
|
|
38
|
+
|
|
39
|
+
## 读取与引用原文的口径
|
|
40
|
+
|
|
41
|
+
Metric 是缩进的 `key=value` 文本,先看任务状态,再沿 Pipeline 找相关 Operator,不要整份通读。引用数字保留原值、单位和所在的 Task、Pipeline、Operator。
|
|
42
|
+
|
|
43
|
+
- **展示范围**:只看了前几名时要说明范围有限,没进前几名的节点也可能放大数据或占内存。
|
|
44
|
+
- **排名和合计**:不同字段、单位、口径的值不合计,也不直接当根因或同时驻留量。同名算子出现多次,不等于有多少次独立的关联或扫描。
|
|
45
|
+
- **输入输出比例**:只有同一个 Operator 明确给出输入和输出、单位和口径一致、没有 `-1` 时才算差值或倍数;缺输入、单位不明、负值、零分母各自说明,不用相邻节点的输出代替输入,也不跨关联、汇总、上下合并、交换手算放大率。
|
|
46
|
+
- **内存字段**:Pipeline 关闭快照、内存上限、`astSizeBytes`、IO 字节都不是算子内存;各类 arena、allocated、deallocated、peak、current 分开记来源,不相加。
|
|
47
|
+
- **单位**:`TaskStateTime` 是毫秒;别处没写单位的值保留原样,不自行当毫秒。
|
|
48
|
+
- **快照**:任务摘要和执行明细是不同时刻的快照,不拼成最终值;`RUNNING` 的摘要只是当时的状态。
|
|
49
|
+
- **两次执行的比较**:先配对唯一同名的 task(用户各给一份时可以配不同名的),Operator 优先按编号对齐;对不上的标成未匹配或有歧义,不取第一条或最后一条。缺失、`-1`、单位不同的不算差值。配对只确认材料对应,业务条件是否可比另外核对。
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# 引擎 · 查询方法
|
|
2
|
+
|
|
3
|
+
engine Metric 用来解释已经锁定的执行:这次计算处理了多少数据、耗时和内存花在哪、因为什么失败。这里写怎么从 trace 找到任务、怎么取 Metric 正文;字段含义见[Metric 字段速查](topics/metric-fields.md),判读口径见[能下什么结论](conclusions.md)。环境、时间、预算和大结果遵守[公共查询规则](../common/queries.md)。慢或失败的引擎执行通常值得读一下 Metric,明确没提交的除外。
|
|
4
|
+
|
|
5
|
+
## 目录
|
|
6
|
+
|
|
7
|
+
- [材料能说明什么](#材料能说明什么)
|
|
8
|
+
- [已有 trace 时取哪些字段](#已有-trace-时取哪些字段)
|
|
9
|
+
- [V1 查询埋点与完成边界](#v1-查询埋点与完成边界)
|
|
10
|
+
- [更新 Write 链路](#更新-write-链路)
|
|
11
|
+
- [由问题选择执行](#由问题选择执行)
|
|
12
|
+
- [Metric 链接与任务日志](#metric-链接与任务日志)
|
|
13
|
+
- [正文获取与响应处理](#正文获取与响应处理)
|
|
14
|
+
- [读取大正文](#读取大正文)
|
|
15
|
+
- [数据规模](#数据规模)
|
|
16
|
+
- [任务属性缺失时](#任务属性缺失时)
|
|
17
|
+
|
|
18
|
+
## 材料能说明什么
|
|
19
|
+
|
|
20
|
+
- 业务请求和页面配置:这次想算什么。trace:各阶段耗时和上下游关系。
|
|
21
|
+
- task ID:区分具体计算和每次重试。任务 ID 和 Metric 链接可能在提交前就生成了,单独证明不了已经开始算。
|
|
22
|
+
- Metric:只有摘要时,解释限于摘要里有的内容;有执行明细才有 Pipeline 和 Operator。
|
|
23
|
+
|
|
24
|
+
引擎物理节点不能直接当成页面步骤。没有业务配置或明确对应关系时,结论停在执行层。
|
|
25
|
+
|
|
26
|
+
## 已有 trace 时取哪些字段
|
|
27
|
+
|
|
28
|
+
定位任务要 `name`、`trace_id`、`span_id`、`parent_span_id`、`timestamp`、`duration_nano`、`has_error`、`status_message`,业务服务已确认时保留 `service.name` 过滤。便捷搜索和详情工具不返回自定义属性,要用 Query Builder 按 `trace_id` 加 span 名,在 `selectFields` 里点名下表字段(见[原始查询例子](../common/topics/query-example.md))。
|
|
29
|
+
|
|
30
|
+
| span | 任务与统计字段 | 说明 |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| `QueryExecutor` | `taskName`、`metric` | 前台查询;不要求固定的父 span 名 |
|
|
33
|
+
| `v2.execute.query` | `polars.taskId`、`polars.submit.ts`、`query.id`、`metric` | 失败时可能没有链接 |
|
|
34
|
+
| `DataFlowExecutor → execute` | `taskName`、`metric`、`compute.retry.pipeline_parallelism_reduced` | 更新写入,保留父记录 |
|
|
35
|
+
|
|
36
|
+
`metric` 属性本身就是一条现成的日志查询链接(见[Metric 链接与任务日志](#metric-链接与任务日志))。也可以先按 `trace_id` 查一次日志,task 常在日志里:`[QueryRecord] query record cost ...ms, taskName:[<task>]`,失败时 `Query(type:COMPONENT, id:<task>, ...) failed! cost = [execute:...ms]`(`type` 还可能是 `PREVIEW` 等)。
|
|
37
|
+
|
|
38
|
+
只定位任务时,span 可以限定为 `update`、`DataFlowExecutor`、`execute`、`QueryExecutor`、`v2.execute.query`,同 trace 的所有形态和尝试都留着;这代替不了业务时间线。每次重试都有自己的 task ID,不合并成一次执行。
|
|
39
|
+
|
|
40
|
+
```text
|
|
41
|
+
trace_id = '<trace>' AND service.name = '<已确认业务服务>'
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
已选定执行 span 时可加 `span_id = '<执行span>'`(外层 HTTP span 不是任务 span)。只补任务属性时复用已有父子关系,不为一个字段重新取整条 trace。数值和布尔字段的 `fieldDataType` 按工具声明(如 `number`、`bool`),`duration_nano` 是 span 字段。
|
|
45
|
+
|
|
46
|
+
## V1 查询埋点与完成边界
|
|
47
|
+
|
|
48
|
+
- `rowCount`:普通取数路径默认是 0,只有单列 count 结果才写入 count 值。它不是返回行数,`rowCount=0` 也不说明数据为空。
|
|
49
|
+
- `queryCount`:本次尝试序号,首次为 1、重试递增,不能把 1、2、3 加成 6 次查询。
|
|
50
|
+
- 取完结果后,关闭 Pipeline、提交事务可能异步进行。执行器的 `end` 或成功埋点、HTTP 完成、引擎最终状态和资源收尾分开核对;后台收尾的耗时不算进用户已经拿到结果之后的等待。
|
|
51
|
+
|
|
52
|
+
## 更新 Write 链路
|
|
53
|
+
|
|
54
|
+
更新可能只有 `DataFlowExecutor -> execute`,不用先找 `QueryExecutor`,直接用 `execute` 的 `taskName`、`metric`;没有链接但任务和时间明确时,按任务查日志。一次更新里有多个任务,或者查询和写入混着,不因其中一个有链接就忽略其他候选。
|
|
55
|
+
|
|
56
|
+
特定数据源的湖表写入遇到 `MemoryLimitExceeded` 时,可能把并行度降到 1 再试,记 `compute.retry.pipeline_parallelism_reduced`。这有数据源和执行方式的限制,不能推广到所有内存超限;失败任务和成功重试分开记。
|
|
57
|
+
|
|
58
|
+
## 由问题选择执行
|
|
59
|
+
|
|
60
|
+
- 用户指定的 span、task 或操作优先,不拿最慢、最新或带链接的候选替换。
|
|
61
|
+
- 报错先看失败的那次尝试,成功重试单独记;多个查询或更新任务逐个核对,没链接的也留着。
|
|
62
|
+
- 用户要分析整条查询的耗时构成时可以按耗时排序,但短的失败任务也留着;耗时缺失、并列或分不清时保留候选,不按父名称、顺序或有没有链接猜。
|
|
63
|
+
|
|
64
|
+
### 从 trace 整理任务绑定
|
|
65
|
+
|
|
66
|
+
1. 先确认结果完整:带下一页游标、`hasMore`、截断标记,或行数到了查询上限,都说明候选不全,先补齐或说明缺口。
|
|
67
|
+
2. 只列上表三类 span:`span_id`、父 span 名和 ID、task(`taskName` 或 `polars.taskId`)、有没有 `metric`、错误状态、耗时。业务入口(如 `operatorsPage`、`previewComponent`)单独记,不是任务 span。
|
|
68
|
+
3. 分几次补到的属性按 `span_id` 合并;同一 span 的值冲突时都留着,不用后到的覆盖。
|
|
69
|
+
4. 不属于这三类、但带 task 或 metric 字段的记录列为“未识别记录”,不丢弃。
|
|
70
|
+
5. 按上面的规则选执行,多个候选都可信时全部保留。
|
|
71
|
+
|
|
72
|
+
## Metric 链接与任务日志
|
|
73
|
+
|
|
74
|
+
`metric` 指向 SigNoZ 日志页(`/logs/logs-explorer`),直接复用它的时间、task、logger 和全部过滤条件:
|
|
75
|
+
|
|
76
|
+
- `startTime`、`endTime`:毫秒,要成对且开始早于结束,否则算链接异常。没有时间时用已有执行范围,不自动扩成前后一小时。
|
|
77
|
+
- `compositeQuery`:URL 编码的 JSON,正常只有一个原始日志查询,没有聚合、分组或公式。
|
|
78
|
+
- 过滤条件只有 `AND` 连接的 `body CONTAINS '<taskName>'`、`logger.name = 'com.fanruan.polars.metric.MetricOuts'`,可能还有 `service.name`。`body` 里的 task 必须和选定执行一致,不一致时先核对执行选择,不按链接换执行。出现 `OR`、多个查询或其他未知条件时,不悄悄换成相似查询。
|
|
79
|
+
|
|
80
|
+
没有链接时,在这次执行的时间窗里按 task 和 logger 精确查(时间参数见[查询约束](../common/queries.md#查询约束))。Metric 日志的 `service.name` 是 MPP 引擎集群(如 `mpp-polars-cluster`),不是业务服务,而且不带 `trace_id`,只能按 task 查,不能套用业务服务过滤。
|
|
81
|
+
|
|
82
|
+
```text
|
|
83
|
+
body CONTAINS '<taskName>' AND logger.name = 'com.fanruan.polars.metric.MetricOuts'
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
只选 `timestamp`、`body`、`logger.name` 和必要的关联字段,设有限结果数。同 task 完整正文只取一次。
|
|
87
|
+
|
|
88
|
+
## 正文获取与响应处理
|
|
89
|
+
|
|
90
|
+
- MetricOuts 只能按精确 `taskName + logger + 执行时间窗` 获取。同一 task 返回多条时,内容相同的按 hash 去重算一份;分清完整明细和任务摘要,不当成多次执行;几份不同的明细不按耗时猜选。
|
|
91
|
+
- 大响应存到系统临时文件(客户端通常已自动存盘),之后读哪一段都从这份文件取,不得为不同片段重复查询同一条日志。只有正文末尾缺 `end_of_metric`,或明确有下一页且候选还不唯一时,才在相同条件下收紧到单条再取一次,不重新找资源、不逐段拼接。
|
|
92
|
+
- 已有 Metric、还要补提交、失败等生命周期日志时,先看已有的错误和快照够不够;要查就在同 task、引擎服务和时间窗里查,排除 MetricOuts 避免再拿一遍大正文。要保留没有 logger 的记录时用 `logger.name NOT EXISTS OR (logger.name EXISTS AND logger.name != 'com.fanruan.polars.metric.MetricOuts')`,和其他条件组合时整体加括号。
|
|
93
|
+
- Query Builder 结果里 `data.data.results` 是查询分组,分组里的 `rows` 才是日志行。看到零条先用保存的原始响应核对:服务端真的返回空、正文缺 `end_of_metric`、格式读不出、本地保存失败是四种情况,后三种都不等于没有日志,也不能据此删过滤条件重查。
|
|
94
|
+
|
|
95
|
+
## 读取大正文
|
|
96
|
+
|
|
97
|
+
不要整份读进上下文,用 shell 工具按需取:
|
|
98
|
+
|
|
99
|
+
- 先看两头:开头的 `Job:StandardTask[...]` 是任务状态和失败信息,末尾有 `end_of_metric` 才完整。
|
|
100
|
+
- 找 Pipeline:`grep -n 'pipeline@\|pipeline_wall_time'`,再按行号 `sed -n '起,止p'` 读相关 Operator。
|
|
101
|
+
- 找数据规模:`grep -nE 'output_rows_num|scanned_rows_num'`;找内存:`grep -nE 'peak|arena|memory_limit'`;找行数上限:`grep -n rowRestrict`。
|
|
102
|
+
- SigNoZ 的 JSON 响应先用 `jq` 取出日志行的 `body`(路径以实际响应为准)。
|
|
103
|
+
- 临时文件放系统临时目录,不把原文、凭据或业务载荷写进工作区。
|
|
104
|
+
|
|
105
|
+
## 数据规模
|
|
106
|
+
|
|
107
|
+
Metric 链接的时间窗只用来取这个 task 的统计,可能比入口 trace 宽;不能拿它去找相邻的业务执行或拼更新关系。
|
|
108
|
+
|
|
109
|
+
列数、行数、存储大小用来解释已锁定执行的数据条件。存储大小不等于计算时内存,单看宽表或大文件不能说它就是慢或 OOM 的根因。
|
|
110
|
+
|
|
111
|
+
## 任务属性缺失时
|
|
112
|
+
|
|
113
|
+
先补同 trace 的任务属性。还缺就沿固定的 trace、focused span、时间和服务读提交或生命周期日志:`Query(type:..., id:task-a)`、`Write(type:..., id:task-a)` 和显式 `taskName` 可以当候选;`tableId`、企业、相近时间、相似表名都代替不了任务关联。多个候选都可信时按目标操作消歧,不默认取第一条。
|
|
114
|
+
|
|
115
|
+
精确 trace 查不到明细、URL 也没时间时,在同环境、已确认服务内按 `trace_id` 查一次日志,最多 30 天;URL 有 `spanId` 就保留这个过滤。找回时间后固定这次执行,仍查不到或分不清再说明覆盖、请用户补最小的缺口。
|
|
116
|
+
|
|
117
|
+
明确提交前就失败的,解释等待条件;提交状态不明、Metric 只有 `RUNNING` 快照时,读同 task 的生命周期日志。已有直接错误时,不重复查同一个业务报错。
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# 引擎 · 入口与信号
|
|
2
|
+
|
|
3
|
+
回答“怎样认出入口,各个 span、attribute、日志和字段是什么意思”。各字段是什么见[Metric 字段速查](topics/metric-fields.md),这里只写判读时的限制。
|
|
4
|
+
|
|
5
|
+
## 目录
|
|
6
|
+
|
|
7
|
+
- [时间信号](#时间信号)
|
|
8
|
+
- [内存信号](#内存信号)
|
|
9
|
+
- [查询失败重试](#查询失败重试)
|
|
10
|
+
- [常见引擎报错](#常见引擎报错)
|
|
11
|
+
- [查询规模信号](#查询规模信号)
|
|
12
|
+
- [数据规模与 Operator 信号](#数据规模与-operator-信号)
|
|
13
|
+
|
|
14
|
+
## 时间信号
|
|
15
|
+
|
|
16
|
+
### 任务与 Pipeline
|
|
17
|
+
|
|
18
|
+
- `TaskStateTime[...]` 各项是状态阶段耗时(毫秒),`start_time` 不是时间戳,`null` 是还没测完、不能填 0。`plan_time` 只算状态机的规划阶段,很短也不能排除优化慢;`Slow constant folding` 的 `elapsedMs` 是另一项独立测量。
|
|
19
|
+
- `pipeline_wall_time_ms` 是 Pipeline 从调度到收尾的墙钟时间,含依赖等待,适合找慢链路,不是 CPU 时间。
|
|
20
|
+
- pending 是等调度,blocked 是等依赖(上游、IO、交换、背压都可能)。两者的 `sum` 会因并发超过墙钟时间,不能拿 `sum / pipeline_wall_time` 当占比,各项 `max` 相加也还原不了总耗时。
|
|
21
|
+
- `{max, min, sum, avg, count}` 里,`max` 看最慢的执行单元,`sum` 看总量;Pipeline 层的 `count` 是参与汇总的执行单元数,算子层的 `count` 可能是列读取、分区等别的对象,按字段确认。
|
|
22
|
+
- active CPU 和 active wall 只在同范围、同口径时比较:CPU 高是在算;wall 远大于 CPU 去找同步 IO、锁等待或线程抢占的信号。两者的 `max` 可能来自不同执行单元。`jit_backend[...]` 下的同名字段只覆盖该后端,和 Pipeline 汇总分开看。
|
|
23
|
+
- 跨 Task 对照先确认是同一份物理工作;只有一个代表 Task 时不推断全体实例的差异。
|
|
24
|
+
|
|
25
|
+
`Task execution timeout after ... ms (limit: ... ms)`(报在引擎 `query` span 上)是优化器计时保护超时,业务层随后报 `QueryTimeOutException` / `polars query timeout`。多半是查询本身太大,先看[查询规模信号](#查询规模信号),再回场景找原因。预算以报错里的 limit 为准;优化器计时和查询总运行时限可能覆盖同一段工作,不能相加。调大预算只是允许算更久,解决不了查询太大。
|
|
26
|
+
|
|
27
|
+
## 内存信号
|
|
28
|
+
|
|
29
|
+
- 任务峰值和上限看 `query_peak_memory`、`query_memory_limit`(Java 侧对应 `peakUserMemory`);节点整体看 `global_*`。
|
|
30
|
+
- `query_peak_memory_when_pipeline_closed` 是 Pipeline 关闭时的查询级快照,不是这条 Pipeline 或最后一个 Operator 独占的量。
|
|
31
|
+
- Operator 专项内存(`arena_*_allocated`、`main_arena_*`、`secondary_arena_*`、`temp_table_*`、`partition_*_allocated`、`store_tuple_arena_*`)比查询级快照更接近具体的哈希、汇总、窗口或缓存状态,有就优先报。main 不是峰值,secondary 不是增量,不按名字算差值。logical 是请求的数据空间,physical 是分配的内存块,都不是进程 RSS,也不是全过程峰值。
|
|
32
|
+
- `hash_table_size`、`hash_table_capacity` 是行数,不是字节。
|
|
33
|
+
- current、allocated、deallocated、peak 生命周期不同;结束后 current 降低不说明运行中内存低。`spill_*` 字节是落盘量,不算驻留内存。
|
|
34
|
+
- `query_peak_memory_v1` 等 `_v1` 字段是另一种跟踪口径,和不带后缀的不相加、不直接比。
|
|
35
|
+
- 显示值保留两位小数(如 `4.00 GiB`),精确边界看同 task 错误里的整数字节。
|
|
36
|
+
- 内存超限报错形如 `<MemoryLimitExceeded> Memory limit exceeded, type MppTask, label <任务 ID>, current ..., will_be ..., limit 4.00 GiB (...)`:`label` 是引擎任务 ID,可直接按它取 Metric;`current` 是当时已用,`limit` 是任务上限,`will_be` 按字面是这次申请后会达到的量(未核实)。哪个上限触发以同 task 的错误为准。
|
|
37
|
+
- OOM 只说明撞了边界,原因还要落到具体计算和这次的数据条件上。只有总行数时,不推断高基数、倾斜或 N:N 放大。
|
|
38
|
+
|
|
39
|
+
## 查询失败重试
|
|
40
|
+
|
|
41
|
+
前台取数(分析表预览、组件、仪表板筛选器候选值)的引擎查询失败后会自动重试,最多跑 3 次,间隔固定 5 秒(流式读取 10 秒)。每次重试前有 WARN 日志 `retry executor:QueryExecutor`,带着上一次的异常;每次尝试有自己的 task ID。
|
|
42
|
+
|
|
43
|
+
- 根 span 十几秒、每次引擎执行只有几十毫秒,时间基本花在重试等待上。把每次尝试的开始时间和报错排出来再下结论。
|
|
44
|
+
- 不重试:查询超时(`QueryTimeOutException`)、语法错误、等资源超时、引擎已知的业务错误。内存超限一般也不重试,只有允许用高性能节点的任务会换到高性能节点再试。连不上引擎 worker(gRPC 不可用)会重试。
|
|
45
|
+
- 三次同一个错,是稳定的失败条件,答复讲这个错误本身,重试只用来解释耗时。
|
|
46
|
+
|
|
47
|
+
## 常见引擎报错
|
|
48
|
+
|
|
49
|
+
错误原文在出错 span 的 `status_message` 或日志里,HTTP 状态码可能仍是 200。
|
|
50
|
+
|
|
51
|
+
- `AggregateSignature not found: sum(Nullable(String))` 这类:对文本、日期或布尔字段做了引擎不支持的聚合(如求和),是配置或字段类型问题,不是性能问题。SigNoZ 里看不到配置变更,请用户在界面上核对聚合设置和字段类型。
|
|
52
|
+
- `TABLE_VERSION_NOT_FOUND`:要读的表版本在引擎里找不到了(推测是被新版本替换后清理,未核实)。报错带表 ID 和版本号,查这张表出错前后的更新记录。
|
|
53
|
+
|
|
54
|
+
## 查询规模信号
|
|
55
|
+
|
|
56
|
+
优化器超时、内存超限之前,常能先看到查询被展开得很大。这两条是日志正文,按 `trace_id` 查日志(可加 `body CONTAINS 'dax parse too slow'`):
|
|
57
|
+
|
|
58
|
+
- `dax parse too slow, dax length = N`:业务层生成的查询语句有 N 个字符。比同一组件单独预览或平时长到几万、几十万字符,说明大量上游计算被一起展开了。
|
|
59
|
+
- `begin get allParent` / `end get parent : N`:活跃检查在逐张表找上游(N 是毫秒)。同一请求里成对出现很多次,说明牵涉很多张表。
|
|
60
|
+
|
|
61
|
+
看到这些,回场景找是什么让查询变大:分析表看[分析步骤](../dataset/topics/steps.md);仪表板常见是参数、动态字段或筛选绑在很深的上游表上(见[仪表板 · 常见现象与候选假设](../dashboard/workflow.md#常见现象与候选假设))。
|
|
62
|
+
|
|
63
|
+
## 数据规模与 Operator 信号
|
|
64
|
+
|
|
65
|
+
看读表行列和字节、各 Operator 的 `output_rows_num`、哈希表大小、汇总和窗口状态、并行度和各实例的 max/avg 差异,并和物理计划、本次业务上下文一起解释。
|
|
66
|
+
|
|
67
|
+
- 检查所有带行数的 Operator,包括最慢 Pipeline 之外的:自身不慢、不占内存的节点也可能放大中间结果。
|
|
68
|
+
- 行数显著增长能说明中间结果放大,但没有连接条件和两侧基数时,不能直接把它命名为 N:N Join。`Unnest` 只表示一行展开成多行,除非这次的计划或配置明确是日期序列,不解释成日期补全。
|
|
69
|
+
- `-1` 是未产出的哨兵,`null` 是没测到,都不参与差值和比例。下游没有产出时,上游已观测的行数仍然有效。
|
|
70
|
+
- 任务失败与否看 `Job:StandardTask` 的 `taskStatMachine`、`failedMessage` 或同 task 的错误日志,不凭 `query_peak_memory == query_memory_limit` 反推。
|
|
71
|
+
- V1 查询埋点的 `rowCount` 和 Operator 的 `output_rows_num` 口径不同,`queryCount` 是尝试序号,见[V1 查询边界](queries.md#v1-查询埋点与完成边界)。
|
|
72
|
+
|
|
73
|
+
差值、倍数和两次执行的对比怎么算、怎么引用,见[读取与引用原文的口径](conclusions.md#读取与引用原文的口径)。
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Metric 字段速查
|
|
2
|
+
|
|
3
|
+
线上查询和更新都跑在 MPP 节点上,这里按 MPP 节点的 Metric 写。拿到一份 Metric 后按“任务 → Pipeline → 算子 → 读表、输出和写表”的顺序看,每一层回答一个问题。字段含义参考了引擎 Profile 手册,并逐个对照过线上 MPP Metric;手册里有、线上没见到的字段没有收进来。各字段之间不能相加、怎样引用,仍按[信号含义](../signals.md)和[能下什么结论](../conclusions.md)来。
|
|
4
|
+
|
|
5
|
+
## 目录
|
|
6
|
+
|
|
7
|
+
- [一份 Metric 长什么样](#一份-metric-长什么样)
|
|
8
|
+
- [任务级:慢在哪个阶段,内存撞没撞线](#任务级慢在哪个阶段内存撞没撞线)
|
|
9
|
+
- [Pipeline:哪条链最慢,慢在算还是在等](#pipeline哪条链最慢慢在算还是在等)
|
|
10
|
+
- [算子:数据在哪变多,内存花在哪](#算子数据在哪变多内存花在哪)
|
|
11
|
+
- [读表、输出和写表](#读表输出和写表)
|
|
12
|
+
- [几个通用约定](#几个通用约定)
|
|
13
|
+
|
|
14
|
+
## 一份 Metric 长什么样
|
|
15
|
+
|
|
16
|
+
一个任务在 `MetricOuts` 里是一条日志,日志的 `service.name` 是引擎集群(如 `mpp-polars-cluster`),不是业务服务,也不带 `trace_id`。从上到下依次是:
|
|
17
|
+
|
|
18
|
+
1. `Job:StandardTask[...]`:任务摘要。`tag` 是任务类别(`QUERY` 查询、`ETL` 更新写表),`description` 里的 `desc` 是来源(如 `COMPONENT`、`etl`),`name` 是请求路径或线程池;`taskStatMachine` 是任务状态(`FINISHED`、`CANCELLED`、`FAILED` 等),失败或取消的原因在 `failedMessage`、`cancelMessage`;最后是 `TaskStateTime[...]` 各阶段耗时。
|
|
19
|
+
2. `analyzed info:`:逻辑计划(`*Node`)。
|
|
20
|
+
3. `SubPlans:`:物理计划(`PHYSICAL_*`),行数上限 `rowRestrict` 在这一层。
|
|
21
|
+
4. 查询汇总:`- query_id=`、`- elapsed_time=` 开头的一组字段,每个任务都有。
|
|
22
|
+
5. `stage_infos`:执行明细,下面是 `task@...`(任务在某个节点上的执行)和一条条 `pipeline@N`。**只有耗时或内存超过一定门槛的任务才记录这一段**,没到门槛的 Metric 到查询汇总就结束了。没有这一段不代表没执行,也不代表数据小,只是没达到记录门槛。
|
|
23
|
+
|
|
24
|
+
最后以 `end_of_metric` 结尾。计划节点和算子名的含义见[Metric 里常见的名字](../concepts.md#metric-里常见的名字)。
|
|
25
|
+
|
|
26
|
+
## 任务级:慢在哪个阶段,内存撞没撞线
|
|
27
|
+
|
|
28
|
+
任务摘要和查询汇总(每个任务都有):
|
|
29
|
+
|
|
30
|
+
| 字段 | 是什么 | 诊断时怎么用 |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| `TaskStateTime[queue_time, wait_resource_time, plan_time, start_time, run_time, finish_time]` | 各状态阶段耗时(毫秒) | 排队、等资源、规划、执行各花了多久,细节见[任务与 Pipeline](../signals.md#任务与-pipeline) |
|
|
33
|
+
| `elapsed_time`、`execution_time` | 整个查询的总耗时、执行耗时 | 可以当作这个任务在引擎里花的总时间 |
|
|
34
|
+
| `queue_cost` | 排队耗时 | 大说明在排队 |
|
|
35
|
+
| `optimizer_cost`(有的任务写作 `optimizer1_cost`) | 优化耗时 | 占了大头时看[优化或编译慢](patterns.md#优化或编译慢执行指标却不高) |
|
|
36
|
+
| `distribution_cost` | 分发耗时:决定任务放到哪些节点,读湖表时构建扫描任务也算在这里 | |
|
|
37
|
+
| `send_cost` | 把任务发给计算节点的耗时 | |
|
|
38
|
+
| `load_balance_cost`、`lb_queue_cost` | 经负载均衡转发的耗时和排队 | |
|
|
39
|
+
| `total_tasks` | 拆成了多少个子任务 | |
|
|
40
|
+
| `sumNodePeakMemory`、`maxNodePeakMemory` | 各节点内存峰值之和、最大值 | 单节点任务两者相同 |
|
|
41
|
+
| `peakUserMemory`、`memCapacity`(任务摘要里) | Java 侧看到的峰值和容量 | `memCapacity=-1` 是没设置 |
|
|
42
|
+
|
|
43
|
+
`task@...` 下面(有执行明细时才有):
|
|
44
|
+
|
|
45
|
+
| 字段 | 是什么 | 诊断时怎么用 |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| `node_id` | 在哪个引擎节点上跑 | 同节点多个任务一起慢时,可以按它归类 |
|
|
48
|
+
| `query_peak_memory`、`query_memory_limit` | 这个任务的内存峰值和上限 | 峰值贴近上限就是撞线了 |
|
|
49
|
+
| `query_memory_allocated`、`query_memory_deallocated` | 累计申请、释放的内存 | 是累计量,不是峰值,不能拿来和上限比 |
|
|
50
|
+
| `global_current_memory`、`global_memory_limit` | 整个引擎节点当前占用和上限 | 任务自己不大、节点整体很满时,可能是被同节点的别的任务挤的 |
|
|
51
|
+
| `spillBytes` | 吐磁盘的字节数 | 不为 0 说明写过磁盘 |
|
|
52
|
+
| `resultRows`、`writtenRows` | 返回给业务的行数、写入目标表的行数 | 预览返回 100 行不代表只算了 100 行 |
|
|
53
|
+
| `astSizeBytes` | 这次生成的执行代码大小 | 和同一查询平时的值比,变大很多说明查询被展开得更复杂了,和[查询规模信号](../signals.md#查询规模信号)一起看 |
|
|
54
|
+
| `queryStartTimestamp`、`queryEndTimestamp` | 执行开始、结束时间 | |
|
|
55
|
+
|
|
56
|
+
## Pipeline:哪条链最慢,慢在算还是在等
|
|
57
|
+
|
|
58
|
+
先按 `pipeline_wall_time_ms` 找出最慢的几条,再看这几条里面:
|
|
59
|
+
|
|
60
|
+
| 字段 | 是什么 | 诊断时怎么用 |
|
|
61
|
+
|---|---|---|
|
|
62
|
+
| `pipeline_parallelism` | 这条 Pipeline 用了几个线程 | 下面这些字段的 `count` 一般就等于它 |
|
|
63
|
+
| `morsel_count` | 拆成了多少个执行单元 | 并行度高但单元很少时,线程会闲着 |
|
|
64
|
+
| `morsel_active_wall_time`、`morsel_active_cpu_time` | 执行单元在跑时的墙钟时间和 CPU 时间 | 两者接近是在算;墙钟远大于 CPU,说明在等 IO、等锁,或者线程抢不到 CPU |
|
|
65
|
+
| `morsel_blocked_time`、`morsel_blocked_count` | 执行单元因依赖没就绪被挂起的时间和次数 | 下游 Pipeline 等上游算完时也会很大,要和上游的耗时一起看,不能直接当成 IO 慢 |
|
|
66
|
+
| `morsel_pending_time` | 在线程池里排队的时间 | 大说明节点忙,任务排不上 |
|
|
67
|
+
| `significant_active_morsel_count`、`significant_active_morsel_time` | 单次执行很久的执行单元个数和耗时 | 有很多说明这段计算重或数据量大 |
|
|
68
|
+
| `morsel_jni_call_count` | 调用 JNI 的次数 | JNI 很慢,次数多可能就是瓶颈 |
|
|
69
|
+
| `pipeline_ast_size_bytes`、`buildAstCostMs`、`jit_backend[...]` 下的 `compile_wall_time` | 生成代码的大小、构建耗时、编译耗时 | 代码过大时编译会慢 |
|
|
70
|
+
| `query_peak_memory_when_pipeline_closed` 等 | Pipeline 关闭那一刻的内存快照 | 看内存在哪条 Pipeline 之后涨上去,不是这条 Pipeline 独占的量 |
|
|
71
|
+
|
|
72
|
+
## 算子:数据在哪变多,内存花在哪
|
|
73
|
+
|
|
74
|
+
| 字段 | 是什么 | 诊断时怎么用 |
|
|
75
|
+
|---|---|---|
|
|
76
|
+
| `output_rows_num`、`output_cols_num` | 算子输出的行数、列数 | 从读表往下逐个比,行数突然变多的就是放大点 |
|
|
77
|
+
| `operator_wall_time` | 算子耗时 | 线上默认不开,通常是 `null`;算子级耗时看不到,靠 Pipeline 耗时和行数推断 |
|
|
78
|
+
| `hash_table_size`(`ParallelHashJoinSink` 的 scan 端)、`partition_hash_table_size_sum` | 关联建表那一侧的哈希表行数 | 很大说明建表侧数据多 |
|
|
79
|
+
| `hash_table_size`、`hash_table_capacity`、`arena_logical_allocated` / `arena_physical_allocated`(`FinalPreHashAggregate`) | 局部汇总的分组数、容量和占用内存 | 分组数接近输入行数,说明分组字段几乎不重复,汇总省不了多少数据 |
|
|
80
|
+
| `main_arena_*_allocated`、`secondary_arena_*_allocated`(`FinalMergeHashAggregate`) | 最终汇总的状态内存 | 汇总的内存大头通常在这里 |
|
|
81
|
+
| `temp_table_logical_allocated`、`temp_table_physical_allocated`(`Cte`) | 复用的中间结果占的内存 | 中间结果被缓存在内存里供多处读取 |
|
|
82
|
+
|
|
83
|
+
## 读表、输出和写表
|
|
84
|
+
|
|
85
|
+
读表(`LakeConnectorSource`):
|
|
86
|
+
|
|
87
|
+
| 字段 | 是什么 | 诊断时怎么用 |
|
|
88
|
+
|---|---|---|
|
|
89
|
+
| `scanned_rows_num`、`scanned_columns_num` | 读了多少行、多少列 | 读得多不多;和物理计划里 `PHYSICAL_TABLE_SCAN` 的 `predicate` 一起看过滤有没有下推到读表 |
|
|
90
|
+
| `scan_task_file_bytes`、`scanner_row_group_*_size_*` | 要读的文件大小、行组大小 | |
|
|
91
|
+
| `s3_input_stream_read_cost`、`s3_input_stream_duration_time` | 从对象存储读数据的耗时 | 大说明读存储慢 |
|
|
92
|
+
| `scanner_get_next_chunk_wall_time_*`、`scanner_read_record_batch_*` | 读每块数据、解码的耗时 | |
|
|
93
|
+
| `table_scan_task_pending_time`、`scan_blocked_time` | 读取任务排队、被挂起的时间 | 平时接近 0,大说明读取任务在排队 |
|
|
94
|
+
| `table_scan_cache_result_queue_size`、`table_scan_idle_scanner_size`(看 `avg`)、`table_scan_num_scanners` | 读出来等着被取走的结果队列长度、空闲读取线程数、读取线程总数 | 按手册的说法:队列接近 0 说明后面取得快,瓶颈在读;接近读取线程数说明读得快,瓶颈在后面的计算 |
|
|
95
|
+
|
|
96
|
+
输出(查询任务的 `BlockOutput`):sink 端的 `output_flush_block_bytes`、`output_blocks_num`、`output_flush_block_time` 是输出了多少、花了多久;scan 端的 `result_cache_collected_rows`、`result_cache_collected_bytes` 是收进结果缓存的行数和字节数。
|
|
97
|
+
|
|
98
|
+
写表(更新任务的 `LakeConnectorSink`):`chunk_row_count` 是写了多少行,`parquet_file_writer_commit_file_count`、`parquet_file_writer_commit_file_size` 是提交了多少文件、多大,`s3_output_stream_multipart_upload_time` 是上传耗时,`sink_blocked_time` 是写入被挂起的时间。
|
|
99
|
+
|
|
100
|
+
## 几个通用约定
|
|
101
|
+
|
|
102
|
+
- 形如 `{max=..., min=..., sum=..., avg=..., count=...}` 的是一组数的汇总,单看某一个值没有意义。Pipeline 级字段的 `count` 一般是线程数,`max` 看最慢的线程,`sum` 看总量;没打印 `count` 时用 `sum / avg` 算。
|
|
103
|
+
- `-1` 是默认初始值,表示没赋值;`null` 表示没测到。两者都不能当成 0。任务被取消或失败时,后面的算子常是 `-1` 或 `null`。
|
|
104
|
+
- 吐磁盘目前只看得到任务级的 `spillBytes`,手册里的 `spill_*` 明细线上没有出现。
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# 常见引擎性能问题
|
|
2
|
+
|
|
3
|
+
拿到这次执行的 Metric 后,按现象查对应条目。每条都是候选机制,要用同一执行的记录确认;判读口径见[能下什么结论](../conclusions.md)。给优化建议前核对业务语义,不自动改资源或重跑任务。
|
|
4
|
+
|
|
5
|
+
## 调度等待长,执行工作量并不高
|
|
6
|
+
|
|
7
|
+
Pipeline 慢、active CPU 和处理量却不高时,分清在哪层等:任务级的排队和等资源(`queue_time`、`wait_resource_time`)、执行单元等调度(`morsel_pending_time`)、等依赖(`morsel_blocked_time`),还有 open/close。只有 `not submitted, skip finish` 这类记录才能说明还没进入计算,提交前失败不套用算子优化。pending 大支持“调度等待贡献了耗时”,但证明不了 CPU 满载或被某个企业抢占。
|
|
8
|
+
|
|
9
|
+
## 扫描很多,最终只返回少量数据
|
|
10
|
+
|
|
11
|
+
看读表算子(`LakeConnectorSource`)的 `scanned_rows_num`、`scanned_columns_num`、`scan_task_file_bytes`、`s3_input_stream_read_cost`、`table_scan_task_pending_time`,再对照物理计划里读表节点的 `predicate` 和筛选的输出。这些读取计时可能重叠,不能相加。条件确实在读表之后才处理时,可以考虑把筛选提前、少选字段、缩小数据范围;已经下推了还读很多,要看缓存、文件布局和条件选择性,不能直接说下推失效。
|
|
12
|
+
|
|
13
|
+
## 表达式或本地计算耗时高
|
|
14
|
+
|
|
15
|
+
比较同范围的 active CPU 和 active wall,对照处理的行列数和物理计划里的表达式。CPU 高说明在算,但具体是哪个 Project 或 Filter 要有专项记录;CPU 不高、wall 高时去看同步读取、锁和调度。定位到具体表达式后,才建议提前筛选、去掉重复计算或少带列。
|
|
16
|
+
|
|
17
|
+
## Join 建表状态大或输出放大
|
|
18
|
+
|
|
19
|
+
用物理计划确认建表侧和探测侧,不按页面上的左右表判断。看两侧输入规模、建表侧的 `hash_table_size`、探测输出和连接条件:建表侧大时输出少也可能很吃内存,输出变多会加重下游排序或窗口。`hash_table_size` 是哈希实现的状态项数,不等于原表行数或唯一键数。缺一侧规模或键重复的记录时,不叫 N:N Join。业务允许时可以先筛选、少带列或先汇总,但要保住连接方式、重复键和空值的语义。
|
|
20
|
+
|
|
21
|
+
## 聚合结果少,Hash 状态仍很大
|
|
22
|
+
|
|
23
|
+
看聚合函数、分组键、`hash_table_size` / `hash_table_capacity`、局部汇总的 arena 和最终汇总的 main/secondary 状态。结果行数少,局部状态、变长键和聚合内容也可能很大;多个局部哈希表的状态数不能当全局分组数,只凭输入行数不能断言分组多。确认压力来源后,再看业务能不能少几个分组字段或先筛选。
|
|
24
|
+
|
|
25
|
+
## 排序或窗口保存大量中间行
|
|
26
|
+
|
|
27
|
+
看排序或窗口的实际输入、保留的列、排序键、分区和状态内存,以及上游是不是先产生了更多行。收集和输出可能在不同 Pipeline,最终输出少也可能先存了很多数据;窗口总行数说明不了单个分区多大。业务允许时可以先筛选、少带列,只要前 N 条时考虑 TopN;改分区、排序或筛选位置都可能改变结果,建议要写清前提。
|
|
28
|
+
|
|
29
|
+
## Spill 降低内存压力,但增加读写成本
|
|
30
|
+
|
|
31
|
+
线上 MPP Metric 目前只看得到任务级 `spillBytes`。不为 0 说明写过磁盘,会增加读写耗时;但写出字节不等于内存峰值,出现 spill 不说明失败,为 0 也不说明没有内存压力。优化先找是什么让状态变大。
|
|
32
|
+
|
|
33
|
+
## Exchange 等待或多个 Task 完成不均
|
|
34
|
+
|
|
35
|
+
多节点执行时,按 Stage、Task 和片段关联找到生产端和消费端,看队列等待、结束确认等待和序列化计时。这些等待可能来自消费慢、其他 Task 晚启动或传输,判断网络慢要有通信专项记录。Task 之间比较前先确认是同一份物理工作;`max` 远高于 `avg` 说明有差异,是否数据倾斜还要别的证据。Metric 可能只打印了代表 Task,先确认覆盖范围。提高并行度会增加状态和交换成本,不是通用提速建议。
|
|
36
|
+
|
|
37
|
+
## 优化或编译慢,执行指标却不高
|
|
38
|
+
|
|
39
|
+
看任务阶段、查询汇总里的 `optimizer_cost`(有的任务写作 `optimizer1_cost`)、同 task 的 `Slow constant folding`、各 `jit_backend[...]` 的编译计时。构建代码、编译、执行是不同工作,active CPU 低不能排除准备阶段慢;不同后端的计时可能重叠,不与 Pipeline 汇总相加。`llvm_predict_compile_time` 是预测值。确认慢在昂贵表达式、常量展开或编译后,再看能否等价简化;优化器超时、等资源超时、业务查询超时分开解释,调大超时只是允许多等。
|
|
40
|
+
|
|
41
|
+
## 简化示例怎样下结论
|
|
42
|
+
|
|
43
|
+
数字只用来说明判断方式,不是通用阈值:
|
|
44
|
+
|
|
45
|
+
| 已有材料 | 可以说明 | 仍不能说明 |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| Pipeline 墙钟 1 秒;pending 的 max 800 毫秒、sum 6 秒、count 8 | 执行单元有调度等待,累计量受并发影响 | 等待占查询耗时 600%,或机器 CPU 已满 |
|
|
48
|
+
| 读表输出 1400 万行,筛选输出 9 行,读取字节和耗时都高 | 读得远比最后输出多,读取是要核对的环节 | 已证明过滤没下推,或任意两节点能直接算放大率 |
|
|
49
|
+
| 排序状态 4 GiB,最终只返回 100 行 | 排序保存的状态仍可能很大,要核对输入和列宽 | 可以直接把 LIMIT 提前且结果不变 |
|
|
50
|
+
| 关联输出变多,下游窗口状态变大,同 task 报内存超限 | 能从数据规模一路解释到下游状态和失败边界(执行层) | 只凭这些就确认唯一业务根因 |
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# 引擎 · 排查入口
|
|
2
|
+
|
|
3
|
+
要拿到或看懂一次引擎执行的统计(Metric)时从这里下手。这里只解释执行层:任务结果、数据规模、耗时和内存。DSL 与业务步骤的映射由各场景域负责。
|
|
4
|
+
|
|
5
|
+
## 入手
|
|
6
|
+
|
|
7
|
+
- 有 Metric 文件或响应就直接读;只有 task 或 Metric 链接,在固定范围里取这个 task 的正文;只有 trace,先找回任务。取法见[查询方法](queries.md),默认值见[公共查询规则](../common/queries.md)。
|
|
8
|
+
- 按用户的问题和明确的关联选执行,失败、重试和没链接的候选都留着;选定后不因别的任务更慢、更新或带链接就换掉。
|
|
9
|
+
- 原始响应保存到系统临时文件,同一份正文不重复查;不要把原始响应、凭据或业务载荷写入工作区。大正文用 shell 分段读,见[读取大正文](queries.md#读取大正文)。
|
|
10
|
+
- 对比两次执行时,目标和基线各自固定范围,不互换时间窗。单次失败不需要成功样本。
|
|
11
|
+
|
|
12
|
+
## 解释
|
|
13
|
+
|
|
14
|
+
按“任务 → Pipeline → 算子 → 读表、输出和写表”的顺序看:字段查[Metric 字段速查](topics/metric-fields.md),判读限制查[信号含义](signals.md),结论口径查[能下什么结论](conclusions.md),按现象查[常见引擎性能问题](topics/patterns.md)。
|
|
15
|
+
|
|
16
|
+
- 先看任务结果和直接报错,再把热点、输入输出、IO、中间状态、并行度和资源上限串起来。最慢的 Pipeline 不一定是根因。
|
|
17
|
+
- 只有总行数时,不推断高基数、数据倾斜或关联放大。
|
|
18
|
+
- 同一个 task 记了 `not submitted, skip finish`,说明提交前就失败了,预先生成的 ID 证明不了算过。
|
|
19
|
+
- 分清拿到的是完整明细、只有摘要、真的为空、被截断、正文不完整,还是 task 对不上。界面截断或本地读取失败,不能说没生成 Metric;`RUNNING` 摘要只是某个时刻的快照。
|
|
20
|
+
- 手上只有引擎记录时,结论停在执行层,再回场景找业务原因。
|