Skip to content

router: add multi-channel distribution backend for N-node AF2 writes#5

Open
riaarora-boop wants to merge 1 commit into
feat/posix-af2-mpu-handlerfrom
feat/router-multi-channel
Open

router: add multi-channel distribution backend for N-node AF2 writes#5
riaarora-boop wants to merge 1 commit into
feat/posix-af2-mpu-handlerfrom
feat/router-multi-channel

Conversation

@riaarora-boop

Copy link
Copy Markdown

Summary:

Adds Router, a backend.Backend implementation that distributes S3 object writes across N AF2 channels (one per node).

Placement: WAL segment names (24 hex chars) are placed by their low-64-bit ordinal mod N so consecutive segments round-robin across slots. Everything else uses fnv1a(bucket+"/"+key) mod N. Placement is deterministic — reads recompute the same slot with no per-object location map.

Writes: owner node writes go through the local backend under a per-channel weight-1 semaphore (P=1 — only one byte-write in flight into a channel at any moment, keeping it out of the wedge). Non-owner requests are forwarded via an s3proxy leg with an optional deadline so a partitioned peer fails fast.

Bucket ops: CreateBucket / DeleteBucket fan out cluster-wide so one create/delete from any node propagates to all.

Note — v1 limitation (will be updated with JFL control plane, §14 of design doc): currently uses a single static OwnerMap loaded at startup. Will be replaced with per-grant routing ((access_key_id, bucket)OtterChannelGrant) once the JFL OtterControl Thrift push + CRDB persistence is implemented.

Test Plan:

  • go test ./backend/router/... passes (placement unit tests: WAL ordinal round-robin, fnv fallback, determinism)
  • Validated end-to-end on a 3-node cluster: 30 concurrent uploads fanned out evenly across 3 channels, read back byte-clean from a different entry node

JIRA Issues:

CDM-557246 (subtask of CDM-557238)

Revert Plan:

Revert this PR. The Router is only used by the otter subcommand (PR 6); reverting either PR is sufficient to remove it from the binary.

Adds Router, a backend.Backend implementation that distributes S3 object
writes across N AF2 channels (one per node) using a stable placement hash:
WAL segment names (24 hex chars) are placed by their low-64-bit ordinal mod N
so consecutive segments round-robin across slots; everything else uses
fnv1a(bucket+"/"+key) mod N. Placement is deterministic — reads recompute
the same slot with no location map.

Writes to the owning node go through the local backend under a per-channel
weight-1 semaphore (P=1). Writes to non-owning nodes are forwarded via an
s3proxy leg with an optional deadline so a partitioned peer fails fast.
CreateBucket/DeleteBucket are fanned out cluster-wide.

Includes OwnerMap (shared JSON config, one selfIdx difference per node) and
placement unit tests.

Jira: CDM-557246
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
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.

1 participant