Skip to content

Storage introspection mirrored in compute#35863

Draft
frankmcsherry wants to merge 4 commits intoMaterializeInc:mainfrom
frankmcsherry:storage_introspection
Draft

Storage introspection mirrored in compute#35863
frankmcsherry wants to merge 4 commits intoMaterializeInc:mainfrom
frankmcsherry:storage_introspection

Conversation

@frankmcsherry
Copy link
Copy Markdown
Contributor

Events from storage's timely infra are captured and replayed in the compute logging dataflows, with identifiers bumped up by 2^48. They are pretty large at that point, but shouldn't collide with the compute identifiers. The nudged identifiers should include Both the timely operator ids, and also the dataflow identifiers (the lead coordinate of addresses).

Not much testing, other than observing the information flowing after creating an auction leaden source.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 3, 2026

Thanks for opening this PR! Here are a few tips to help make the review process smooth for everyone.

PR title guidelines

  • Use imperative mood: "Fix X" not "Fixed X" or "Fixes X"
  • Be specific: "Fix panic in catalog sync when controller restarts" not "Fix bug" or "Update catalog code"
  • Prefix with area if helpful: compute: , storage: , adapter: , sql:

Pre-merge checklist

  • The PR title is descriptive and will make sense in the git log.
  • This PR has adequate test coverage / QA involvement has been duly considered. (trigger-ci for additional test/nightly runs)
  • If this PR includes major user-facing behavior changes, I have pinged the relevant PM to schedule a changelog post.
  • This PR has an associated up-to-date design doc, is a design doc (template), or is sufficiently small to not require a design.
  • If this PR evolves an existing $T ⇔ Proto$T mapping (possibly in a backwards-incompatible way), then it is tagged with a T-proto label.
  • If this PR will require changes to cloud orchestration or tests, there is a companion cloud PR to account for those changes that is tagged with the release-blocker label (example).

@frankmcsherry frankmcsherry force-pushed the storage_introspection branch 3 times, most recently from 7baca63 to ec858b9 Compare April 3, 2026 18:19
Copy link
Copy Markdown
Member

@antiguru antiguru left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The approach checks out, I left some comments around the implementation.

One though I have is that we should feature-gate the functionality and have it turned off by default to prevent downstream consumers to make assumptions around the operator IDs, but that is contrary to the goal of introspection. So we should at least document it as a temporary behavior until we figure out our plans for cluster unification.

Comment thread src/storage/src/server.rs
// We use an approach similar to compute's logging: wrap the writer in
// a BatchLogger that translates Logger callbacks into Event pushes,
// then register the Logger with timely's log_register.
let interval_ms = 1000u128; // 1 second batching interval
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO, but low priority: Make the interval configurable.

Comment thread src/compute/src/server.rs
None
};
let mut active = self.activate_compute().unwrap();
active.storage_log_reader = storage_log_reader;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fragile as it only works if the current command is CrateInstance, but not in any other case. This is transient state, but it seems to be better to make it part of ComputeState to avoid unrelated parts of the code to depend on implementation details.

Comment thread src/compute/src/server.rs
Comment on lines +81 to +84
/// Per-worker readers for storage timely logging events.
// TODO: Consider using the timely config's `process` and `workers` fields to
// deterministically assign readers to workers by local index, rather than pop().
pub storage_log_readers: Arc<Mutex<Vec<StorageTimelyLogReader>>>,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The invariant in compute dataflows is that worker id $$x$$ processes introspection data of worker $$x$$. It might be that a more general invariant might be true, too, but we need to audit the implementation. Probably this is true: Each worker ID must send its updates to exactly one processing operator instance, for the lifetime of the worker.

Comment thread src/clusterd/src/lib.rs
Comment on lines +372 to +375
// Create per-worker bridges for forwarding storage timely logging events to compute.
let num_workers = storage_timely_config.workers;
let (storage_log_writers, storage_log_readers): (Vec<_>, Vec<_>) =
(0..num_workers).map(|_| arc_event_link()).unzip();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be feature-flagged. It means a new parameter to clusterd that is set by envd depending on a feature flag.

@frankmcsherry frankmcsherry force-pushed the storage_introspection branch from ec858b9 to e87ceb1 Compare April 14, 2026 12:43
@frankmcsherry frankmcsherry force-pushed the storage_introspection branch from e87ceb1 to 46e4c45 Compare April 14, 2026 20:20
Comment on lines +831 to +839
/// Offset added to storage operator/channel IDs to avoid collisions with compute IDs.
///
/// This is large enough that compute IDs (which start from 0 and grow) will never reach it,
/// but small enough to be representable as a `u64` with room for many storage operators.
const STORAGE_ID_OFFSET: usize = 1 << 48;

/// Remaps operator, channel, and address IDs in a `TimelyEvent` originating from a storage
/// timely instance so they don't collide with compute's IDs.
fn remap_timely_event_ids(event: &mut TimelyEvent) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question for console folks: How does the UI decide which things show up in the clickable introspection graph thing? If a bunch of storage operators show up in the introspection tables with these gigantic IDs, will that clutter the existing introspection UI for compute?
@leedqin

@ublubu ublubu force-pushed the storage_introspection branch from f0b20ae to 620cdc0 Compare April 16, 2026 22:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants