Skip to content

Commit 1b83e16

Browse files
authored
HDDS-14866. Enhance DiskBalancer Report to show individual volume's density (#9969)
1 parent 1ca9192 commit 1b83e16

7 files changed

Lines changed: 312 additions & 42 deletions

File tree

hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/diskbalancer/DiskBalancerInfo.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,15 @@
1717

1818
package org.apache.hadoop.ozone.container.diskbalancer;
1919

20+
import java.util.Collections;
21+
import java.util.List;
2022
import java.util.Objects;
2123
import org.apache.hadoop.hdds.protocol.proto.HddsProtos.DiskBalancerRunningStatus;
24+
import org.apache.hadoop.hdds.protocol.proto.HddsProtos.VolumeReportProto;
2225

2326
/**
24-
* DiskBalancer's information to persist.
27+
* DiskBalancer's information to persist and for report.
28+
* Report-only fields (idealUsage, volumeInfo) are NOT persisted to YAML.
2529
*/
2630
public class DiskBalancerInfo {
2731
private DiskBalancerRunningStatus operationalState;
@@ -35,6 +39,10 @@ public class DiskBalancerInfo {
3539
private long bytesToMove;
3640
private long balancedBytes;
3741
private double volumeDataDensity;
42+
// Report-only: ideal usage from volume snapshot. NOT persisted.
43+
private double idealUsage;
44+
// Report-only: per-volume info. NOT persisted.
45+
private List<VolumeReportProto> volumeInfo;
3846

3947
public DiskBalancerInfo(DiskBalancerRunningStatus operationalState, double threshold,
4048
long bandwidthInMB, int parallelThread, boolean stopAfterDiskEven) {
@@ -208,6 +216,22 @@ public void setVolumeDataDensity(double volumeDataDensity) {
208216
this.volumeDataDensity = volumeDataDensity;
209217
}
210218

219+
public double getIdealUsage() {
220+
return idealUsage;
221+
}
222+
223+
public void setIdealUsage(double idealUsage) {
224+
this.idealUsage = idealUsage;
225+
}
226+
227+
public List<VolumeReportProto> getVolumeInfo() {
228+
return volumeInfo != null ? volumeInfo : Collections.emptyList();
229+
}
230+
231+
public void setVolumeInfo(List<VolumeReportProto> volumeInfo) {
232+
this.volumeInfo = volumeInfo;
233+
}
234+
211235
@Override
212236
public boolean equals(Object o) {
213237
if (this == o) {

hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/diskbalancer/DiskBalancerProtocolServer.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ public DatanodeDiskBalancerInfoProto getDiskBalancerInfo(GetDiskBalancerInfoRequ
8282
.setBytesToMove(info.getBytesToMove())
8383
.setBytesMoved(info.getBalancedBytes())
8484
.setRunningStatus(info.getOperationalState())
85+
.setIdealUsage(info.getIdealUsage())
86+
.addAllVolumeInfo(info.getVolumeInfo())
8587
.build();
8688
}
8789

hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/diskbalancer/DiskBalancerService.java

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import java.nio.file.Path;
3232
import java.nio.file.Paths;
3333
import java.nio.file.StandardCopyOption;
34+
import java.util.ArrayList;
35+
import java.util.Collections;
3436
import java.util.List;
3537
import java.util.Map;
3638
import java.util.Objects;
@@ -47,6 +49,7 @@
4749
import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ContainerDataProto.State;
4850
import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
4951
import org.apache.hadoop.hdds.protocol.proto.HddsProtos.DiskBalancerRunningStatus;
52+
import org.apache.hadoop.hdds.protocol.proto.HddsProtos.VolumeReportProto;
5053
import org.apache.hadoop.hdds.scm.container.ContainerID;
5154
import org.apache.hadoop.hdds.scm.container.common.helpers.StorageContainerException;
5255
import org.apache.hadoop.hdds.server.ServerUtils;
@@ -685,9 +688,43 @@ public DiskBalancerInfo getDiskBalancerInfo() {
685688
bytesToMove = calculateBytesToMove(volumeUsages);
686689
}
687690

688-
return new DiskBalancerInfo(operationalState, threshold, bandwidthInMB,
691+
DiskBalancerInfo info = new DiskBalancerInfo(operationalState, threshold, bandwidthInMB,
689692
parallelThread, stopAfterDiskEven, version, metrics.getSuccessCount(),
690693
metrics.getFailureCount(), bytesToMove, metrics.getSuccessBytes(), volumeDataDensity);
694+
info.setIdealUsage(getIdealUsage(volumeUsages));
695+
info.setVolumeInfo(buildVolumeReportProto(volumeUsages));
696+
return info;
697+
}
698+
699+
/**
700+
* Build a list of VolumeReportProto from a list of VolumeFixedUsage.
701+
* VolumeReportProto consists of information like StorageID,
702+
* volume utilization and committed bytes to the client.
703+
*
704+
* @param volumeSet snapshot of VolumeFixedUsage which contains the usage information of each volume
705+
* @return a list of VolumeReportProto which will be sent to clients for reporting volume status
706+
*/
707+
public static List<VolumeReportProto> buildVolumeReportProto(List<VolumeFixedUsage> volumeSet) {
708+
if (volumeSet == null || volumeSet.isEmpty()) {
709+
return Collections.emptyList();
710+
}
711+
712+
List<VolumeReportProto> result = new ArrayList<>();
713+
for (VolumeFixedUsage v : volumeSet) {
714+
HddsVolume volume = v.getVolume();
715+
VolumeReportProto.Builder builder = VolumeReportProto.newBuilder()
716+
.setStorageId(volume.getStorageID())
717+
.setTotalCapacity(v.getUsage().getCapacity())
718+
.setUsedSpace(v.getUsage().getUsedSpace())
719+
.setCommittedBytes(volume.getCommittedBytes())
720+
.setEffectiveUsedSpace(v.getEffectiveUsed())
721+
.setUtilization(v.getUtilization());
722+
if (volume.getStorageDir() != null) {
723+
builder.setStoragePath(volume.getStorageDir().getPath());
724+
}
725+
result.add(builder.build());
726+
}
727+
return result;
691728
}
692729

693730
public long calculateBytesToMove(List<VolumeFixedUsage> inputVolumeSet) {

hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/diskbalancer/TestDiskBalancerProtocolServer.java

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,14 @@
2828
import static org.mockito.Mockito.when;
2929

3030
import java.io.IOException;
31+
import java.util.Arrays;
3132
import java.util.UUID;
3233
import org.apache.hadoop.hdds.protocol.DatanodeDetails;
3334
import org.apache.hadoop.hdds.protocol.proto.DiskBalancerProtocolProtos.GetDiskBalancerInfoRequestProto;
3435
import org.apache.hadoop.hdds.protocol.proto.HddsProtos.DatanodeDiskBalancerInfoProto;
3536
import org.apache.hadoop.hdds.protocol.proto.HddsProtos.DiskBalancerConfigurationProto;
3637
import org.apache.hadoop.hdds.protocol.proto.HddsProtos.DiskBalancerRunningStatus;
38+
import org.apache.hadoop.hdds.protocol.proto.HddsProtos.VolumeReportProto;
3739
import org.apache.hadoop.ozone.container.common.statemachine.DatanodeStateMachine;
3840
import org.apache.hadoop.ozone.container.diskbalancer.DiskBalancerProtocolServer.PrivilegedOperation;
3941
import org.apache.hadoop.ozone.container.ozoneimpl.OzoneContainer;
@@ -51,6 +53,23 @@ class TestDiskBalancerProtocolServer {
5153
private static final int TEST_THREADS = 5;
5254
private static final boolean TEST_STOP_AFTER_DISK_EVEN = true;
5355
private static final double TEST_VOLUME_DENSITY = 15.5;
56+
private static final double TEST_IDEAL_USAGE = 0.6;
57+
private static final String TEST_STORAGE_ID_1 = "vol1";
58+
private static final String TEST_STORAGE_PATH_1 = "/data/hdds1";
59+
private static final String TEST_STORAGE_ID_2 = "vol2";
60+
private static final String TEST_STORAGE_PATH_2 = "/data/hdds2";
61+
private static final double TEST_UTILIZATION_1 = 0.57;
62+
private static final double TEST_UTILIZATION_2 = 0.63;
63+
private static final long TEST_COMMITTED_BYTES_1 = 10L * 1024 * 1024;
64+
private static final long TEST_COMMITTED_BYTES_2 = 25L * 1024 * 1024;
65+
private static final long TEST_TOTAL_CAPACITY = 200L * 1024 * 1024;
66+
private static final long TEST_USED_SPACE_1 = 40L * 1024 * 1024;
67+
private static final long TEST_USED_SPACE_2 = 50L * 1024 * 1024;
68+
private static final long TEST_EFFECTIVE_USED_SPACE_1 =
69+
TEST_USED_SPACE_1 + TEST_COMMITTED_BYTES_1;
70+
private static final long TEST_EFFECTIVE_USED_SPACE_2 =
71+
TEST_USED_SPACE_2 + TEST_COMMITTED_BYTES_2;
72+
private static final int TEST_VOLUME_INFO_COUNT = 2;
5473

5574
private DatanodeStateMachine datanodeStateMachine;
5675
private DiskBalancerService diskBalancerService;
@@ -80,6 +99,27 @@ void setup() throws IOException {
8099
0L, // balancedBytes
81100
TEST_VOLUME_DENSITY
82101
);
102+
diskBalancerInfo.setIdealUsage(TEST_IDEAL_USAGE);
103+
diskBalancerInfo.setVolumeInfo(Arrays.asList(
104+
VolumeReportProto.newBuilder()
105+
.setStorageId(TEST_STORAGE_ID_1)
106+
.setStoragePath(TEST_STORAGE_PATH_1)
107+
.setUtilization(TEST_UTILIZATION_1)
108+
.setCommittedBytes(TEST_COMMITTED_BYTES_1)
109+
.setTotalCapacity(TEST_TOTAL_CAPACITY)
110+
.setUsedSpace(TEST_USED_SPACE_1)
111+
.setEffectiveUsedSpace(TEST_EFFECTIVE_USED_SPACE_1)
112+
.build(),
113+
VolumeReportProto.newBuilder()
114+
.setStorageId(TEST_STORAGE_ID_2)
115+
.setStoragePath(TEST_STORAGE_PATH_2)
116+
.setUtilization(TEST_UTILIZATION_2)
117+
.setCommittedBytes(TEST_COMMITTED_BYTES_2)
118+
.setTotalCapacity(TEST_TOTAL_CAPACITY)
119+
.setUsedSpace(TEST_USED_SPACE_2)
120+
.setEffectiveUsedSpace(TEST_EFFECTIVE_USED_SPACE_2)
121+
.build()));
122+
83123
when(ozoneContainer.getDiskBalancerInfo()).thenReturn(diskBalancerInfo);
84124

85125
// Create datanode details
@@ -102,12 +142,29 @@ void setup() throws IOException {
102142

103143
@Test
104144
void testGetDiskBalancerInfoReport() throws IOException {
105-
// Test REPORT type - should only return volume density
106145
DatanodeDiskBalancerInfoProto report = server.getDiskBalancerInfo(REQUEST_WITH_OLD_CLIENT_VERSION);
107-
146+
VolumeReportProto volReport0 = report.getVolumeInfo(0);
147+
VolumeReportProto volReport1 = report.getVolumeInfo(1);
148+
108149
assertNotNull(report);
109150
assertNotNull(report.getNode());
110151
assertEquals(TEST_VOLUME_DENSITY, report.getCurrentVolumeDensitySum());
152+
assertEquals(TEST_IDEAL_USAGE, report.getIdealUsage());
153+
assertEquals(TEST_VOLUME_INFO_COUNT, report.getVolumeInfoCount());
154+
assertEquals(TEST_STORAGE_ID_1, volReport0.getStorageId());
155+
assertEquals(TEST_STORAGE_PATH_1, volReport0.getStoragePath());
156+
assertEquals(TEST_UTILIZATION_1, volReport0.getUtilization());
157+
assertEquals(TEST_COMMITTED_BYTES_1, volReport0.getCommittedBytes());
158+
assertEquals(TEST_TOTAL_CAPACITY, volReport0.getTotalCapacity());
159+
assertEquals(TEST_USED_SPACE_1, volReport0.getUsedSpace());
160+
assertEquals(TEST_EFFECTIVE_USED_SPACE_1, volReport0.getEffectiveUsedSpace());
161+
assertEquals(TEST_STORAGE_ID_2, volReport1.getStorageId());
162+
assertEquals(TEST_STORAGE_PATH_2, volReport1.getStoragePath());
163+
assertEquals(TEST_UTILIZATION_2, volReport1.getUtilization());
164+
assertEquals(TEST_COMMITTED_BYTES_2, volReport1.getCommittedBytes());
165+
assertEquals(TEST_TOTAL_CAPACITY, volReport1.getTotalCapacity());
166+
assertEquals(TEST_USED_SPACE_2, volReport1.getUsedSpace());
167+
assertEquals(TEST_EFFECTIVE_USED_SPACE_2, volReport1.getEffectiveUsedSpace());
111168
}
112169

113170
@Test

hadoop-hdds/interface-client/src/main/proto/hdds.proto

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,16 @@ enum DiskBalancerRunningStatus {
579579
PAUSED = 3;
580580
}
581581

582+
message VolumeReportProto {
583+
optional string storageId = 1;
584+
optional string storagePath = 2;
585+
optional uint64 totalCapacity = 3;
586+
optional uint64 usedSpace = 4;
587+
optional uint64 committedBytes = 5;
588+
optional uint64 effectiveUsedSpace = 6;
589+
optional double utilization = 7;
590+
}
591+
582592
message DatanodeDiskBalancerInfoProto {
583593
required DatanodeDetailsProto node = 1;
584594
required double currentVolumeDensitySum = 2;
@@ -588,4 +598,6 @@ message DatanodeDiskBalancerInfoProto {
588598
optional uint64 failureMoveCount = 6;
589599
optional uint64 bytesToMove = 7;
590600
optional uint64 bytesMoved = 8;
601+
optional double idealUsage = 9;
602+
repeated VolumeReportProto volumeInfo = 10;
591603
}

0 commit comments

Comments
 (0)