HDDS-14926. Allow QUASI_CLOSED containers in DiskBalancer with improved debug logs for containers#10022
Conversation
|
@ChenSammi Please review the PR. |
I think we should remove the config and have all containers that would otherwise be eligible for replication between datanodes (non-open containers) eligible for disk balancing. Since they can be safely copied between datanodes there is no reason to exclude them when copying between disks as well. |
Thanks for the suggestion — the idea that anything safe to replicate between datanodes should be safe to move between disks on the same node is reasonable. |
|
#9964 largely applies to over-replicated containers. It is required because the balancer will create more over-replication as it runs if deletes are not processed. The disk balancer does not create over-replication because a datanode can only load one container at a time, and furthermore the datanodes themselves are not aware of whether a container is over-replicated. The only overlap between the two is handling quasi-closed containers. For quasi-closed containers I don't see a reason for either process to exclude them, and I'm not sure #9964 made the right call here. I can't find any documented reason why quasi-closed containers should be excluded from either process, only jira descriptions saying it will be done with no supporting reasoning. @siddhantsangwan @sarvekshayr @sadanand48 what do you think? |
Same here, Theoretically I think we could skip excluding quasi-closed containers however my guess based on some discussions is that we didn't want cases where same container is acted upon by both balancer and RM, Say balancer schedules a move for a quasi-closed container and RM sends a command to close the container at the same time. While balancer moves the QC container, If we don't do the bcsId check it can increase the containers that have lower bcsId by the balancer selecting it and delete not processing in the system. Still should not be a major issue. I think we just wanted to play safe by only moving immutable container state. If we have tested these scenarios I believe we can include these in the default criteria The origin of the check is in https://github.com/apache/ozone/pull/2441/changes#diff-b0ac1e8086a1da3247489a1a6ad742996052aa17a46544f1f6aaf24bfd92a762R76-R82 @siddhantsangwan please correct me if I am wrong |
@sadanand48 What I know is that BCSID increases when new block commits go through the container pipeline (Ratis log index on PutBlock). Balancers relocate bytes and metadata; they should preserve BCSID. I think we allow quasi closed containers to be moved without any config unless we want to play safe. |
Right my comment above does not state that it alters bcsID , but it can increase the replicas with lower bcsId by replicating them (given the delete fails in the move). As I stated above, if all such scenarios are tested thoroughly , IMO we can bring the quasi-closed containers in the default criteria for selection |
|
Approved? |
There was a problem hiding this comment.
Pull request overview
This PR extends the datanode DiskBalancer to move not only CLOSED containers but also additional lifecycle states (notably QUASI_CLOSED) via a new configurable “movable container states” setting, and improves debuggability by adding detailed skip-reason debug logs during container selection. It also wires the new setting end-to-end (CLI → protobuf → persisted YAML → service runtime) and updates docs/tests accordingly.
Changes:
- Add a new config property to control which container lifecycle states are eligible for disk balancing, and propagate it through DiskBalancer service state/reporting.
- Update container selection to filter by the configured movable states and add granular debug logs for skip conditions.
- Extend CLI/status output, protobuf, YAML persistence, and tests/docs to include the new
containerStatessetting.
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/scm/node/TestDiskBalancerPolicyPerformance.java | Updates performance tests to pass the new movable-states parameter. |
| hadoop-ozone/cli-admin/src/test/java/org/apache/hadoop/hdds/scm/cli/datanode/TestDiskBalancerSubCommands.java | Adds CLI test for invalid container state reporting during update. |
| hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/datanode/DiskBalancerUpdateSubcommand.java | Adds --container-states option and includes it in update config proto/output. |
| hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/datanode/DiskBalancerStatusSubcommand.java | Displays configured container states in status output and JSON. |
| hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/datanode/DiskBalancerStartSubcommand.java | Adds --container-states option to start; wires to config proto/output. |
| hadoop-hdds/interface-client/src/main/proto/hdds.proto | Adds containerStates field to DiskBalancerConfigurationProto. |
| hadoop-hdds/docs/content/feature/DiskBalancer.md | Documents the new hdds.datanode.disk.balancer.container.states setting. |
| hadoop-hdds/docs/content/feature/DiskBalancer.zh.md | Chinese documentation update for the new container-states config. |
| hadoop-hdds/docs/content/design/diskbalancer.md | Updates design doc to reflect state-driven movability (CLOSED/QUASI_CLOSED default). |
| hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/diskbalancer/policy/ContainerChoosingPolicy.java | Extends the policy interface to accept movable container states. |
| hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/diskbalancer/policy/DefaultContainerChoosingPolicy.java | Implements state filtering + detailed debug skip logs; updates method signature. |
| hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/diskbalancer/DiskBalancerConfiguration.java | Introduces container.states config, default states, parsing/validation helper. |
| hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/diskbalancer/DiskBalancerInfo.java | Persists containerStates as part of DiskBalancerInfo equality/state. |
| hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/diskbalancer/DiskBalancerYaml.java | Adds containerStates to YAML read/write with backward-compatible defaulting. |
| hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/diskbalancer/DiskBalancerService.java | Tracks/persists container states and enforces movability both at choose-time and move-time. |
| hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/diskbalancer/DiskBalancerProtocolServer.java | Returns containerStates in the disk balancer info RPC/status proto. |
| hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/diskbalancer/TestDiskBalancerYaml.java | Parameterizes YAML round-trip tests to include container states. |
| hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/diskbalancer/TestDiskBalancerTask.java | Removes prior “test mode” gating for QUASI_CLOSED; aligns tests with new config-based eligibility. |
| hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/diskbalancer/TestDiskBalancerService.java | Adds unit tests for parsing/validation of movable container states. |
| hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/diskbalancer/TestDiskBalancerProtocolServer.java | Updates protocol server tests to verify containerStates propagation. |
| hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/diskbalancer/TestDefaultContainerChoosingPolicy.java | Adds tests validating QUASI_CLOSED eligibility based on configured state list. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| * | ||
| * @return unmodifiable non-empty set | ||
| */ | ||
| public Set<State> getMovableContainerStates() { |
There was a problem hiding this comment.
Please make it private, call it from setContainerStates. We should verify the new setting value in setContainerStates.
There was a problem hiding this comment.
Done verifying the new setting value in setContainerStates.
In order to make getMovableContainerStates private and only use it from setContainerStates. That only works if every time the config is loaded, setContainerStates runs.
It doesn’t: for OzoneConfiguration.getObject(DiskBalancerConfiguration.class), the framework binds hdds.datanode.disk.balancer.container.states by writing the containerStates field directly and setContainerStates is not invoked.
So code like DefaultContainerChoosingPolicy, DiskBalancerService, tests, etc. still need a public way to get Set from that object. Today that’s getMovableContainerStates(), which parses the injected string on read.
If we made that method private and only called it from setContainerStates, those getObject(...) instances would never get a parsed set.
There was a problem hiding this comment.
Can we do the parseMovableContainerStates in the constructor?
There was a problem hiding this comment.
As far as I understand the contsructor cannot validate because @Config fields are injected via reflection after the constructor returns (field.set(obj, value) in injectConfiguration). The constructor only ever sees the default value of the field not the configured value. So we cannot move parseMovableContainerStates in constructor.
|
@ChenSammi Please take a look, I have updated the patch. |
|
The last patch LGTM, +1. Thanks @Gargi-jais11 , and @errose28 @sadanand48 for the discussion. |
What changes were proposed in this pull request?
Currently DiskBalancer only supports CLOSED containers to be moved but if user wants to also move quasi closed containers then we should support that as well.
1st Improvement:
Below scenario can happen in real, so Disk balancer can only attempt those 10 CLOSED containers. Even if it moves all 10 successfully, disk A might drop only from 90% → 85% — nowhere near balance. The QUASI_CLOSED containers are the real bulk occupying the space and disk balancer is completely blind to them.
Added a config
hdds.datanode.disk.balancer.container.statesdefault=CLOSED,QUASI_CLOSED which indicate the container lifecycle state names (CLOSED, QUASI_CLOSED) that are eligible to be moved between disks on a datanode.Extended this to a CLI option for start or update config command so there is no need to restart dn after updating the property.
2nd Improvement:
We need to add debug logs for chooseContainer method as user might not understand why if they have over and under utilised volume still container is not moved. This parts needs more clarification. Because I see in escalation it helped a lot with balancer debug logs for container not choose to identify what state the container or volume was in.
I suggest adding these logs for container not choose :
What is the link to the Apache JIRA
https://issues.apache.org/jira/browse/HDDS-14926
How was this patch tested?
Added unit test.
Tested manually as well for CLI: