feat: Free Volume Deadband (M) for EC shard placement (#12029)

* feat: Free Volume Deadband (M) for EC Place nodes and racks

|ΔfreeSlots| ≤ M is a tie; remainder is liveShards. M=0 stays strict
freeSlots. M is free volume slots (× dataShards). pickNodeInRackEligible
and pickRackEligible share the rule. Worker plugin config
free_slots_deadband, default 0. Not on the write path.

* fix: anchor EC freeSlots deadband on class maxFree

Pairwise |Δfree|≤M vs the current winner is not transitive: 120→110→100
at M=10 slots picked 100. After evenness, rank by maxFree, keep
|free-maxFree|≤M, then min liveShards. Shared by node and rack. M=0 is
still only maxFree then live.

* worker: add free_slots_deadband to ErasureCodingTaskConfig

* erasure_coding: persist free_slots_deadband through TaskPolicy

ApplyMaintenanceConfigFromToml accepted the key but the admin save path
round-trips config through ToTaskPolicy, so the value was dropped on
reload; serialize it like the other EC settings.

* erasure_coding: bound free_slots_deadband at its declared maximum

The TOML loader and the plugin worker config only clamped negatives, so
a value above the spec's 100000 could reach the int32 TaskPolicy field
and wrap; cap at 100000 on both entry paths and declare MaxValue on the
plugin field.

* erasure_coding: document free_slots_deadband in scaffold admin.toml

---------

Co-authored-by: Chepurnov Simon <195125934+CHEPURNOV-S-S@users.noreply.github.com>
Co-authored-by: user.email <chrislusf@users.noreply.github.com>
This commit is contained in:
authored and GitHub committed 2026-10-24 07:06:46 -07:00
1 parent 52e05ccda4
commit 18f9d9a0b6
12 files changed
+551 -72

No files matched your search

+3
View File
@@ -66,6 +66,9 @@
# replica_placement = ""
# fail planning when the placement constraints cannot be met instead of relaxing them
# strict_placement = false
# volume-slot deadband for shard placement: nodes whose free volume slots differ by at
# most this much tie and fewer live shards wins; applied times data shards (0 = strict)
# free_slots_deadband = 0
# max retry attempts for a failed erasure coding job
# retry_limit = 1
# seconds to wait between retry attempts