Skip to content

[fix] Guarantee even node distribution for simple storage units - #144

Merged
0oshowero0 merged 2 commits into
Ascend:mainfrom
OutstanderWang:feat_round_robin_storage_units
Aug 3, 2026
Merged

[fix] Guarantee even node distribution for simple storage units#144
0oshowero0 merged 2 commits into
Ascend:mainfrom
OutstanderWang:feat_round_robin_storage_units

Conversation

@OutstanderWang

Copy link
Copy Markdown
Contributor

Motivation

SimpleStorage fans experience data out across num_data_storage_units Ray actors. For memory and network bandwidth to be balanced across the cluster, those units must be spread evenly over the available Ray nodes — otherwise a subset of nodes absorbs a disproportionate share of the storage load and becomes a hotspot. The current placement relies on a placement group with the SPREAD strategy, which does not actually guarantee this.

What was wrong

  1. SPREAD is best-effort, not a guarantee. initialize_simple_storage created a placement group via get_placement_group(num_data_storage_units), which builds one CPU bundle per unit with ray.util.placement_group(..., strategy="SPREAD"). Ray's SPREAD is explicitly documented as best-effort: when scheduling is constrained (resource pressure, timing, node availability) it silently falls back to packing multiple bundles — and therefore multiple storage units — onto the same node.
  2. No control over the units-vs-nodes ratio. SPREAD gives no even-split guarantee regardless of how num_data_storage_units compares to the node count, and its strict sibling STRICT_SPREAD isn't a usable alternative here because it fails outright once num_actors > num_nodes (the common case, since the recommended setting is ≥ 2× nodes). The result: uneven memory/bandwidth distribution and node hotspots that the "spread" was supposed to prevent.

What this changes

  1. Explicit round-robin placement via NodeAffinitySchedulingStrategy. New helper get_node_round_robin_scheduling_strategies(num_actors) in transfer_queue/utils/common.py enumerates all currently alive Ray nodes (ray.nodes() filtered by Alive, sorted by NodeID for deterministic ordering) and returns one strategy per actor, assigning actor i to alive_node_ids[i % len(alive_node_ids)] with soft=False (hard affinity). This guarantees each node receives floor(num_actors / num_nodes) or ceil(num_actors / num_nodes) units — an even split by construction, for any ratio of units to nodes.
  2. initialize_simple_storage now schedules per-unit. It calls get_node_round_robin_scheduling_strategies(num_data_storage_units) and passes scheduling_strategy=strategies[rank] to each SimpleStorageUnit.options(...), replacing the previous placement_group + placement_group_bundle_index wiring. The creation log line now records the target node_id for each unit, making the distribution observable.
  3. Fail-fast on an empty cluster. If no alive nodes are found, the helper raises RuntimeError("No alive Ray nodes found. Is Ray initialized?") instead of proceeding with an undefined placement.
  4. Config doc clarified. config.yaml documents that units are round-robin scheduled across all alive nodes for an even per-node split, and keeps the "≥ 2× nodes" recommendation (now framed as "so each node hosts multiple units").

Tests

Verified on a Ray cluster that num_data_storage_units units are distributed evenly across alive nodes for both units ≤ nodes and units > nodes cases, with each unit's target node confirmed via the new creation log line. Existing SimpleStorage unit and e2e lifecycle tests continue to pass.

Placement group SPREAD scheduling is best-effort and can pack multiple
storage units onto the same node; switch to explicit round-robin
NodeAffinitySchedulingStrategy so units are evenly split across all
alive Ray nodes regardless of how num_data_storage_units compares to
the node count.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ascend-robot

Copy link
Copy Markdown

CLA Signature Guide

@OutstanderWang , thanks for your pull request.

The following commit(s) are not associated with a signed Contributor License Agreement (CLA).

Commit Reason
[3b67867 [fix] Guarantee even node distr...](3b67867) the email used in the commit is not linked to a signed CLA!
please verify that it matches the email you used when signing the CLA.

To sign CLA, click here.

To check if your email is configured correctly, refer to the FAQs.

Once you've signed the CLA or updating your email, please comment /check-cla to revalidate CLA status.

@OutstanderWang

Copy link
Copy Markdown
Contributor Author

/check-cla

@ascend-robot

Copy link
Copy Markdown

CLA Signature Guide

@OutstanderWang , thanks for your pull request.

The following commit(s) are not associated with a signed Contributor License Agreement (CLA).

Commit Reason
[3b67867 [fix] Guarantee even node distr...](3b67867) the email used in the commit is not linked to a signed CLA!
please verify that it matches the email you used when signing the CLA.

To sign CLA, click here.

To check if your email is configured correctly, refer to the FAQs.

Once you've signed the CLA or updating your email, please comment /check-cla to revalidate CLA status.

@ascend-robot

Copy link
Copy Markdown

CLA Signature Pass

OutstanderWang, thanks for your pull request. All authors of the commits have signed the CLA. 👍

total_storage_size: null
# Number of distributed storage units.
# Recommended: >= 2 x number of nodes for load balancing.
# Number of distributed storage units. Units are round-robin scheduled across all

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It is done.

@ascend-robot

Copy link
Copy Markdown

CLA Signature Guide

@OutstanderWang , thanks for your pull request.

The following commit(s) are not associated with a signed Contributor License Agreement (CLA).

Commit Reason
[0eb642c [fix] Sync perftest config comm...](0eb642c) the email used in the commit is not linked to a signed CLA!
please verify that it matches the email you used when signing the CLA.

To sign CLA, click here.

To check if your email is configured correctly, refer to the FAQs.

Once you've signed the CLA or updating your email, please comment /check-cla to revalidate CLA status.

Mirror the num_data_storage_units documentation from
transfer_queue/config.yaml so the perf-test config reflects the
round-robin node scheduling behavior.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@OutstanderWang
OutstanderWang force-pushed the feat_round_robin_storage_units branch from 0eb642c to 240c9e2 Compare July 31, 2026 14:43
@ascend-robot

Copy link
Copy Markdown

CLA Signature Guide

@OutstanderWang , thanks for your pull request.

The following commit(s) are not associated with a signed Contributor License Agreement (CLA).

Commit Reason
[240c9e2 [fix] Sync perftest config comm...](240c9e2) the email used in the commit is not linked to a signed CLA!
please verify that it matches the email you used when signing the CLA.

To sign CLA, click here.

To check if your email is configured correctly, refer to the FAQs.

Once you've signed the CLA or updating your email, please comment /check-cla to revalidate CLA status.

@0oshowero0
0oshowero0 merged commit 796b68c into Ascend:main Aug 3, 2026
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants