sparkforensics-server 0.5.2 → 0.8.1
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/index.js +16 -7
- package/package.json +1 -1
- package/public/assets/AutoscalingChurn-DenWKTv-.js +1 -0
- package/public/assets/CacheUtilization-DLz7NdjV.js +1 -0
- package/public/assets/CachingOpportunity-zpQIqhzm.js +1 -0
- package/public/assets/ChartTheme-DAiARbLP.js +8 -0
- package/public/assets/ColdStart-C-9HjxWl.js +1 -0
- package/public/assets/ConfigAudit-D0V9tcrJ.js +1 -0
- package/public/assets/CoreUsageArea-yeerrljd.js +1 -0
- package/public/assets/Dashboard-DkUPrHKV.js +1 -0
- package/public/assets/DisclosureContext-DK1_iz6J.js +1 -0
- package/public/assets/DuplicatePlanSubtree-xDNDbCd3.js +1 -0
- package/public/assets/DurationHistogram-B6jsE0Ov.js +1 -0
- package/public/assets/EmptyState-C1uL40VU.js +1 -0
- package/public/assets/ExecutorUtilization-DXDZKmSc.js +1 -0
- package/public/assets/GcPressure-MRf7I4IG.js +1 -0
- package/public/assets/ImpactEstimate-Dm3xWbzV.js +1 -0
- package/public/assets/IncompleteRun-CaLOhMtf.js +1 -0
- package/public/assets/JobFailures-CzmzlvhO.js +1 -0
- package/public/assets/MemoryUtilization-AWUMUjCH.js +1 -0
- package/public/assets/NestedLoopJoin-C9sNr6Ss.js +1 -0
- package/public/assets/OverBroadcast-BOmRE6ca.js +1 -0
- package/public/assets/PartitionHint-BL2EmJfE.js +1 -0
- package/public/assets/PartitionSizing-BzBySvUq.js +1 -0
- package/public/assets/PlanExplorer-DdiQRcJU.js +1 -0
- package/public/assets/PlanGraphRoute-CIH9gBuR.js +1 -0
- package/public/assets/PlanView-B1hxzFRs.js +2 -0
- package/public/assets/PythonUdf-DvgCCueD.js +1 -0
- package/public/assets/RetryWaste-uXXu_CyM.js +1 -0
- package/public/assets/RowPagination-C-LzWkI5.js +1 -0
- package/public/assets/RowStatusCluster-Dbtmte7l.js +1 -0
- package/public/assets/ShuffleIO-nALwzC1_.js +1 -0
- package/public/assets/Skew-CHMEKgvk.js +1 -0
- package/public/assets/SlowHost-yyvjpHk6.js +1 -0
- package/public/assets/SmallFiles-y6odJ97n.js +1 -0
- package/public/assets/SpeculationWaste-C-SD2LOt.js +1 -0
- package/public/assets/Spill-DHTMmOup.js +1 -0
- package/public/assets/StageFailed-CQ3DxC9R.js +1 -0
- package/public/assets/StageFindingGroup-BgYLyj5q.js +1 -0
- package/public/assets/StageHeader-CIETkjVZ.js +1 -0
- package/public/assets/StagePill--P7PDd3s.js +1 -0
- package/public/assets/StageShape-BIv8vx_o.js +1 -0
- package/public/assets/StageSlowness-MMqzERxN.js +1 -0
- package/public/assets/Straggler-BgrY7AyW.js +1 -0
- package/public/assets/TaskFailures-BHHyKYTs.js +1 -0
- package/public/assets/TinyTask-DDScNhCl.js +1 -0
- package/public/assets/UnderBroadcast-CGIC04TI.js +1 -0
- package/public/assets/WidgetLeadSummary-CXFZP00C.js +1 -0
- package/public/assets/button-DbpTz2yk.js +1 -0
- package/public/assets/charts-vendor-CtTxwTeu.js +59 -0
- package/public/assets/composite-C9Nu2EI9.js +1 -0
- package/public/assets/d3-vendor-DNlD2-cz.js +1 -0
- package/public/assets/detector-registry-Bp8hrLua.js +2 -0
- package/public/assets/downsample-WmNM1qc9.js +1 -0
- package/public/assets/finding-anchor-Dr40LkS9.js +1 -0
- package/public/assets/findings-of-type-BL2u3RGZ.js +1 -0
- package/public/assets/impact-sort-mC5ISgX8.js +1 -0
- package/public/assets/inbox-KPU1Gppm.js +1 -0
- package/public/assets/index-CaRVPvAT.css +2 -0
- package/public/assets/index-fDiwfuoO.js +14 -0
- package/public/assets/inertValue-L9VxV0VE.js +1 -0
- package/public/assets/instrument-sans-latin-ext-wdth-normal-C5E2Gvlv.woff2 +0 -0
- package/public/assets/instrument-sans-latin-wdth-normal-BVScPF0l.woff2 +0 -0
- package/public/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
- package/public/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
- package/public/assets/layout.worker-CLcBHxVp.js +3 -0
- package/public/assets/{parser-worker-CA5RxqKc.js → parser-worker-CRIOPMOW.js} +8 -8
- package/public/assets/plan-graph-vendor-Ce6d4HU6.js +7 -0
- package/public/assets/react-vendor-C6KcUD36.js +9 -0
- package/public/assets/select-BHqOqun5.js +1 -0
- package/public/assets/toggle-DPeN6aNa.js +1 -0
- package/public/assets/toggle-group-Kl3uyHSr.js +1 -0
- package/public/assets/usePagedRows-BafD6bEN.js +1 -0
- package/public/assets/useRecentFiles-DzJZAoOT.js +3 -0
- package/public/assets/useRegisterFieldControl-pQv-ZDoU.js +1 -0
- package/public/assets/useScrollLock-BCxn_dMp.js +1 -0
- package/public/assets/useSortMode-DjrAN-z4.js +1 -0
- package/public/docs/404.html +3 -7
- package/public/docs/assets/{app.eYTPqTeq.js → app.1gvzd5Zb.js} +1 -1
- package/public/docs/assets/chunks/@localSearchIndexroot.DS2TQP5_.js +1 -0
- package/public/docs/assets/chunks/{VPLocalSearchBox.DsZrQKQR.js → VPLocalSearchBox.CNxT3s0I.js} +1 -1
- package/public/docs/assets/chunks/{theme.DsTNE2pE.js → theme.C5lLqUv7.js} +2 -2
- package/public/docs/assets/contributor-guide_architecture_board-widgets.md.CqKM_jEG.js +1 -0
- package/public/docs/assets/contributor-guide_architecture_board-widgets.md.CqKM_jEG.lean.js +1 -0
- package/public/docs/assets/{contributor-guide_architecture_board-widgets_caching-and-memory.md.8bH1HnZp.js → contributor-guide_architecture_board-widgets_caching-and-memory.md.BYDo3ClR.js} +1 -1
- package/public/docs/assets/contributor-guide_architecture_board-widgets_plan-advisor.md.ajUAVdbc.js +1 -0
- package/public/docs/assets/contributor-guide_architecture_board-widgets_visual-system-and-templating.md.WqY74T0T.js +1 -0
- package/public/docs/assets/contributor-guide_architecture_board-widgets_visual-system-and-templating.md.WqY74T0T.lean.js +1 -0
- package/public/docs/assets/contributor-guide_architecture_detector-contract.md.CHHgywoP.js +1 -0
- package/public/docs/assets/{contributor-guide_architecture_detector-contract.md.wj6Et6UD.lean.js → contributor-guide_architecture_detector-contract.md.CHHgywoP.lean.js} +1 -1
- package/public/docs/assets/contributor-guide_architecture_detector-contract_plan-attribution.md.DIz3_oz9.js +1 -0
- package/public/docs/assets/contributor-guide_architecture_detector-contract_plan-attribution.md.DIz3_oz9.lean.js +1 -0
- package/public/docs/assets/contributor-guide_architecture_detector-contract_threshold-tables.md.WH4tRHPL.js +1 -0
- package/public/docs/assets/{contributor-guide_architecture_detector-contract_threshold-tables.md.CKjWG56Y.lean.js → contributor-guide_architecture_detector-contract_threshold-tables.md.WH4tRHPL.lean.js} +1 -1
- package/public/docs/assets/{contributor-guide_architecture_drill-down.md.CqZPrdo9.js → contributor-guide_architecture_drill-down.md.yB-Hz2XT.js} +1 -1
- package/public/docs/assets/{contributor-guide_architecture_drill-down.md.CqZPrdo9.lean.js → contributor-guide_architecture_drill-down.md.yB-Hz2XT.lean.js} +1 -1
- package/public/docs/assets/contributor-guide_architecture_drill-down_plan-graph.md.BQZE04sw.js +1 -0
- package/public/docs/assets/{contributor-guide_architecture_drill-down_plan-graph.md.DwOozIEs.lean.js → contributor-guide_architecture_drill-down_plan-graph.md.BQZE04sw.lean.js} +1 -1
- package/public/docs/assets/contributor-guide_architecture_impact-estimation.md.K71YB-Rr.js +1 -0
- package/public/docs/assets/{contributor-guide_architecture_impact-estimation.md.CZv_ZGOp.lean.js → contributor-guide_architecture_impact-estimation.md.K71YB-Rr.lean.js} +1 -1
- package/public/docs/assets/contributor-guide_architecture_impact-estimation_caveats-tuning-and-coverage.md.DLCAffwn.js +1 -0
- package/public/docs/assets/{contributor-guide_architecture_impact-estimation_caveats-tuning-and-coverage.md.BUucRc0A.lean.js → contributor-guide_architecture_impact-estimation_caveats-tuning-and-coverage.md.DLCAffwn.lean.js} +1 -1
- package/public/docs/assets/contributor-guide_architecture_impact-estimation_stage-union-rollup.md.JFrzDMwo.js +1 -0
- package/public/docs/assets/contributor-guide_architecture_impact-estimation_stage-union-rollup.md.JFrzDMwo.lean.js +1 -0
- package/public/docs/assets/contributor-guide_architecture_overview.md.nxkpOhgf.js +1 -0
- package/public/docs/assets/contributor-guide_architecture_state-and-history_run-comparison-internals.md.U-9KMDFK.js +1 -0
- package/public/docs/assets/{contributor-guide_architecture_state-and-history_run-comparison-internals.md.CZA0JLtV.lean.js → contributor-guide_architecture_state-and-history_run-comparison-internals.md.U-9KMDFK.lean.js} +1 -1
- package/public/docs/assets/contributor-guide_architecture_widget-rendering.md.BrSz8Ezh.js +1 -0
- package/public/docs/assets/contributor-guide_architecture_widget-rendering_findings-tab.md.B7rjSF_h.js +1 -0
- package/public/docs/assets/contributor-guide_architecture_widget-rendering_findings-tab.md.B7rjSF_h.lean.js +1 -0
- package/public/docs/assets/{contributor-guide_architecture_widget-rendering_list-sort-mode.md.BuHKgH0C.js → contributor-guide_architecture_widget-rendering_list-sort-mode.md.37hcZJ7q.js} +1 -1
- package/public/docs/assets/{contributor-guide_architecture_widget-rendering_row-expand-contract.md.ZT89u9f1.js → contributor-guide_architecture_widget-rendering_row-expand-contract.md.mK_VmAWk.js} +1 -1
- package/public/docs/assets/{contributor-guide_architecture_worker-protocol.md.BAnhi2-d.js → contributor-guide_architecture_worker-protocol.md.Br6OE7RW.js} +1 -1
- package/public/docs/assets/contributor-guide_architecture_worker-protocol.md.Br6OE7RW.lean.js +1 -0
- package/public/docs/assets/contributor-guide_architecture_worker-protocol_cli-and-mcp.md.IVyaXrGe.js +1 -0
- package/public/docs/assets/{contributor-guide_architecture_worker-protocol_cli-and-mcp.md.DC1YqXBp.lean.js → contributor-guide_architecture_worker-protocol_cli-and-mcp.md.IVyaXrGe.lean.js} +1 -1
- package/public/docs/assets/{contributor-guide_architecture_worker-protocol_core-and-event-validation.md.DSVFPpWb.js → contributor-guide_architecture_worker-protocol_core-and-event-validation.md.DVSXn-bb.js} +1 -1
- package/public/docs/assets/{contributor-guide_architecture_worker-protocol_evidence-availability.md.CjimIDBY.js → contributor-guide_architecture_worker-protocol_evidence-availability.md.D3S5cyOW.js} +2 -2
- package/public/docs/assets/{contributor-guide_architecture_worker-protocol_evidence-availability.md.CjimIDBY.lean.js → contributor-guide_architecture_worker-protocol_evidence-availability.md.D3S5cyOW.lean.js} +1 -1
- package/public/docs/assets/contributor-guide_architecture_worker-protocol_evidence-report.md.CtmCU57I.js +1 -0
- package/public/docs/assets/{contributor-guide_architecture_worker-protocol_evidence-report.md.DVGZOWvW.lean.js → contributor-guide_architecture_worker-protocol_evidence-report.md.CtmCU57I.lean.js} +1 -1
- package/public/docs/assets/contributor-guide_contributing.md.DBW4drtZ.js +1 -0
- package/public/docs/assets/{contributor-guide_development-setup.md.D9bu4j_c.js → contributor-guide_development-setup.md.B21ZTDhn.js} +3 -3
- package/public/docs/assets/contributor-guide_development-setup.md.B21ZTDhn.lean.js +1 -0
- package/public/docs/assets/contributor-guide_testing.md.DpkozNoG.js +4 -0
- package/public/docs/assets/{contributor-guide_testing.md.By6XGR9a.lean.js → contributor-guide_testing.md.DpkozNoG.lean.js} +1 -1
- package/public/docs/assets/{index.md.CHJVslga.js → index.md.lMm7SUMz.js} +1 -1
- package/public/docs/assets/{index.md.CHJVslga.lean.js → index.md.lMm7SUMz.lean.js} +1 -1
- package/public/docs/assets/instrument-sans-latin-ext-wdth-normal.C5E2Gvlv.woff2 +0 -0
- package/public/docs/assets/instrument-sans-latin-wdth-normal.BVScPF0l.woff2 +0 -0
- package/public/docs/assets/jetbrains-mono-cyrillic-wght-normal.D73BlboJ.woff2 +0 -0
- package/public/docs/assets/jetbrains-mono-greek-wght-normal.Bw9x6K1M.woff2 +0 -0
- package/public/docs/assets/jetbrains-mono-latin-ext-wght-normal.DBQx-q_a.woff2 +0 -0
- package/public/docs/assets/jetbrains-mono-latin-wght-normal.B9CIFXIH.woff2 +0 -0
- package/public/docs/assets/jetbrains-mono-vietnamese-wght-normal.Bt-aOZkq.woff2 +0 -0
- package/public/docs/assets/style.Cfxqlj0y.css +1 -0
- package/public/docs/assets/user-guide_getting-started_ci-and-automation.md.C0pcQoNc.js +29 -0
- package/public/docs/assets/user-guide_getting-started_ci-and-automation.md.C0pcQoNc.lean.js +1 -0
- package/public/docs/assets/user-guide_getting-started_reading-the-dashboard.md.CGaxPX_1.js +1 -0
- package/public/docs/assets/{user-guide_getting-started_tuning-thresholds.md.B_MyjyZm.js → user-guide_getting-started_tuning-thresholds.md.BGVE-wrc.js} +2 -2
- package/public/docs/assets/{user-guide_getting-started_tuning-thresholds.md.B_MyjyZm.lean.js → user-guide_getting-started_tuning-thresholds.md.BGVE-wrc.lean.js} +1 -1
- package/public/docs/assets/{user-guide_mcp-tools.md.C65SjWUL.js → user-guide_mcp-tools.md.49r3L2YE.js} +1 -1
- package/public/docs/assets/{user-guide_mcp-tools_compare-runs.md.Cc_gLoix.js → user-guide_mcp-tools_compare-runs.md.BQ_kIptC.js} +11 -6
- package/public/docs/assets/user-guide_mcp-tools_compare-runs.md.BQ_kIptC.lean.js +1 -0
- package/public/docs/assets/user-guide_mcp-tools_diagnose-run.md.azCZXkH8.js +44 -0
- package/public/docs/assets/{user-guide_mcp-tools_diagnose-run.md.BP1vnHA5.lean.js → user-guide_mcp-tools_diagnose-run.md.azCZXkH8.lean.js} +1 -1
- package/public/docs/assets/{user-guide_mcp-tools_evaluate-budgets.md.BB0nDY3Z.js → user-guide_mcp-tools_evaluate-budgets.md.dpQpRQ7z.js} +2 -2
- package/public/docs/assets/{user-guide_mcp-tools_evaluate-budgets.md.BB0nDY3Z.lean.js → user-guide_mcp-tools_evaluate-budgets.md.dpQpRQ7z.lean.js} +1 -1
- package/public/docs/assets/{user-guide_mcp-tools_get-finding-evidence.md.rKyu4wts.js → user-guide_mcp-tools_get-finding-evidence.md.CH6FkNLX.js} +2 -1
- package/public/docs/assets/{user-guide_mcp-tools_get-finding-evidence.md.rKyu4wts.lean.js → user-guide_mcp-tools_get-finding-evidence.md.CH6FkNLX.lean.js} +1 -1
- package/public/docs/assets/{user-guide_mcp-tools_get-run-summary.md.DpxZ4ZNp.js → user-guide_mcp-tools_get-run-summary.md.EhaIsele.js} +1 -1
- package/public/docs/assets/user-guide_run-comparison.md.B_LOkdBf.js +1 -0
- package/public/docs/assets/user-guide_run-comparison.md.B_LOkdBf.lean.js +1 -0
- package/public/docs/assets/user-guide_understanding-findings.md.C4riKCKl.js +1 -0
- package/public/docs/assets/user-guide_understanding-findings.md.C4riKCKl.lean.js +1 -0
- package/public/docs/contributor-guide/architecture/board-widgets/caching-and-memory.html +6 -10
- package/public/docs/contributor-guide/architecture/board-widgets/plan-advisor.html +6 -10
- package/public/docs/contributor-guide/architecture/board-widgets/visual-system-and-templating.html +6 -10
- package/public/docs/contributor-guide/architecture/board-widgets.html +6 -10
- package/public/docs/contributor-guide/architecture/detector-contract/plan-attribution.html +6 -10
- package/public/docs/contributor-guide/architecture/detector-contract/threshold-tables.html +6 -10
- package/public/docs/contributor-guide/architecture/detector-contract.html +6 -10
- package/public/docs/contributor-guide/architecture/drill-down/plan-graph.html +6 -10
- package/public/docs/contributor-guide/architecture/drill-down.html +6 -10
- package/public/docs/contributor-guide/architecture/impact-estimation/caveats-tuning-and-coverage.html +6 -10
- package/public/docs/contributor-guide/architecture/impact-estimation/stage-union-rollup.html +6 -10
- package/public/docs/contributor-guide/architecture/impact-estimation.html +6 -10
- package/public/docs/contributor-guide/architecture/index.html +5 -9
- package/public/docs/contributor-guide/architecture/overview.html +6 -10
- package/public/docs/contributor-guide/architecture/state-and-history/history-server-intake.html +5 -9
- package/public/docs/contributor-guide/architecture/state-and-history/run-comparison-internals.html +6 -10
- package/public/docs/contributor-guide/architecture/state-and-history.html +5 -9
- package/public/docs/contributor-guide/architecture/widget-rendering/findings-tab.html +6 -10
- package/public/docs/contributor-guide/architecture/widget-rendering/investigation-routing.html +5 -9
- package/public/docs/contributor-guide/architecture/widget-rendering/list-sort-mode.html +6 -10
- package/public/docs/contributor-guide/architecture/widget-rendering/reference-section.html +5 -9
- package/public/docs/contributor-guide/architecture/widget-rendering/row-expand-contract.html +6 -10
- package/public/docs/contributor-guide/architecture/widget-rendering.html +6 -10
- package/public/docs/contributor-guide/architecture/worker-protocol/cli-and-mcp.html +6 -10
- package/public/docs/contributor-guide/architecture/worker-protocol/core-and-event-validation.html +6 -10
- package/public/docs/contributor-guide/architecture/worker-protocol/evidence-availability.html +7 -11
- package/public/docs/contributor-guide/architecture/worker-protocol/evidence-report.html +6 -10
- package/public/docs/contributor-guide/architecture/worker-protocol.html +6 -10
- package/public/docs/contributor-guide/contributing.html +6 -10
- package/public/docs/contributor-guide/development-setup.html +8 -12
- package/public/docs/contributor-guide/testing.html +9 -10
- package/public/docs/favicon.svg +2 -2
- package/public/docs/hashmap.json +1 -1
- package/public/docs/index.html +6 -10
- package/public/docs/logo-dark.svg +1 -0
- package/public/docs/logo-light.svg +1 -0
- package/public/docs/tuning-reference/anti-patterns.html +5 -9
- package/public/docs/tuning-reference/aqe.html +5 -9
- package/public/docs/tuning-reference/bottleneck-broadcast-sizing.html +5 -9
- package/public/docs/tuning-reference/bottleneck-cold-start.html +5 -9
- package/public/docs/tuning-reference/bottleneck-duplicate-plan-subtree.html +5 -9
- package/public/docs/tuning-reference/bottleneck-failures.html +5 -9
- package/public/docs/tuning-reference/bottleneck-gc.html +5 -9
- package/public/docs/tuning-reference/bottleneck-job-failure-rate.html +5 -9
- package/public/docs/tuning-reference/bottleneck-memory-utilization.html +5 -9
- package/public/docs/tuning-reference/bottleneck-retry-waste.html +5 -9
- package/public/docs/tuning-reference/bottleneck-shuffle.html +5 -9
- package/public/docs/tuning-reference/bottleneck-skew.html +5 -9
- package/public/docs/tuning-reference/bottleneck-slow-host.html +5 -9
- package/public/docs/tuning-reference/bottleneck-small-files.html +5 -9
- package/public/docs/tuning-reference/bottleneck-spill.html +5 -9
- package/public/docs/tuning-reference/bottleneck-straggler.html +5 -9
- package/public/docs/tuning-reference/bottleneck-tiny-tasks.html +5 -9
- package/public/docs/tuning-reference/bottleneck-utilization.html +5 -9
- package/public/docs/tuning-reference/caching.html +5 -9
- package/public/docs/tuning-reference/cluster-config.html +5 -9
- package/public/docs/tuning-reference/config.html +5 -9
- package/public/docs/tuning-reference/data-formats.html +5 -9
- package/public/docs/tuning-reference/index.html +5 -9
- package/public/docs/tuning-reference/intro.html +5 -9
- package/public/docs/tuning-reference/joins.html +5 -9
- package/public/docs/tuning-reference/memory-model.html +5 -9
- package/public/docs/tuning-reference/metrics.html +5 -9
- package/public/docs/tuning-reference/partitioning.html +5 -9
- package/public/docs/tuning-reference/pyspark.html +5 -9
- package/public/docs/tuning-reference/shuffle.html +5 -9
- package/public/docs/tuning-reference/spark-architecture.html +5 -9
- package/public/docs/tuning-reference/table-formats.html +5 -9
- package/public/docs/user-guide/alternative-log-retrieval/managed-platforms.html +5 -9
- package/public/docs/user-guide/alternative-log-retrieval/ssh-bastion.html +5 -9
- package/public/docs/user-guide/alternative-log-retrieval.html +5 -9
- package/public/docs/user-guide/getting-started/ci-and-automation.html +17 -15
- package/public/docs/user-guide/getting-started/reading-the-dashboard.html +6 -10
- package/public/docs/user-guide/getting-started/regression-metric-keys.html +5 -9
- package/public/docs/user-guide/getting-started/tuning-thresholds.html +7 -11
- package/public/docs/user-guide/getting-started.html +5 -9
- package/public/docs/user-guide/mcp-tools/compare-runs.html +16 -15
- package/public/docs/user-guide/mcp-tools/diagnose-run.html +28 -11
- package/public/docs/user-guide/mcp-tools/evaluate-budgets.html +6 -10
- package/public/docs/user-guide/mcp-tools/get-finding-documentation.html +5 -9
- package/public/docs/user-guide/mcp-tools/get-finding-evidence.html +7 -10
- package/public/docs/user-guide/mcp-tools/get-reference-doc.html +5 -9
- package/public/docs/user-guide/mcp-tools/get-run-summary.html +6 -10
- package/public/docs/user-guide/mcp-tools/list-runs.html +5 -9
- package/public/docs/user-guide/mcp-tools.html +6 -10
- package/public/docs/user-guide/run-comparison/how-stages-are-matched.html +5 -9
- package/public/docs/user-guide/run-comparison.html +6 -10
- package/public/docs/user-guide/understanding-findings.html +6 -10
- package/public/export-template.html +46 -46
- package/public/favicon.svg +2 -2
- package/public/index.html +8 -10
- package/public/sample-runs/sample-run.ndjson.gz +0 -0
- package/vendor-core/allocation.js +126 -39
- package/vendor-core/analyzer.js +85 -58
- package/vendor-core/api-merge-writes.js +3 -0
- package/vendor-core/aqe-skew.js +347 -0
- package/vendor-core/cli/budgets.js +6 -4
- package/vendor-core/cli/collect-run-pair.js +89 -0
- package/vendor-core/cli/collect-run-worker.js +16 -0
- package/vendor-core/cli/collect-run.js +1 -2
- package/vendor-core/cli/native-zstd.js +12 -16
- package/vendor-core/comparability.js +234 -0
- package/vendor-core/comparison-output.js +15 -7
- package/vendor-core/comparison-verdict.js +105 -25
- package/vendor-core/core-source-hash.txt +1 -1
- package/vendor-core/core-time-series.js +0 -1
- package/vendor-core/core-usage-locality.js +1 -1
- package/vendor-core/delta-log-paths.js +10 -1
- package/vendor-core/detectors.js +1078 -416
- package/vendor-core/docs-config.js +0 -4
- package/vendor-core/docs-content/detection/cache.md +2 -1
- package/vendor-core/docs-content/detection/cfg.md +19 -11
- package/vendor-core/docs-content/detection/cold.md +2 -1
- package/vendor-core/docs-content/detection/gc.md +7 -3
- package/vendor-core/docs-content/detection/host.md +11 -1
- package/vendor-core/docs-content/detection/mem.md +17 -6
- package/vendor-core/docs-content/detection/part.md +3 -1
- package/vendor-core/docs-content/detection/plan.md +55 -13
- package/vendor-core/docs-content/detection/shfl.md +11 -5
- package/vendor-core/docs-content/detection/skew.md +48 -1
- package/vendor-core/docs-content/detection/slow.md +4 -2
- package/vendor-core/docs-content/detection/spec.md +6 -1
- package/vendor-core/docs-content/detection/spill.md +6 -3
- package/vendor-core/docs-content/detection/strag.md +19 -6
- package/vendor-core/docs-content/detection/tiny.md +9 -3
- package/vendor-core/docs-content/detection/util.md +6 -2
- package/vendor-core/effective-conf.js +7 -10
- package/vendor-core/efficiency-model.js +24 -16
- package/vendor-core/etl-phases.js +1 -2
- package/vendor-core/event-handlers.js +175 -57
- package/vendor-core/event-schemas.js +21 -16
- package/vendor-core/evidence-availability.js +9 -2
- package/vendor-core/evidence-report.js +118 -35
- package/vendor-core/executor-peaks.js +41 -0
- package/vendor-core/export-data.js +5 -5
- package/vendor-core/finding-identity.js +78 -0
- package/vendor-core/finding-presentation.js +129 -39
- package/vendor-core/finding-types.js +108 -30
- package/vendor-core/format-utils.js +14 -15
- package/vendor-core/html-export.js +1 -1
- package/vendor-core/impact-band.js +2 -2
- package/vendor-core/impact-format.js +47 -19
- package/vendor-core/impact-model.js +28 -17
- package/vendor-core/job-groups.js +4 -4
- package/vendor-core/mcp-server-factory.js +48 -12
- package/vendor-core/mcp-tools.js +179 -24
- package/vendor-core/median.js +2 -2
- package/vendor-core/nested-loop-join.js +73 -0
- package/vendor-core/occupancy.js +1 -2
- package/vendor-core/parser-worker.js +1 -1
- package/vendor-core/plan-graph-model.js +14 -22
- package/vendor-core/plan-node-detail.js +2 -3
- package/vendor-core/plan-summary.js +24 -19
- package/vendor-core/plan-tree-walk.js +6 -8
- package/vendor-core/python-stage.js +12 -1
- package/vendor-core/recommendation-rollup.js +13 -12
- package/vendor-core/redact.js +52 -46
- package/vendor-core/remediation.js +10 -5
- package/vendor-core/run-aggregates.js +6 -8
- package/vendor-core/run-comparison.js +226 -66
- package/vendor-core/run-identity.js +12 -0
- package/vendor-core/run-interpretation.js +21 -0
- package/vendor-core/run-metrics.js +2 -2
- package/vendor-core/run-output.js +44 -11
- package/vendor-core/run-totals.js +12 -0
- package/vendor-core/run-verdict.js +76 -3
- package/vendor-core/scaling-sim.js +3 -4
- package/vendor-core/snappy-block.js +2 -2
- package/vendor-core/spark-conf.js +168 -0
- package/vendor-core/sql-stages.js +2 -2
- package/vendor-core/stage-alignment.js +2 -12
- package/vendor-core/stage-identity.js +58 -3
- package/vendor-core/stage-label.js +14 -0
- package/vendor-core/stage-plan-nodes.js +17 -3
- package/vendor-core/stage-quantiles.js +141 -9
- package/vendor-core/stage-structure.js +17 -3
- package/vendor-core/threshold-overrides.js +9 -3
- package/vendor-core/types.js +70 -23
- package/vendor-core/wall-clock.js +8 -0
- package/vendor-core/wasted-core-hours.js +12 -12
- package/vendor-core/write-targets.js +146 -14
- package/vendor-core/zstd-worker-client.js +1 -1
- package/vendor-core/zstd-worker.js +1 -1
- package/public/assets/AutoscalingChurn-8t3U3isq.js +0 -1
- package/public/assets/CacheUtilization-CJs9tTum.js +0 -1
- package/public/assets/CachingOpportunity-D1NcHs0V.js +0 -1
- package/public/assets/ColdStart-CdRJ9gD8.js +0 -1
- package/public/assets/ConfigAudit-B5Gbe5js.js +0 -1
- package/public/assets/CoreUsageArea-a--NTRGY.js +0 -1
- package/public/assets/Dashboard-C1hNeX49.js +0 -2
- package/public/assets/DisclosureContext-ZpE6CkHx.js +0 -1
- package/public/assets/DuplicatePlanSubtree-dobXdz7E.js +0 -1
- package/public/assets/ExecutorUtilization-D9grwi7t.js +0 -1
- package/public/assets/GcPressure-8-G2ri10.js +0 -1
- package/public/assets/IncompleteRun-B91lky7a.js +0 -1
- package/public/assets/JobFailures-BsWvBMyJ.js +0 -1
- package/public/assets/MemoryUtilization-BM5schZI.js +0 -1
- package/public/assets/OverBroadcast-DdN8JIJH.js +0 -1
- package/public/assets/PartitionHint-CUvbnnxy.js +0 -1
- package/public/assets/PartitionSizing-CY5HDYtp.js +0 -1
- package/public/assets/PlanExplorer-DgHCDBD_.js +0 -1
- package/public/assets/PlanGraphRoute-DH3KJb8j.js +0 -1
- package/public/assets/RetryWaste-DOnE9vGF.js +0 -1
- package/public/assets/ShuffleIO-MMnDESkF.js +0 -1
- package/public/assets/Skew-BmZZJ5ms.js +0 -1
- package/public/assets/SlowHost-CsJzfEqo.js +0 -1
- package/public/assets/SmallFiles-BoK3R1Ex.js +0 -1
- package/public/assets/SpeculationWaste-CnVxB5AJ.js +0 -1
- package/public/assets/Spill-BhNicyBy.js +0 -1
- package/public/assets/StageFailed-mAhHU4l_.js +0 -1
- package/public/assets/StageFindingGroup-BEtPWcT0.js +0 -1
- package/public/assets/StageHeader-DJkYkrsU.js +0 -1
- package/public/assets/StageShape-BDxRknLp.js +0 -1
- package/public/assets/StageSlowness-BPRw-otN.js +0 -1
- package/public/assets/Straggler-CZCbnOWP.js +0 -1
- package/public/assets/TaskFailures-C57YcLFQ.js +0 -1
- package/public/assets/TinyTask-Bi84qU7n.js +0 -1
- package/public/assets/UnderBroadcast-DdQV7htE.js +0 -1
- package/public/assets/charts-vendor-0VMaLVLN.js +0 -59
- package/public/assets/finding-anchor-Cl6_5hfV.js +0 -1
- package/public/assets/impact-sort-CssZ6MT2.js +0 -1
- package/public/assets/index-2h_TgUAb.css +0 -2
- package/public/assets/index-B-03mG7K.js +0 -14
- package/public/assets/plan-graph-vendor-BYl-AzN5.js +0 -7
- package/public/assets/react-vendor-DEdfrRTJ.js +0 -9
- package/public/assets/select-CQjNhprm.js +0 -1
- package/public/assets/usePagedRows-Dyl6T8Ok.js +0 -1
- package/public/assets/useRecentFiles-XZEnLlal.js +0 -11
- package/public/assets/useSortMode-Dhvit8dt.js +0 -1
- package/public/docs/assets/chunks/@localSearchIndexroot.u_e5bQz4.js +0 -1
- package/public/docs/assets/contributor-guide_architecture_board-widgets.md.YQcj5EI4.js +0 -1
- package/public/docs/assets/contributor-guide_architecture_board-widgets.md.YQcj5EI4.lean.js +0 -1
- package/public/docs/assets/contributor-guide_architecture_board-widgets_plan-advisor.md.RlzvUmNm.js +0 -1
- package/public/docs/assets/contributor-guide_architecture_board-widgets_visual-system-and-templating.md.DYgUpIJB.js +0 -1
- package/public/docs/assets/contributor-guide_architecture_board-widgets_visual-system-and-templating.md.DYgUpIJB.lean.js +0 -1
- package/public/docs/assets/contributor-guide_architecture_detector-contract.md.wj6Et6UD.js +0 -1
- package/public/docs/assets/contributor-guide_architecture_detector-contract_plan-attribution.md.yNex4bys.js +0 -1
- package/public/docs/assets/contributor-guide_architecture_detector-contract_plan-attribution.md.yNex4bys.lean.js +0 -1
- package/public/docs/assets/contributor-guide_architecture_detector-contract_threshold-tables.md.CKjWG56Y.js +0 -1
- package/public/docs/assets/contributor-guide_architecture_drill-down_plan-graph.md.DwOozIEs.js +0 -1
- package/public/docs/assets/contributor-guide_architecture_impact-estimation.md.CZv_ZGOp.js +0 -1
- package/public/docs/assets/contributor-guide_architecture_impact-estimation_caveats-tuning-and-coverage.md.BUucRc0A.js +0 -1
- package/public/docs/assets/contributor-guide_architecture_impact-estimation_stage-union-rollup.md.DdCGtAGu.js +0 -1
- package/public/docs/assets/contributor-guide_architecture_impact-estimation_stage-union-rollup.md.DdCGtAGu.lean.js +0 -1
- package/public/docs/assets/contributor-guide_architecture_overview.md.C1sSvm9i.js +0 -1
- package/public/docs/assets/contributor-guide_architecture_state-and-history_run-comparison-internals.md.CZA0JLtV.js +0 -1
- package/public/docs/assets/contributor-guide_architecture_widget-rendering.md.BOZ1azXG.js +0 -1
- package/public/docs/assets/contributor-guide_architecture_widget-rendering_findings-tab.md.BQXycK6G.js +0 -1
- package/public/docs/assets/contributor-guide_architecture_widget-rendering_findings-tab.md.BQXycK6G.lean.js +0 -1
- package/public/docs/assets/contributor-guide_architecture_worker-protocol.md.BAnhi2-d.lean.js +0 -1
- package/public/docs/assets/contributor-guide_architecture_worker-protocol_cli-and-mcp.md.DC1YqXBp.js +0 -1
- package/public/docs/assets/contributor-guide_architecture_worker-protocol_evidence-report.md.DVGZOWvW.js +0 -1
- package/public/docs/assets/contributor-guide_contributing.md.CQMvGwFt.js +0 -1
- package/public/docs/assets/contributor-guide_development-setup.md.D9bu4j_c.lean.js +0 -1
- package/public/docs/assets/contributor-guide_testing.md.By6XGR9a.js +0 -1
- package/public/docs/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 +0 -0
- package/public/docs/assets/inter-italic-cyrillic.By2_1cv3.woff2 +0 -0
- package/public/docs/assets/inter-italic-greek-ext.1u6EdAuj.woff2 +0 -0
- package/public/docs/assets/inter-italic-greek.DJ8dCoTZ.woff2 +0 -0
- package/public/docs/assets/inter-italic-latin-ext.CN1xVJS-.woff2 +0 -0
- package/public/docs/assets/inter-italic-latin.C2AdPX0b.woff2 +0 -0
- package/public/docs/assets/inter-italic-vietnamese.BSbpV94h.woff2 +0 -0
- package/public/docs/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 +0 -0
- package/public/docs/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 +0 -0
- package/public/docs/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 +0 -0
- package/public/docs/assets/inter-roman-greek.BBVDIX6e.woff2 +0 -0
- package/public/docs/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 +0 -0
- package/public/docs/assets/inter-roman-latin.Di8DUHzh.woff2 +0 -0
- package/public/docs/assets/inter-roman-vietnamese.BjW4sHH5.woff2 +0 -0
- package/public/docs/assets/style.tmDhD3c8.css +0 -1
- package/public/docs/assets/user-guide_getting-started_ci-and-automation.md.OUQqw3mI.js +0 -23
- package/public/docs/assets/user-guide_getting-started_ci-and-automation.md.OUQqw3mI.lean.js +0 -1
- package/public/docs/assets/user-guide_getting-started_reading-the-dashboard.md.Obf3W3__.js +0 -1
- package/public/docs/assets/user-guide_mcp-tools_compare-runs.md.Cc_gLoix.lean.js +0 -1
- package/public/docs/assets/user-guide_mcp-tools_diagnose-run.md.BP1vnHA5.js +0 -23
- package/public/docs/assets/user-guide_run-comparison.md.BUALkohi.js +0 -1
- package/public/docs/assets/user-guide_run-comparison.md.BUALkohi.lean.js +0 -1
- package/public/docs/assets/user-guide_understanding-findings.md.C9YRruMT.js +0 -1
- package/public/docs/assets/user-guide_understanding-findings.md.C9YRruMT.lean.js +0 -1
- /package/public/docs/assets/{contributor-guide_architecture_board-widgets_caching-and-memory.md.8bH1HnZp.lean.js → contributor-guide_architecture_board-widgets_caching-and-memory.md.BYDo3ClR.lean.js} +0 -0
- /package/public/docs/assets/{contributor-guide_architecture_board-widgets_plan-advisor.md.RlzvUmNm.lean.js → contributor-guide_architecture_board-widgets_plan-advisor.md.ajUAVdbc.lean.js} +0 -0
- /package/public/docs/assets/{contributor-guide_architecture_overview.md.C1sSvm9i.lean.js → contributor-guide_architecture_overview.md.nxkpOhgf.lean.js} +0 -0
- /package/public/docs/assets/{contributor-guide_architecture_widget-rendering.md.BOZ1azXG.lean.js → contributor-guide_architecture_widget-rendering.md.BrSz8Ezh.lean.js} +0 -0
- /package/public/docs/assets/{contributor-guide_architecture_widget-rendering_list-sort-mode.md.BuHKgH0C.lean.js → contributor-guide_architecture_widget-rendering_list-sort-mode.md.37hcZJ7q.lean.js} +0 -0
- /package/public/docs/assets/{contributor-guide_architecture_widget-rendering_row-expand-contract.md.ZT89u9f1.lean.js → contributor-guide_architecture_widget-rendering_row-expand-contract.md.mK_VmAWk.lean.js} +0 -0
- /package/public/docs/assets/{contributor-guide_architecture_worker-protocol_core-and-event-validation.md.DSVFPpWb.lean.js → contributor-guide_architecture_worker-protocol_core-and-event-validation.md.DVSXn-bb.lean.js} +0 -0
- /package/public/docs/assets/{contributor-guide_contributing.md.CQMvGwFt.lean.js → contributor-guide_contributing.md.DBW4drtZ.lean.js} +0 -0
- /package/public/docs/assets/{user-guide_getting-started_reading-the-dashboard.md.Obf3W3__.lean.js → user-guide_getting-started_reading-the-dashboard.md.CGaxPX_1.lean.js} +0 -0
- /package/public/docs/assets/{user-guide_mcp-tools.md.C65SjWUL.lean.js → user-guide_mcp-tools.md.49r3L2YE.lean.js} +0 -0
- /package/public/docs/assets/{user-guide_mcp-tools_get-run-summary.md.DpxZ4ZNp.lean.js → user-guide_mcp-tools_get-run-summary.md.EhaIsele.lean.js} +0 -0
|
@@ -60,11 +60,9 @@ export const METRIC_ANCHORS = {
|
|
|
60
60
|
// section, and gating keeps that from becoming a dead "Learn more" link. docs-config.test.js
|
|
61
61
|
// asserts this stays a subset of the real ids so it can't drift.
|
|
62
62
|
export const KNOWN_DOC_ANCHORS = new Set([
|
|
63
|
-
// Page sections
|
|
64
63
|
'#intro', '#spark-architecture', '#memory-model', '#partitioning', '#joins',
|
|
65
64
|
'#shuffle', '#data-formats', '#table-formats', '#caching', '#pyspark', '#aqe',
|
|
66
65
|
'#cluster-config', '#anti-patterns', '#metrics', '#config',
|
|
67
|
-
// Bottleneck sections
|
|
68
66
|
'#bottleneck-cold-start', '#bottleneck-failures', '#bottleneck-gc',
|
|
69
67
|
'#bottleneck-job-failure-rate', '#bottleneck-retry-waste', '#bottleneck-shuffle',
|
|
70
68
|
'#bottleneck-skew', '#bottleneck-slow-host', '#bottleneck-spill',
|
|
@@ -75,10 +73,8 @@ export const KNOWN_DOC_ANCHORS = new Set([
|
|
|
75
73
|
'#bottleneck-partition-sizing', '#bottleneck-speculation-waste',
|
|
76
74
|
'#bottleneck-core-locality', '#bottleneck-caching-opportunity',
|
|
77
75
|
'#bottleneck-autoscaling-churn', '#bottleneck-cache-utilization',
|
|
78
|
-
// Config-audit sections
|
|
79
76
|
'#config-autoscale-bounds', '#config-memory-overhead', '#config-serializer',
|
|
80
77
|
'#config-shuffle-service',
|
|
81
|
-
// Metric glossary entries
|
|
82
78
|
...Object.values(METRIC_ANCHORS),
|
|
83
79
|
]);
|
|
84
80
|
|
|
@@ -5,4 +5,5 @@ join/union result recomputed by two or more executions, matched by plan
|
|
|
5
5
|
shape) may be worth persisting between stages. Self-flags a confidence that scales with
|
|
6
6
|
how many executions reuse the same relation: reuse is only inferred, from
|
|
7
7
|
plan-scan identity across SQL executions, so confirm the reads really do
|
|
8
|
-
hit the same data before you cache anything.
|
|
8
|
+
hit the same data before you cache anything. The figure is the input those
|
|
9
|
+
queries scanned and how many queries scanned it, not a time.
|
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
### `CFG`: Configuration audit {#cfg}
|
|
2
2
|
|
|
3
3
|
Flags configuration settings that may cause reliability or efficiency
|
|
4
|
-
problems, independent of any one stage's behavior.
|
|
4
|
+
problems, independent of any one stage's behavior. Three checks run:
|
|
5
5
|
|
|
6
|
-
- `spark.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- `spark.dynamicAllocation.minExecutors`/`maxExecutors`: with dynamic
|
|
10
|
-
allocation on, flagged when min exceeds max (reported on `minExecutors`)
|
|
11
|
-
or when no max is set.
|
|
6
|
+
- `spark.dynamicAllocation.maxExecutors`: with dynamic allocation on,
|
|
7
|
+
flagged when the effective max is Spark's unbounded default, so the cluster
|
|
8
|
+
can grow without a cap.
|
|
12
9
|
- `spark.serializer`: flagged when not set to Kryo (the default is the Java
|
|
13
|
-
serializer)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
serializer), and only on a run with stages outside any SQL execution.
|
|
11
|
+
DataFrame and SQL shuffles and caches use Spark's own row format, so the
|
|
12
|
+
serializer only matters for RDD work.
|
|
13
|
+
`org.apache.spark.serializer.KryoSerializer` is faster and produces smaller
|
|
14
|
+
buffers.
|
|
15
|
+
- `spark.executor.memoryOverhead`: flagged when set below the overhead Spark
|
|
16
|
+
computes by default, max(`spark.executor.minMemoryOverhead`, executor memory
|
|
17
|
+
times `spark.executor.memoryOverheadFactor`). The minimum is 384 MiB and the
|
|
18
|
+
factor 10% unless the run sets them; each setting counts only on a Spark
|
|
19
|
+
version that reads it (the factor from 3.3, the minimum from 4.0).
|
|
20
|
+
|
|
21
|
+
Two settings are never flagged because Spark rejects them at startup, so no
|
|
22
|
+
event log carries them: dynamic allocation with neither the external shuffle
|
|
23
|
+
service, shuffle tracking, shuffle-block decommissioning nor a reliable
|
|
24
|
+
shuffle storage plugin, and `minExecutors` above `maxExecutors`.
|
|
@@ -4,4 +4,5 @@ The first stage waited more than 30 s for an executor. Keep a warm pool of
|
|
|
4
4
|
executors, or, with dynamic allocation, raise
|
|
5
5
|
`spark.dynamicAllocation.minExecutors`/`initialExecutors` so the app doesn't
|
|
6
6
|
scale up from zero. With dynamic allocation off (`evidence.dynamicAllocation`
|
|
7
|
-
is `off
|
|
7
|
+
is `off`, which includes a run that never set it, as Spark defaults it off) no
|
|
8
|
+
executor-count property applies and `remediation` is empty.
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Tasks spend more than 10% of executor run time reclaiming memory. Reduce
|
|
4
4
|
object creation: use primitive types, avoid UDFs, or raise executor memory.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
When the log carries no measured executor heap peaks, or the executor memory
|
|
6
|
+
is unknown, so [`MEM`](#mem) cannot judge the heap, a stage with GC below 5%
|
|
7
|
+
gets an informational note that executor memory may be over-provisioned, only
|
|
8
|
+
on stages that take at least 0.5% of the run, and never on a stage that failed
|
|
9
|
+
or lost tasks. Both need at least 10 s of executor run time on the stage. A
|
|
10
|
+
stage with advice to raise executor memory (high GC, volume spill, a GC-bound
|
|
11
|
+
straggler tail) gets no advice to lower it.
|
|
@@ -4,4 +4,14 @@ One executor is much slower than its peers, or carries most of the stage's
|
|
|
4
4
|
task time or bytes. It may just hold data locality
|
|
5
5
|
for its tasks or carry one heavy stage, rather than a hardware fault.
|
|
6
6
|
Enable `spark.speculation` to relaunch a lagging task automatically. Only
|
|
7
|
-
flagged on stages that take at least 0.5% of the run.
|
|
7
|
+
flagged on stages that take at least 0.5% of the run. A task-time grade
|
|
8
|
+
rests on the largest of N executor means, which a larger executor count reaches
|
|
9
|
+
by chance more often, so the finding states `confidence: low` with the executor
|
|
10
|
+
count and the task count.
|
|
11
|
+
|
|
12
|
+
An executor whose tasks ran slower than the median executor's is flagged only
|
|
13
|
+
when the gap is larger than the stage's own spread of task times and the
|
|
14
|
+
executor's task count allow. The slowest of 75 executors tops the median by
|
|
15
|
+
chance far more often than the slowest of 3, so the gap it needs grows with
|
|
16
|
+
the number of executors. A stage whose per-task timings are missing flags no
|
|
17
|
+
executor on task time.
|
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
### `MEM`: Memory utilization {#mem}
|
|
2
2
|
|
|
3
3
|
Executor memory or core capacity may be over- or under-provisioned: more
|
|
4
|
-
than 50% of
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
than 50% of allocated core time ran no task, or the busiest executor's heap
|
|
5
|
+
peak stayed below 70% of `spark.executor.memory`. Heap peaks come from the
|
|
6
|
+
executor metrics Spark 3+ writes on every task end (and from stage executor
|
|
7
|
+
metrics when `spark.eventLog.logStageExecutorMetrics=true`). Spark samples them
|
|
8
|
+
at executor heartbeat, so a peak is a lower bound, and the heap-used metric
|
|
9
|
+
counts uncollected garbage, so a peak near the limit is not reported as a
|
|
10
|
+
memory risk. A log with no peaks (every task ended between two heartbeats, so
|
|
11
|
+
each reports zeros, as in local mode) gets a note that executor memory sizing was
|
|
12
|
+
not measured; it suggests `spark.eventLog.logStageExecutorMetrics=true` while that
|
|
13
|
+
is off. A run-level finding that advises lowering executor memory (a heap under
|
|
14
|
+
70%, idle allocated memory-time) keeps its figures but not that advice when any
|
|
15
|
+
stage asks for more memory, and names those stages; a stage's low-GC note is
|
|
16
|
+
dropped on a stage that asks for more. The
|
|
17
|
+
idle-memory figure counts the executors' alive time, not the peak executor count
|
|
18
|
+
over the whole run.
|
|
8
19
|
Review `spark.executor.memory` and executor count if allocated memory sat
|
|
9
20
|
largely idle over the run. That idle-memory variant self-flags a confidence
|
|
10
21
|
that scales with how far the estimated waste sits past a 1.5x buffer: it
|
|
11
|
-
estimates waste from allocated memory-time versus task run time
|
|
12
|
-
measured heap usage). Check it against
|
|
22
|
+
estimates waste from allocated memory-time versus task run time per
|
|
23
|
+
executor core (not measured heap usage). Check it against
|
|
13
24
|
the Spark UI before resizing anything.
|
|
@@ -2,4 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
Shuffle partitions are too large, too uneven, or too few for the work. A
|
|
4
4
|
single shuffle partition over 5 GB, for example, will OOM or spill heavily:
|
|
5
|
-
repartition to break it up before the stage runs.
|
|
5
|
+
repartition to break it up before the stage runs. The partition-skew rule
|
|
6
|
+
words its advice the same way a `SKEW` finding does, including
|
|
7
|
+
`evidence.aqeSkew`.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
### `PLAN`: Plan advisor {#plan}
|
|
2
2
|
|
|
3
|
-
Flags patterns in the SQL execution plan worth reviewing.
|
|
3
|
+
Flags patterns in the SQL execution plan worth reviewing. Six checks share
|
|
4
4
|
this tag:
|
|
5
5
|
|
|
6
6
|
- Duplicate plan subtree: the same subtree recomputed more than once in the
|
|
@@ -9,16 +9,58 @@ this tag:
|
|
|
9
9
|
when the repeat's stages take at least 0.5% of the run.
|
|
10
10
|
- Small files: one plan node reads or writes more than 100 files averaging
|
|
11
11
|
under 3 MB. Compact upstream output, or coalesce before writing.
|
|
12
|
-
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
- Nested loop join: a `BroadcastNestedLoopJoin` or `CartesianProduct` whose
|
|
13
|
+
output has at least 1,000,000 rows (the rows a `CartesianProduct`'s condition
|
|
14
|
+
kept, when it has one). A `BroadcastNestedLoopJoin` must also
|
|
15
|
+
produce at least 10 times the rows of its larger input; a `CartesianProduct`
|
|
16
|
+
is judged on its output alone, because it re-reads each input once per
|
|
17
|
+
partition of the other side, so the input row counts the executors report
|
|
18
|
+
are not row counts. Spark plans these when a join has no equi-join key. The
|
|
19
|
+
finding carries the join condition and is graded by the time of the stages
|
|
20
|
+
that run the join. The advice is to add an equi-join key, to bucket the range
|
|
21
|
+
of a range join and join on the bucket, or to confirm that a cross join is
|
|
22
|
+
intended. It needs the executors' `number of output rows` metrics, so a join
|
|
23
|
+
with no reported row counts is not flagged.
|
|
24
|
+
- Row-at-a-time Python UDF: a plan runs `BatchEvalPython`, which pickles
|
|
25
|
+
every row to a Python worker and back. Flagged when its stages sent at
|
|
26
|
+
least 64 MiB to the workers (`data sent to Python workers`) and ran for at
|
|
27
|
+
least 30 seconds together; the finding reports the bytes sent and returned
|
|
28
|
+
and the stage time, and is informational. `ArrowEvalPython` (Arrow-optimized
|
|
29
|
+
and pandas UDFs) is never flagged. The advice is
|
|
30
|
+
`spark.sql.execution.pythonUDF.arrow.enabled=true` (Spark 3.4 and later;
|
|
31
|
+
already the default from 4.2, where the UDF may have opted out with
|
|
32
|
+
`useArrow=False`, take no arguments, or have been created before the property
|
|
33
|
+
was set) or a pandas UDF. These floors are conservative guesses,
|
|
34
|
+
not tuned against real workloads. A plan that reports no
|
|
35
|
+
`data sent to Python workers` value is skipped.
|
|
36
|
+
- Under-broadcast: a side of a Sort Merge Join that its join type can
|
|
37
|
+
broadcast (`evidence.buildSide`, sized by the finding's value) was not
|
|
38
|
+
broadcast although it is small enough: it is over a small effective
|
|
39
|
+
threshold (`evidence.broadcastThreshold` is `limits`), or automatic
|
|
40
|
+
broadcast is disabled with `-1` (`disabled`); consider a `broadcast()` hint
|
|
41
|
+
or setting the threshold property. The size is
|
|
42
|
+
the shuffle's `data size`, the metric adaptive execution compares at runtime.
|
|
43
|
+
The threshold is `spark.sql.adaptive.autoBroadcastJoinThreshold` when the
|
|
44
|
+
plan is adaptive and that property is set, else
|
|
45
|
+
`spark.sql.autoBroadcastJoinThreshold` (the query's own setting, else the
|
|
46
|
+
logged one, else Spark's 10 MiB). A full outer join never fires, and a side
|
|
47
|
+
under 1 MiB or over the over-broadcast limit is skipped. When the effective
|
|
48
|
+
threshold already admits the side (`evidence.broadcastThreshold` is
|
|
49
|
+
`notLimiting`), the threshold is not what stopped the broadcast, so
|
|
50
|
+
`remediation` is empty and the advice is a hint or table statistics (for an
|
|
51
|
+
adaptive plan, `spark.sql.adaptive.nonEmptyPartitionRatioForBroadcastJoin`:
|
|
52
|
+
AQE keeps a side with a low share of non-empty partitions out of a broadcast
|
|
53
|
+
whatever its size). Both
|
|
54
|
+
sides need a shuffle `data size` of their own, so a join over another join's
|
|
55
|
+
output is skipped, and so is a join whose only buildable side is larger than
|
|
56
|
+
the other side, since broadcasting it saves nothing. The build side is
|
|
57
|
+
always the smaller one and `evidence.largerSideBytes` is the other side.
|
|
19
58
|
- Over-broadcast: a broadcast exceeds the 1 GB threshold; check for a
|
|
20
|
-
misapplied broadcast hint or a misconfigured
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
59
|
+
misapplied broadcast hint or a misconfigured threshold property. Under
|
|
60
|
+
adaptive execution a broadcast planned up front is admitted by
|
|
61
|
+
`spark.sql.autoBroadcastJoinThreshold` and one converted at runtime by
|
|
62
|
+
`spark.sql.adaptive.autoBroadcastJoinThreshold` (when set), so the finding
|
|
63
|
+
names whichever of them admits the broadcast. When every applicable
|
|
64
|
+
threshold is below the broadcast or disabled (`evidence.broadcastThreshold`
|
|
65
|
+
is `notLimiting`, or `disabled` when all are disabled), a hint forced it:
|
|
66
|
+
remove the hint, and `remediation` is empty.
|
|
@@ -4,8 +4,14 @@ Tasks move a large amount of intermediate data between stages. Raise
|
|
|
4
4
|
`spark.sql.shuffle.partitions`, or add a broadcast join. The partition-count
|
|
5
5
|
advice follows the effective conf (`evidence.partitions`): `raise` when the
|
|
6
6
|
property limits the stage, `sufficient` when the tasks already read a good
|
|
7
|
-
size each, `aqeCoalesced` when AQE merged the partitions
|
|
8
|
-
`spark.sql.adaptive.advisoryPartitionSizeInBytes`), and
|
|
9
|
-
the property is already high enough (the stage's own
|
|
10
|
-
parallelism limits it
|
|
11
|
-
|
|
7
|
+
size each, `aqeCoalesced` when AQE merged the partitions of a stage in a SQL
|
|
8
|
+
execution (lower `spark.sql.adaptive.advisoryPartitionSizeInBytes`), and
|
|
9
|
+
`ownPartitioning` when the property is already high enough (the stage's own
|
|
10
|
+
`repartition(n)` or RDD parallelism limits it, as for any stage outside a SQL
|
|
11
|
+
execution). With AQE coalescing on,
|
|
12
|
+
`spark.sql.adaptive.coalescePartitions.initialPartitionNum` replaces the
|
|
13
|
+
property as the starting count when it is set, and a stage that ran more tasks
|
|
14
|
+
than that, with a skew split in the final plan or no final plan to rule one
|
|
15
|
+
out, is not blamed on its own `repartition(n)`: the advice states the task and
|
|
16
|
+
configured counts and names `repartition(n)` only when the plan holds one the
|
|
17
|
+
job wrote. Only flagged on stages that take at least 0.5% of the run.
|
|
@@ -8,7 +8,54 @@ stage. The fix depends on what the stage reads, which the finding's
|
|
|
8
8
|
already has it; otherwise salt the key or repartition on a better key. A
|
|
9
9
|
stage that reads files with uneven sizes (`inputScan`) gets compaction of
|
|
10
10
|
small files or a lower `spark.sql.files.maxPartitionBytes`. Any other stage
|
|
11
|
-
(`other`) gets the salting advice and no conf
|
|
11
|
+
(`other`) gets the salting advice and no conf, as a `code` entry in
|
|
12
|
+
`remediation`. Flagged when P95 task time
|
|
12
13
|
(the longest task, on a stage with fewer than 20 tasks) exceeds 3x the median
|
|
13
14
|
and the recoverable tail is at least 0.5% of the run. The median is the
|
|
14
15
|
textbook one: on an even task count, the mean of the two middle values.
|
|
16
|
+
|
|
17
|
+
Skew is a statement about data volume, as in Spark's UI and AQE. Each stage's
|
|
18
|
+
slow tasks (over 3x the median task) are compared with the median task's input
|
|
19
|
+
plus shuffle-read bytes and records. If run time scaled with that volume, the
|
|
20
|
+
share of the slow tasks' extra time it accounts for is the data share; at 50% or
|
|
21
|
+
more the tail is skew (`evidence.cause` is `data`, `evidence.dataRatio` is the
|
|
22
|
+
median slow task's volume over the median task's). A tail that mostly is not data
|
|
23
|
+
is reported as `STRAG` with its cause. Ratios are taken only against a median task that read at least
|
|
24
|
+
1 MiB or 1,000 records, so a median of a few bytes never prints a huge multiple. When the median task read less than that floor (almost nothing),
|
|
25
|
+
there is no ratio to take (`evidence.dataRatio` is absent, and the advice says the
|
|
26
|
+
median task read almost nothing): GC and fetch wait claim their share of the slow
|
|
27
|
+
tasks' extra time first, and a slow task that read data (at least 1 MiB or 1,000
|
|
28
|
+
records) owns what is left. When the data share is under 50%, the cause is the largest
|
|
29
|
+
of GC, fetch wait, host and what none of them accounts for. With no data volume
|
|
30
|
+
to compare, what none of them accounts for is labelled `unattributed` (no share is
|
|
31
|
+
reported) instead of `unexplained`; GC, fetch wait or host still win when larger. A
|
|
32
|
+
stage with no tail attribution is `unattributed` too. An `unattributed` tail is
|
|
33
|
+
reported as `STRAG` only, never as `SKEW`.
|
|
34
|
+
|
|
35
|
+
With AQE skew-join handling on, a `shuffleJoin` stage's advice says why
|
|
36
|
+
handling did or did not act on that stage's join, read from the execution's
|
|
37
|
+
final plan and its effective conf. `evidence.aqeSkew` records the case:
|
|
38
|
+
|
|
39
|
+
| `aqeSkew` | What the final plan and conf show | Advice |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| `split` | The join is marked `skew=true` and a shuffle read says `skewed` | AQE already split the skewed partitions, so what remains is not join skew: look at GC, a slow host or an expensive key. When the tail is data (`evidence.cause` is `data`), the slow tasks still read far more data than the median task, and the advice is the key remedy. |
|
|
42
|
+
| `evenReads` | One join side shuffles next to nothing, so the task read is the other side's, and the largest task read is under twice the median | The slow tail is not partition-size skew: look at GC, a slow host or an expensive key. Never given when `evidence.cause` is `data`, which counts input and records as well as shuffle-read bytes. |
|
|
43
|
+
| `belowThreshold` | The largest task read is under `spark.sql.adaptive.skewJoin.skewedPartitionThresholdInBytes` (256 MB by default), which bounds every partition of both sides; or one side's read is at least twice the median but not far enough over it for `spark.sql.adaptive.skewJoin.skewedPartitionFactor` (5) | Lower the threshold or the factor for the query. |
|
|
44
|
+
| `planShape` | An aggregate, window or other operator sits between the join and its shuffle | AQE splits only a shuffle that feeds the join directly: salt the key. |
|
|
45
|
+
| `userRepartition` | The shuffle under the join is a `repartition` or `rebalance` in the job's code | AQE leaves a shuffle you asked for alone: drop it, or salt the key. |
|
|
46
|
+
| `joinType` | The join type does not let AQE split the skewed side: neither side of a full outer join, only the left side of a left outer, left semi or left anti join, only the right side of a right outer join | Join the hot key on its own and union the results, or salt the key. Swapping the sides does not help: the null-supplying or filtering table stays unsplittable. |
|
|
47
|
+
| `extraShuffle` | An aggregate, window or join above this join needs its partitioning, so a split would add a shuffle | Set `spark.sql.adaptive.forceOptimizeSkewedJoin` to `true` when that shuffle costs less than the tail (Spark 3.3 and later; before that, salt the key). |
|
|
48
|
+
| `notSplit` | Nothing above explains it | Salt the key. |
|
|
49
|
+
|
|
50
|
+
The stage's join is the one whose plan node ran in that stage; a plan whose
|
|
51
|
+
nodes carry no stage ids is read as one join only when the stage's shuffle read
|
|
52
|
+
matches what the join's two shuffles wrote. A task reads one partition of each
|
|
53
|
+
join side, so the stage's largest task read covers both sides. Spark judges each
|
|
54
|
+
side's partitions against that side's own median, which the log does not give, so
|
|
55
|
+
the finding calls the reads even or under the factor only when one side shuffles
|
|
56
|
+
at most 5% of the join's bytes; otherwise it can only show a partition is under
|
|
57
|
+
the absolute threshold (a task's read bounds every partition in it). The finding
|
|
58
|
+
does not say which side is skewed; for a join type that splits only one side it
|
|
59
|
+
names both possibilities. A run whose final plan is missing or ties no join to
|
|
60
|
+
the stage, or whose coalesced read could be many small partitions, keeps the
|
|
61
|
+
general advice.
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
A stage ran for 15 minutes or more and no slow host was flagged on it. It
|
|
4
4
|
can appear alongside other findings on the same stage. On a stage that reads a
|
|
5
|
-
shuffle, often a partition-count problem: raise
|
|
6
|
-
|
|
5
|
+
shuffle, often a partition-count problem: raise `spark.sql.shuffle.partitions`
|
|
6
|
+
when the stage ran that many tasks, lower
|
|
7
|
+
`spark.sql.adaptive.advisoryPartitionSizeInBytes` when AQE coalesced them, or
|
|
8
|
+
raise the stage's own `repartition(n)` or RDD parallelism; or check for a
|
|
7
9
|
large per-task data volume driving heavy shuffle and spill. On a stage that
|
|
8
10
|
reads input files and no shuffle, check input file sizes and lower
|
|
9
11
|
`spark.sql.files.maxPartitionBytes`. `evidence.reads` says which case
|
|
@@ -4,4 +4,9 @@ Speculative task attempts used a lot of executor time without confirming a
|
|
|
4
4
|
genuine straggler. Self-flags a confidence that scales with how far the
|
|
5
5
|
wasted time sits past the threshold. If task durations are just naturally
|
|
6
6
|
variable rather than genuine stragglers, tune
|
|
7
|
-
`spark.speculation.multiplier`/`spark.speculation.quantile`.
|
|
7
|
+
`spark.speculation.multiplier`/`spark.speculation.quantile`. The
|
|
8
|
+
recommendation names the run's effective values: Spark relaunches a task that
|
|
9
|
+
runs over the multiplier times the median once the quantile of the stage's
|
|
10
|
+
tasks has finished, which is 1.5x and 75% before Spark 4.0 and 3x and 90% from
|
|
11
|
+
4.0 unless the job sets them. A speculative-attempt `straggler` and a
|
|
12
|
+
`slowHost` finding word their speculation advice the same way.
|
|
@@ -4,7 +4,10 @@ Tasks are writing data out of memory, which slows execution. Two spill
|
|
|
4
4
|
patterns get flagged differently: skew spill, where a few heavy tasks spill
|
|
5
5
|
while most don't (rebalance partitioning), and volume spill, where most
|
|
6
6
|
tasks spill because the data genuinely exceeds available memory (add
|
|
7
|
-
partitions or executor memory).
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
partitions or executor memory). Partition-count advice is given only for a
|
|
8
|
+
stage that reads a shuffle; `evidence.reads` says what the stage reads
|
|
9
|
+
(`shuffle`, `input` or `other`). It names what sized the stage:
|
|
10
|
+
`spark.sql.shuffle.partitions` when the stage ran that many tasks,
|
|
11
|
+
`spark.sql.adaptive.advisoryPartitionSizeInBytes` when AQE coalesced them, and
|
|
12
|
+
the stage's own `repartition(n)` or RDD parallelism otherwise. Only flagged on stages that take at
|
|
10
13
|
least 0.5% of the run.
|
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
### `STRAG`: Straggler tasks {#strag}
|
|
2
2
|
|
|
3
|
-
A few tasks run much slower than the rest of their stage
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
A few tasks run much slower than the rest of their stage for a reason other
|
|
4
|
+
than reading more data (a data-driven tail is `SKEW`). `evidence.cause` names
|
|
5
|
+
what the slow tasks' extra time went to, taken in this order so no millisecond
|
|
6
|
+
counts twice: data volume, then GC time over the median task's, then shuffle
|
|
7
|
+
fetch wait over the median task's, then one host that holds most of the slow
|
|
8
|
+
tasks out of proportion to its share of the stage (`evidence.host`). What none of
|
|
9
|
+
them accounts for is `unexplained` (`unattributed` with no data volume to compare); an
|
|
10
|
+
`unexplained` tail whose slow tasks read at least twice the median task's data says so
|
|
11
|
+
rather than "no more data", and keeps the `SKEW` data advice when data is its largest share; `evidence.cpuPct` (the slow tasks' CPU time
|
|
12
|
+
over their run time) says whether those tasks mostly waited or were busy. With
|
|
13
|
+
no data volume to compare, what is left is `unattributed` when it is the largest share, as is a stage
|
|
14
|
+
with no tail attribution: the advice names no fix, only the slow tasks' input sizes, GC time and hosts to check.
|
|
15
|
+
A stage is flagged when more than 5% of its tasks run over 4x the median (2.5%
|
|
16
|
+
when the tail clears 0.5% of the run), a speculative task ran, or the `SKEW`
|
|
17
|
+
duration test holds on a tail that is not data. A stage whose tail is data but
|
|
18
|
+
which `SKEW` does not flag by duration keeps a `STRAG` finding with cause `data`. A finding only the `SKEW` duration
|
|
19
|
+
test admits reports that test's ratio (`metric` `P95/median` or `max/median`, `unit` `ratio`)
|
|
20
|
+
instead of a share.
|
|
21
|
+
Stages under 0.5% of the run are skipped unless the `SKEW` duration test holds.
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
### `TINY`: Tiny tasks {#tiny}
|
|
2
2
|
|
|
3
3
|
Many very short tasks add scheduling overhead out of proportion to the work
|
|
4
|
-
each one does. Repartition to fewer, larger tasks
|
|
5
|
-
(`evidence.reads` is `shuffle`)
|
|
6
|
-
|
|
4
|
+
each one does. Repartition to fewer, larger tasks. On a stage that reads a
|
|
5
|
+
shuffle (`evidence.reads` is `shuffle`) the advice names what sized it: lower
|
|
6
|
+
`spark.sql.shuffle.partitions` when the stage ran that many tasks; when AQE
|
|
7
|
+
coalesced them and still kept tiny ones, set
|
|
8
|
+
`spark.sql.adaptive.coalescePartitions.parallelismFirst` to `false` (AQE then
|
|
9
|
+
targets `spark.sql.adaptive.advisoryPartitionSizeInBytes` rather than
|
|
10
|
+
`defaultParallelism` tasks) and then raise the advisory size, which alone changes
|
|
11
|
+
nothing while `parallelismFirst` is on; otherwise lower the
|
|
12
|
+
`repartition(n)` or RDD partition count in the code. Only flagged on stages that take at least 0.5% of the run.
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
### `UTIL`: Low utilization {#util}
|
|
2
2
|
|
|
3
|
-
Allocated executors sit idle for a large share of the application run
|
|
4
|
-
|
|
3
|
+
Allocated executors sit idle for a large share of the application run: under
|
|
4
|
+
60% of the core time the run allocated (cores times the time each executor was
|
|
5
|
+
alive) ran a task. Consider a smaller cluster. With dynamic allocation off,
|
|
6
|
+
either lower `spark.executor.instances` or enable dynamic allocation; the two are
|
|
7
|
+
alternatives. With it on, lower `spark.dynamicAllocation.maxExecutors`, and
|
|
8
|
+
`spark.dynamicAllocation.minExecutors` too when the run sets it above 0.
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
// The effective Spark configuration of a run for the CLI's JSON output, so a caller can check
|
|
2
|
-
// that a --conf overlay took effect.
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
// prefix) is emitted.
|
|
2
|
+
// that a --conf overlay took effect. A withheld key is shown as present with no value, and no
|
|
3
|
+
// derivative of the value (no hash, length or prefix) is emitted. Patterns and output shape:
|
|
4
|
+
// docs-site/user-guide/getting-started/ci-and-automation.md, "Effective conf".
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
export const EFFECTIVE_CONF_SCHEMA_VERSION = 1;
|
|
@@ -50,16 +49,14 @@ export function compileJvmPattern(source ) {
|
|
|
50
49
|
// Sensitive query/parameter names in a URL-like value: signatures of pre-signed and SAS URLs.
|
|
51
50
|
const SIGNATURE_PARAMS = 'sig|signature|x-amz-signature|x-amz-credential|x-amz-security-token|x-goog-signature|x-goog-credential';
|
|
52
51
|
|
|
53
|
-
// A `name=value` credential parameter in any value (
|
|
54
|
-
//
|
|
55
|
-
// the tail of a longer name (`-Djavax.net.ssl.keyStorePassword=`).
|
|
52
|
+
// A `name=value` credential parameter in any value (JDBC or ODBC string, JVM option, query string),
|
|
53
|
+
// alone or as the tail of a longer name (`-Djavax.net.ssl.keyStorePassword=`).
|
|
56
54
|
const CREDENTIAL_PARAM = new RegExp(
|
|
57
55
|
'((?:^|[\\s;&,?:"\'(]|-D)(?:[\\w.-]*?(?:password|passwd|pwd|secret|token|api[_.-]?key|account[_.-]?key|access[_.-]?key|private[_.-]?key)|pass|sas|credential|'
|
|
58
56
|
+ `${SIGNATURE_PARAMS})\\s*=\\s*)("[^"]*"|'[^']*'|[^;&,\\s"']*)`, 'gi');
|
|
59
57
|
|
|
60
|
-
/** Strips credentials from a value: `name=value` credential parameters anywhere
|
|
61
|
-
*
|
|
62
|
-
* value that looks like a URL, userinfo (user:password@host) and the Oracle thin form
|
|
58
|
+
/** Strips credentials from a value: `name=value` credential parameters anywhere, and, in a value
|
|
59
|
+
* that looks like a URL, userinfo (user:password@host) and the Oracle thin form
|
|
63
60
|
* (jdbc:oracle:thin:user/password@host). */
|
|
64
61
|
export function stripUrlCredentials(value ) {
|
|
65
62
|
const urlLike = /^[a-z][a-z0-9+.-]*:/i.test(value) || value.includes('://');
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
import {
|
|
1
|
+
// Efficiency/wastage model: decomposes available compute-hours into driver-bound vs executor-bound
|
|
2
|
+
// waste, plus the zero-skew makespan floor.
|
|
3
|
+
import { stageWindows } from './wall-clock.js';
|
|
4
|
+
import { allocatedCoreMs, allocatedCoreMsWithin } from './allocation.js';
|
|
4
5
|
import { computePeakConcurrentCores } from './core-count.js';
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
export function computeEfficiencyModel({ app, stages, executorsAdded, executorsRemoved, runAggregates }
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
|
|
@@ -18,23 +19,25 @@ export function computeEfficiencyModel({ app, stages, executorsAdded, executorsR
|
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
{
|
|
21
|
-
// Capacity is the
|
|
22
|
-
// use, so the Unused core time tile matches the verdict's
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
|
|
22
|
+
// Capacity is the run's allocation (cores x time alive, metrics.allocation.coreHours), the one the
|
|
23
|
+
// utilization and idle-cores detectors use, so the Unused core time tile matches the verdict's
|
|
24
|
+
// idle figure. Peak concurrent cores times the whole run would count cores the run never held
|
|
25
|
+
// under dynamic allocation. Null without executor cores: no capacity, so no figure.
|
|
26
|
+
const input = { app, stages, executors: { added: executorsAdded, removed: executorsRemoved } };
|
|
27
|
+
const allocatedMs = allocatedCoreMs(input);
|
|
28
|
+
// Split by where the allocated cores were held, from the same alive intervals: inside the union
|
|
29
|
+
// of the stages' windows, or outside it (startup, gaps between stages, after the last stage).
|
|
30
|
+
// Executors that join after startup hold no cores there, so spreading the allocation evenly
|
|
31
|
+
// over the run would bill the driver for cores that never existed.
|
|
32
|
+
const allocatedActiveCoreMs = allocatedMs == null ? 0 : allocatedCoreMsWithin(input, stageWindows(stages)) ?? 0;
|
|
28
33
|
|
|
29
|
-
const availableComputeHours =
|
|
34
|
+
const availableComputeHours = (allocatedMs ?? 0) / 3600000;
|
|
30
35
|
|
|
31
|
-
// Driver-bound: cores
|
|
32
|
-
const
|
|
33
|
-
const driverWasteHours = totalCores * (driverIdleMs / 3600000);
|
|
36
|
+
// Driver-bound: cores held while no stage was active (startup, gaps, idle).
|
|
37
|
+
const driverWasteHours = Math.max(0, (allocatedMs ?? 0) - allocatedActiveCoreMs) / 3600000;
|
|
34
38
|
|
|
35
39
|
// Executor-bound: allocated capacity beyond busy cores during stagesActive. Tasks only run in
|
|
36
40
|
// active windows, so whole-run busyCoreMs already lives inside stagesActive.
|
|
37
|
-
const allocatedActiveCoreMs = totalCores * wc.stagesActive;
|
|
38
41
|
const busyCoreMs = runAggregates?.busyCoreMs ?? 0;
|
|
39
42
|
const executorWasteHours = Math.max(0, allocatedActiveCoreMs - busyCoreMs) / 3600000;
|
|
40
43
|
|
|
@@ -44,6 +47,11 @@ export function computeEfficiencyModel({ app, stages, executorsAdded, executorsR
|
|
|
44
47
|
let totalTaskMs = 0;
|
|
45
48
|
const perStage = runAggregates?.perStage ?? {};
|
|
46
49
|
for (const k of Object.keys(perStage)) totalTaskMs += perStage[k].totalTaskDurationSum;
|
|
50
|
+
// The floor is the least time the work takes on the widest the cluster ever was: peak concurrent
|
|
51
|
+
// cores (not the allocation), summing every addition (computeTotalCores) would count a replaced
|
|
52
|
+
// executor's cores alongside its replacement's. `app ?? {}`: callers tolerate a null app
|
|
53
|
+
// (malformed logs); `app!` would crash on app.resources.
|
|
54
|
+
const totalCores = computePeakConcurrentCores(app ?? {}, executorsAdded, executorsRemoved);
|
|
47
55
|
const floorZeroSkewMs = totalCores > 0 ? totalTaskMs / totalCores : 0;
|
|
48
56
|
|
|
49
57
|
let dominantWaste = null;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
//
|
|
2
|
-
// byte-flow shape. A stage can be both Transform and Load, so buckets overlap and need not sum to
|
|
1
|
+
// ETL-phase time attribution. Heuristic: classify each stage by byte-flow shape. A stage can be both Transform and Load, so buckets overlap and need not sum to
|
|
3
2
|
// wall-clock. Storage-format-aware attribution (Hudi/Delta/Iceberg) isn't portable, out of scope.
|
|
4
3
|
|
|
5
4
|
|