HDDS-15071. [SCM] Add configuration and global EC reconstruction limit - #10122
HDDS-15071. [SCM] Add configuration and global EC reconstruction limit#10122jojochuang wants to merge 8 commits into
Conversation
|
Pushed a small change to disable the global reconstruction threshold, to keep the behavior the same. |
smengcl
left a comment
There was a problem hiding this comment.
Thanks @jojochuang . I found two more issues
There was a problem hiding this comment.
Pull request overview
Adds a cluster-wide throttling mechanism for EC reconstruction in SCM’s ReplicationManager, backed by new configuration knobs. This helps prevent excessive aggregate EC reconstruction work when the feature is enabled, while keeping default behavior unchanged (limit disabled by default).
Changes:
- Introduces new
ReplicationManagerConfigurationproperties for EC decommission reconstruction enablement, load factor, and a global EC reconstruction limit. - Tracks inflight EC reconstruction commands via an atomic counter and per-command fragment accounting, and enforces the global limit when sending reconstruction commands.
- Adds/extends unit tests covering default-disabled behavior, limit accounting, and limit-triggered rejection paths.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/ReplicationManager.java | Adds global EC reconstruction limit config + inflight tracking and enforcement in reconstruction command sending / completion handling. |
| hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestReplicationManager.java | Adds tests for default behavior, inflight reconstruction tracking, rejection at limit, and counter reset on leader transitions. |
| hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestUnderReplicatedProcessor.java | Adds a processor test related to reconstruction-limit behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.
Comments suppressed due to low confidence (1)
hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/ReplicationManager.java:601
- The PR description says UnhealthyReplicationProcessor will check the global reconstruction limit before dequeuing work; however, the processors only check the replication inflight limit and there is no reconstruction-limit check in UnhealthyReplicationProcessor/UnderReplicatedProcessor. As implemented, the limit is enforced only when sending the command (by throwing CommandTargetOverloadedException), which can still dequeue/process/requeue items and create churn. Please either implement the dequeue-time check or update the PR description/testing notes accordingly.
if (isReconstructionLimitReached()) {
metrics.incrECReconstructionCmdsDeferredTotal();
throw new CommandTargetOverloadedException(
"Global reconstruction limit (" + getReconstructionInFlightLimit()
+ ") reached for container " + containerInfo.getContainerID());
}
List<DatanodeDetails> targets = command.getTargetDatanodes();
List<Pair<Integer, DatanodeDetails>> targetWithCmds =
getAvailableDatanodesForReplication(targets);
if (targetWithCmds.isEmpty()) {
metrics.incrECReconstructionCmdsDeferredTotal();
throw new CommandTargetOverloadedException("No target with capacity " +
"available for reconstruction of " + containerInfo.getContainerID());
}
DatanodeDetails target = selectAndOptionallyExcludeDatanode(
rmConf.getReconstructionCommandWeight(), targetWithCmds);
sendDatanodeCommand(command, containerInfo, target);
}
Set hdds.scm.replication.reconstruction.global.limit default to 0 so cluster-wide EC reconstruction throttling is opt-in and default behavior matches pre-PR Ozone. Co-authored-by: Cursor <cursoragent@cursor.com> Change-Id: I6a0915cf8b181a1a98b08a4f3ede071e4d460e88
… reset. Move global reconstruction throttling from the under-replicated processor loop to sendThrottledReconstructionCommand so 1-1 replication continues when the cap is reached. Clear reconstruction counters on leader transition when pending ops are cleared. Co-authored-by: Cursor <cursoragent@cursor.com> Change-Id: I881fee0c3ea3c2e350b8fbb95321985569bef636
Skip reconstruction counter decrements when the command is no longer tracked after notifyStatusChanged clear, and floor decrements at zero. Co-authored-by: Cursor <cursoragent@cursor.com> Change-Id: I1530348aa2b09c232ad0410468d90cf098d8d0a3
…and tests. Validate reconstruction config bounds, remove a misleading processor test stub, and reuse ECUnderReplicationHandler.integers2ByteString in unit tests. Co-authored-by: Cursor <cursoragent@cursor.com> Change-Id: I55216c0c4c0af92e003486e04dd9bc0c42a8dc5c
…espace. Reserve the global reconstruction limit with a CAS before sending commands, release on send failure, and add a concurrent unit test. Clean up trailing whitespace in reconstruction limit tests. Co-authored-by: Cursor <cursoragent@cursor.com> Change-Id: If8c0e4613209b8fb381271c7dab1733eac0e5bde
…ress review nits. Always reserve reconstruction slots via CAS even when the global limit is disabled so inflightReconstructionCount stays accurate for observability and runtime reconfiguration. Extend the default-disabled test, wrap long test lines, rename the concurrent-test command ID variable, and shut down the executor in a finally block. Co-authored-by: Cursor <cursoragent@cursor.com> Change-Id: I92d085a415582483d9baa3a8d42b1a956b42e485
|
@smengcl Thanks for the July 7 review. Both items are addressed in subsequent commits:
Latest push (
All review threads are resolved. Could you take another look when you have a chance? |
…g ops. Register reconstructionCommandIdToPendingFragmentCount immediately after reserving a slot so opCompleted can always release it. Remove the map put from adjustPendingOpsAndMetrics and clear the entry on send failure. Co-authored-by: Cursor <cursoragent@cursor.com> Change-Id: I454d0a6d8510a200d93a26118cda8990416d149f
|
This PR has been marked as stale due to 21 days of inactivity. Please comment or remove the stale label to keep it open. Otherwise, it will be automatically closed in 7 days. |
|
Thank you for your contribution. This PR is being closed due to inactivity. Please contact a maintainer if you would like to reopen it. |
|
Rebased onto latest master and force-pushed. Unit tests for global reconstruction limit pass locally: @smengcl Could you take another look when you have a chance? This is the foundation for HDDS-15072 (dynamic EC decommission reconstruction switch). |
|
Addressed @adoroszlai review in 6aa5640 (also on #11054):
Review threads resolved. |
What changes were proposed in this pull request?
HDDS-15071. [SCM] Add configuration and global reconstruction limit
Please describe your PR in detail:
hdds.scm.replication.decommission.ec.reconstruction.enabled
hdds.scm.replication.decommission.ec.reconstruction.load.factor (default 0.9)
hdds.scm.replication.reconstruction.global.limit (default 0, disabled)
sendThrottledReconstructionCommand()viatryReserveReconstructionSlot()so 1-1 replication continues when the reconstruction cap is reached.Default behavior is unchanged.
hdds.scm.replication.reconstruction.global.limitdefaults to0, which disables cluster-wide reconstruction limit checking (same pattern ashdds.scm.replication.inflight.limit.factor). Set a positive value to opt in to throttling; a value of50is recommended when enabling HDDS-15072 EC decommission reconstruction.The inflight reconstruction counter is always maintained for observability, even when the limit is disabled. Limit enforcement only applies when
reconstruction.global.limit > 0.What is the link to the Apache JIRA
https://issues.apache.org/jira/browse/HDDS-15071
How was this patch tested?
Unit tests:
TestReplicationManager.testReconstructionGlobalLimitDisabledByDefault()TestReplicationManager.testInflightReconstructionLimit()TestReplicationManager.testSendReconstructionCommandRejectedWhenGlobalLimitReached()TestReplicationManager.testReconstructionGlobalLimitEnforcedConcurrently()TestReplicationManager.testNotifyStatusChangedClearsReconstructionCounters()TestReplicationManager.testInflightReconstructionCountNotNegativeAfterFailoverClear()TestUnderReplicatedProcessor.testMessageNotProcessedIfGlobalLimitReached()(replication inflight limit)