Repository navigation
Conversation
49d56ce to
340052e
Compare
QA LLM Review1. MEDIUM -- Skew verdicts can't fire on 2-worker replicas, which get "spread evenly" instead
DetailsWith two workers, This is the case the PR description motivates the drawer with: one worker pegged while A fix is to compare the busiest worker against the mean of the other workers. That gives 5× for |
340052e to
3c07311
Compare
QA LLM Review1. MEDIUM -- High-CPU verdict headline says "spread evenly" while its own body reports uneven work
This push turns uneven work under high replica CPU into a note on the DetailsThis branch is easy to reach. Take a 2-worker replica at one worker per core, with workers Before this push the headline was accurate, because an One fix is to drop "spread evenly across its workers" from the label when |
3c07311 to
e57a587
Compare
e57a587 to
5c304f9
Compare
QA LLM Review1. MEDIUM -- Finished ad-hoc queries keep resetting the verdict window, so replicas loaded by ad-hoc queries never get a verdict
Any reading where a worker's counter fell is marked DetailsA worker's counter sums only the dataflows that are still running. A slow-path peek runs in a transient dataflow, which I ran synthetic counters through the PR's
|
1e047f7 to
87f9e42
Compare
|
Both QA reviews are addressed in 87f9e42:
|
QA LLM Review1. MEDIUM -- The saturated-worker verdict names a busiest process even when the processes are even
The new process sentence names whichever process has the highest mean CPU, with no evenness threshold. A process with many workers barely moves when one of them saturates, so on large multi-process replicas the sentence often credits another process with "the most CPU" by about a point. It then links to the processes drawer, which applies Details
Take 2 processes of 62 workers, with w3 at 100% and every other worker at 20%. w3 adds (1 − 0.2)/62 ≈ 1.3 points to process 0, so process 0 reads about 21% and process 1 about 20%, a ratio of 1.06. Any larger difference between the processes, for example in work outside dataflows, decides which one comes out ahead. If process 1 wins, the verdict for w3 says "Process 1 used the most CPU, 21% against 20% for the other 1." That points away from the worker the verdict is about. "CPU and memory by process" then opens a drawer that says "CPU and memory are spread evenly across the processes." If process 0 wins, "Its process, process 0, used the most CPU" claims a lead the processes drawer doesn't count. The tests only use 61 vs 34 and 70 vs 40, both well past 1.25. One fix is to share |
87f9e42 to
80fef06
Compare
|
Busiest process named when the processes are even is addressed in 80fef06. |
80fef06 to
2fcf71c
Compare
QA LLM Review1. MEDIUM -- The busiest worker's breakdown says "about as much as the other workers" when it spent far less
DetailsThis needs one object hot on the busiest worker and another hot on a different worker, for example two keyed objects whose hot keys hash to different workers, or a single-key reduce. Take 4 workers,
The other workers averaged 7s on One fix is to treat the band from 1/ |
2fcf71c to
bbbd2b7
Compare
|
Breakdown calling a much smaller share even is addressed in bbbd2b7. Even is now the band from 1/1.25 to 1.25. Below it, the line says "less than the other workers" and gives the multiple. When the object is skewed onto another worker, it also names that worker, so it agrees with the table's hottest-worker cell. Your |
QA LLM Review1. MEDIUM -- The new "less than the other workers" note is always clipped, so "hottest on wN" never shows
The string this push adds for objects below the even band is wider than the breakdown's fixed 280px note column ( DetailsI rendered the notes in Chromium using the console's Inter font and the
Both pre-existing strings fit: "20s, 10.0× the other workers' average" and "3s, about as much as the other workers" each measure 280px or less. The new test at |
bbbd2b7 to
0e88dc6
Compare
|
Clipped "less than the other workers" note is addressed in 0e88dc6. The note is shorter and matches the table's wording: "3s · 0.4× the others, hottest w2". It also wraps to a second line before it truncates, and the full note shows on hover, so a long duration or a three-digit worker id still shows the hottest worker. |
0e88dc6 to
f155158
Compare
… cluster page Adds a Workers button to the redesigned cluster page's CPU chart. It opens a drawer that reads the replica's per-worker scheduling counters over one WebSocket session while open, and leads with a finding in the CPU troubleshooting guide's terms: a saturated or uneven worker, every worker busy, high CPU inside or outside running dataflows, idle, or balanced. Below it are the replica's CPU against its time running dataflows, the busiest and average worker over time, the busiest workers, and a table of objects with one bar per worker against an even share.
f155158 to
731d7c2
Compare
Motivation
Sixth PR in the cluster details redesign stack, on top of #39607. The CPU chart shows a replica's CPU as a share of its allocation, averaged over its workers. The CPU troubleshooting guide points out that a replica whose work sits on one worker can peg a core while reporting a modest
cpu_percent, and that high CPU with evenly spread work points elsewhere: an expensive object, ad-hoc queries, or an undersized cluster. The Console had no way to tell these apart.This adds a Workers button to the CPU chart, next to #39508's Processes. It opens a drawer that reads the replica's per-worker scheduling counters live and leads with a finding in the guide's terms.
Description
What it reads. The drawer reads only while open.
mz_scheduling_elapsed_per_worker(list_length(address) = 1), because a root's time includes its children.mz_compute_exports. Transient (t) exports pool into one "Ad-hoc queries and subscribes" row.clusterandcluster_replicaon the session.WebsocketQueryClient), held only while reading. An HTTP read would open a session each time, and a session start costsmz_catalog_serverabout 35 ms of CPU.statement_timeoutof 10s;useReplicaProcessSamples), an index lookup onreplica_idover the last 20 minutes. The card's series can't be reused: past a 1h window they are per-bucket peaks, and past 24h they are polled.What it shows.
A verdict over the last 5 minutes:
The busiest worker is compared with the others' average, not with an average that includes it, which can't reach 2× on two workers. Only a saturated worker outranks high CPU. Uneven work under high CPU becomes a note on that verdict. On a multi-process replica, a skewed worker's verdict also says whether its process used the most CPU over the same window, by the Processes drawer's rule (1.25× the others). Below that, it says the processes were even and the skew is between workers.
The skew verdicts name the object that took most of the busiest worker's time. They also give a copyable
EXPLAIN ANALYZE CPU WITH SKEWfor that object, pinned to the replica. Until 30s of readings exist, the drawer shows a first look from the lifetime counters instead.Processes and workers link to each other. On a multi-process replica, the Workers drawer links to the Processes drawer and back, opening on the same replica. Both drawers draw the replica's line and its busiest process or worker in the replica's color, and the rest muted.
Two charts on one clock axis:
The busiest workers. The busiest worker always shows, with what it spent its dataflow time on: its top three objects, each with its share of the worker's time, the time itself, and how that compares with the other workers' average on the same object. When work is skewed, the next four workers follow, each with its top object. The rest are one range.
Where the CPU went: a UniversalTable with one row per object, measured since the drawer opened or since each dataflow started. Each row has:
Since the drawer opened, the share is % of the replica's CPU allocation, the CPU chart's unit. Objects, an "Other dataflows" footer and a line for work outside running dataflows add up to the replica's CPU. Over each dataflow's lifetime there is no common span, so the share is of all dataflow CPU instead. Objects under 1% of the dataflow CPU aren't flagged as skewed. Header tooltips define each column.
Counter semantics. A dataflow's time leaves the counters when it shuts down (
handle_shutdowninsrc/compute/src/logging/timely.rs). So the counters fall when a dataflow is dropped, an ad-hoc query's dataflow finishes, or the replica restarts.Supporting changes.
useObjectLinkis shared with the memory by object card.TimeAxistakes atickFormat.SubscribeCollectiongainsgetRows.workers.SessionVariablesincludesstatement_timeout.standsOut,EVEN_RATIO) moves toprocessReadingsModel.ts, shared with the worker verdict.buildExtendedRequestQueryis exported.The drawer ships with the redesign, so it is behind the same UI preview flag and off in self-managed.
Cost.
mz_catalog_server: one session per stretch of reading, and one metrics SUBSCRIBE per open drawer.The read time on a large replica isn't measured yet. The backoff and the 10-minute cap bound it.
Verification
workerCpuModel.test.ts:workerCpuSampler.test.ts:WebsocketQueryClient.test.ts:ResourceUsage.test.tsx: the Workers and Processes drawers switch to each other on the same replica.BusiestWorkers.test.tsx: the busiest worker's breakdown shows even when work is balanced, with each object's time against the other workers'. An object the busiest worker spent less on reads as a multiple below 1×, naming the object's hottest worker when the object is skewed onto another one, for example "3s · 0.4× the others, hottest w2".ObjectCpuTable.test.tsx:WorkerCpuVerdict.test.tsx:EXPLAIN ANALYZE CPU WITH SKEW, pinned to the replica;🤖 Generated with Claude Code