You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ozone.apache.org by ad...@apache.org on 2026/10/03 12:28:47 UTC
(ozone) branch master updated: HDDS-14018. Avoid repeated operations in SCMNodeManager#getNodeStatistics (#11292)
This is an automated email from the ASF dual-hosted git repository.
adoroszlai pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git
The following commit(s) were added to refs/heads/master by this push:
new 7f7cb3f5597 HDDS-14018. Avoid repeated operations in SCMNodeManager#getNodeStatistics (#11292)
7f7cb3f5597 is described below
commit 7f7cb3f5597e69e138278a8f35f91817bd1a5b2b
Author: Sarveksha Yeshavantha Raju <79...@users.noreply.github.com>
AuthorDate: Sat Oct 3 17:58:40 2026 +0530
HDDS-14018. Avoid repeated operations in SCMNodeManager#getNodeStatistics (#11292)
---
.../hadoop/hdds/scm/node/SCMNodeManager.java | 185 +++++++++++++--------
1 file changed, 114 insertions(+), 71 deletions(-)
diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/node/SCMNodeManager.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/node/SCMNodeManager.java
index 6a891e09b5c..d8884cdc464 100644
--- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/node/SCMNodeManager.java
+++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/node/SCMNodeManager.java
@@ -1187,7 +1187,7 @@ public Map<String, Map<String, Integer>> getNodeCount() {
}
nodes.put(opState.name(), states);
}
- for (DatanodeInfo dni : nodeStateManager.getAllNodes()) {
+ for (DatanodeInfo dni : getAllNodes()) {
NodeStatus status = dni.getNodeStatus();
nodes.get(status.getOperationalState().name())
.compute(status.getHealth().name(), (k, v) -> v + 1);
@@ -1222,7 +1222,7 @@ public Map<String, Long> getNodeInfo() {
boolean fsPresent = false;
boolean fsMissing = false;
- for (DatanodeInfo node : nodeStateManager.getAllNodes()) {
+ for (DatanodeInfo node : getAllNodes()) {
String keyPrefix = "";
NodeStatus status = node.getNodeStatus();
if (status.isMaintenance()) {
@@ -1280,7 +1280,7 @@ public Map<String, Long> getNodeInfo() {
@Override
public Map<String, Map<String, String>> getNodeStatusInfo() {
Map<String, Map<String, String>> nodes = new HashMap<>();
- for (DatanodeInfo dni : nodeStateManager.getAllNodes()) {
+ for (DatanodeInfo dni : getAllNodes()) {
String hostName = dni.getHostName();
DatanodeDetails.Port httpPort = dni.getPort(HTTP);
DatanodeDetails.Port httpsPort = dni.getPort(HTTPS);
@@ -1374,66 +1374,96 @@ public static String[] calculateStoragePercentage(
String usedPercentage = "N/A";
String nonUsedPercentage = "N/A";
if (storageReports != null && !storageReports.isEmpty()) {
- long capacity = 0;
- long scmUsed = 0;
- long remaining = 0;
+ StorageReportTotals totals = sumStorageReports(storageReports);
+ long scmNonUsed = totals.capacity - totals.scmUsed - totals.remaining;
+ usedPercentage = formatStoragePercentage(
+ ((double) totals.scmUsed / totals.capacity) * 100);
+ nonUsedPercentage = formatStoragePercentage(
+ ((double) scmNonUsed / totals.capacity) * 100);
+ }
+
+ storagePercentage[0] = usedPercentage;
+ storagePercentage[1] = nonUsedPercentage;
+ return storagePercentage;
+ }
+
+ private static StorageReportTotals sumStorageReports(List<StorageReportProto> storageReports) {
+ long capacity = 0;
+ long scmUsed = 0;
+ long remaining = 0;
+ if (storageReports != null) {
for (StorageReportProto storageReport : storageReports) {
capacity += storageReport.getCapacity();
scmUsed += storageReport.getScmUsed();
remaining += storageReport.getRemaining();
}
- long scmNonUsed = capacity - scmUsed - remaining;
-
- DecimalFormat decimalFormat = TWO_DECIMAL_FORMAT.get();
-
- double usedPerc = ((double) scmUsed / capacity) * 100;
- usedPerc = usedPerc > 100.0 ? 100.0 : usedPerc;
- double nonUsedPerc = ((double) scmNonUsed / capacity) * 100;
- nonUsedPerc = nonUsedPerc > 100.0 ? 100.0 : nonUsedPerc;
- usedPercentage = decimalFormat.format(usedPerc);
- nonUsedPercentage = decimalFormat.format(nonUsedPerc);
}
+ return new StorageReportTotals(capacity, scmUsed, remaining);
+ }
- storagePercentage[0] = usedPercentage;
- storagePercentage[1] = nonUsedPercentage;
- return storagePercentage;
+ private static String formatStoragePercentage(double percentage) {
+ double capped = percentage > 100.0 ? 100.0 : percentage;
+ return TWO_DECIMAL_FORMAT.get().format(capped);
}
@Override
public Map<String, String> getNodeStatistics() {
Map<String, String> nodeStatistics = new HashMap<>();
- // Statistics node usaged
- nodeUsageStatistics(nodeStatistics);
+ List<DatanodeInfo> allNodes = getAllNodes();
+ NodeStorageAggregation storageAggregation = aggregateNodeStorage(allNodes);
+ // Statistics node usage
+ nodeUsageStatistics(nodeStatistics, storageAggregation);
// Statistics node states
- nodeStateStatistics(nodeStatistics);
+ nodeStateStatistics(nodeStatistics, allNodes);
// Statistics node space
- nodeSpaceStatistics(nodeStatistics);
+ nodeSpaceStatistics(nodeStatistics, storageAggregation);
// Statistics node non-writable
- nodeNonWritableStatistics(nodeStatistics);
+ nodeNonWritableStatistics(nodeStatistics, allNodes);
// todo: Statistics of other instances
return nodeStatistics;
}
- private void nodeUsageStatistics(Map<String, String> nodeStatics) {
- if (nodeStateManager.getAllNodes().isEmpty()) {
- return;
+ private NodeStorageAggregation aggregateNodeStorage(List<DatanodeInfo> allNodes) {
+ if (allNodes.isEmpty()) {
+ return null;
}
- float[] usages = new float[nodeStateManager.getAllNodes().size()];
- float totalOzoneUsed = 0;
- int i = 0;
- for (DatanodeInfo dni : nodeStateManager.getAllNodes()) {
- String[] storagePercentage = calculateStoragePercentage(
- dni.getStorageReports());
- if (storagePercentage[0].equals("N/A")) {
- usages[i++] = 0;
+ long capacityByte = 0;
+ long scmUsedByte = 0;
+ long remainingByte = 0;
+ long totalPending = 0;
+ float[] usages = new float[allNodes.size()];
+ int usageIndex = 0;
+ for (DatanodeInfo dni : allNodes) {
+ totalPending += dni.getPendingContainerAllocations().getCount();
+ List<StorageReportProto> storageReports = dni.getStorageReports();
+ if (storageReports != null && !storageReports.isEmpty()) {
+ StorageReportTotals nodeTotals = sumStorageReports(storageReports);
+ capacityByte += nodeTotals.capacity;
+ scmUsedByte += nodeTotals.scmUsed;
+ remainingByte += nodeTotals.remaining;
+ if (nodeTotals.capacity <= 0) {
+ usages[usageIndex++] = 0;
+ } else {
+ usages[usageIndex++] = Float.parseFloat(formatStoragePercentage(
+ ((double) nodeTotals.scmUsed / nodeTotals.capacity) * 100));
+ }
} else {
- float storagePerc = Float.parseFloat(storagePercentage[0]);
- usages[i++] = storagePerc;
- totalOzoneUsed = totalOzoneUsed + storagePerc;
+ usages[usageIndex++] = 0;
}
}
+ return new NodeStorageAggregation(capacityByte, scmUsedByte, remainingByte, totalPending, usages);
+ }
- totalOzoneUsed /= nodeStateManager.getAllNodes().size();
+ private void nodeUsageStatistics(Map<String, String> nodeStatics, NodeStorageAggregation storageAggregation) {
+ if (storageAggregation == null) {
+ return;
+ }
+ float[] usages = storageAggregation.usages.clone();
+ float totalOzoneUsed = 0;
+ for (float usage : usages) {
+ totalOzoneUsed += usage;
+ }
+ totalOzoneUsed /= usages.length;
Arrays.sort(usages);
float median = usages[usages.length / 2];
nodeStatics.put(UsageStatics.MEDIAN.getLabel(), String.valueOf(median));
@@ -1443,19 +1473,39 @@ private void nodeUsageStatistics(Map<String, String> nodeStatics) {
nodeStatics.put(UsageStatics.MIN.getLabel(), String.valueOf(min));
float dev = 0;
- for (i = 0; i < usages.length; i++) {
- dev += (usages[i] - totalOzoneUsed) * (usages[i] - totalOzoneUsed);
+ for (float usage : usages) {
+ dev += (usage - totalOzoneUsed) * (usage - totalOzoneUsed);
}
dev = (float) Math.sqrt(dev / usages.length);
nodeStatics.put(UsageStatics.STDEV.getLabel(), TWO_DECIMAL_FORMAT.get().format(dev));
}
- private void nodeStateStatistics(Map<String, String> nodeStatics) {
- int healthyNodeCount = nodeStateManager.getHealthyNodeCount();
- int deadNodeCount = nodeStateManager.getDeadNodeCount();
- int decommissioningNodeCount = nodeStateManager.getDecommissioningNodeCount();
- int enteringMaintenanceNodeCount = nodeStateManager.getEnteringMaintenanceNodeCount();
- int volumeFailuresNodeCount = nodeStateManager.getVolumeFailuresNodeCount();
+ private void nodeStateStatistics(Map<String, String> nodeStatics, List<DatanodeInfo> allNodes) {
+ int healthyNodeCount = 0;
+ int deadNodeCount = 0;
+ int decommissioningNodeCount = 0;
+ int enteringMaintenanceNodeCount = 0;
+ int volumeFailuresNodeCount = 0;
+
+ for (DatanodeInfo dni : allNodes) {
+ NodeStatus status = dni.getNodeStatus();
+ if (status.getHealth() == HEALTHY) {
+ healthyNodeCount++;
+ }
+ if (status.isDead()) {
+ deadNodeCount++;
+ }
+ if (status.isDecommissioning()) {
+ decommissioningNodeCount++;
+ }
+ if (status.isEnteringMaintenance()) {
+ enteringMaintenanceNodeCount++;
+ }
+ if (dni.getFailedVolumeCount() > 0) {
+ volumeFailuresNodeCount++;
+ }
+ }
+
nodeStatics.put(StateStatistics.HEALTHY.getLabel(), String.valueOf(healthyNodeCount));
nodeStatics.put(StateStatistics.DEAD.getLabel(), String.valueOf(deadNodeCount));
nodeStatics.put(StateStatistics.DECOMMISSIONING.getLabel(), String.valueOf(decommissioningNodeCount));
@@ -1463,34 +1513,20 @@ private void nodeStateStatistics(Map<String, String> nodeStatics) {
nodeStatics.put(StateStatistics.VOLUME_FAILURES.getLabel(), String.valueOf(volumeFailuresNodeCount));
}
- private void nodeSpaceStatistics(Map<String, String> nodeStatics) {
- if (nodeStateManager.getAllNodes().isEmpty()) {
+ private void nodeSpaceStatistics(Map<String, String> nodeStatics, NodeStorageAggregation storageAggregation) {
+ if (storageAggregation == null) {
return;
}
- long capacityByte = 0;
- long scmUsedByte = 0;
- long remainingByte = 0;
- long totalPending = 0;
- for (DatanodeInfo dni : nodeStateManager.getAllNodes()) {
- totalPending += dni.getPendingContainerAllocations().getCount();
- List<StorageReportProto> storageReports = dni.getStorageReports();
- if (storageReports != null && !storageReports.isEmpty()) {
- for (StorageReportProto storageReport : storageReports) {
- capacityByte += storageReport.getCapacity();
- scmUsedByte += storageReport.getScmUsed();
- remainingByte += storageReport.getRemaining();
- }
- }
- }
- metrics.setTotalPendingContainerSlots(totalPending);
+ metrics.setTotalPendingContainerSlots(storageAggregation.totalPending);
- long nonScmUsedByte = capacityByte - scmUsedByte - remainingByte;
+ long nonScmUsedByte = storageAggregation.capacityByte - storageAggregation.scmUsedByte
+ - storageAggregation.remainingByte;
if (nonScmUsedByte < 0) {
nonScmUsedByte = 0;
}
- String capacity = convertUnit(capacityByte);
- String scmUsed = convertUnit(scmUsedByte);
- String remaining = convertUnit(remainingByte);
+ String capacity = convertUnit(storageAggregation.capacityByte);
+ String scmUsed = convertUnit(storageAggregation.scmUsedByte);
+ String remaining = convertUnit(storageAggregation.remainingByte);
String nonScmUsed = convertUnit(nonScmUsedByte);
nodeStatics.put(SpaceStatistics.CAPACITY.getLabel(), capacity);
nodeStatics.put(SpaceStatistics.SCM_USED.getLabel(), scmUsed);
@@ -1498,8 +1534,8 @@ private void nodeSpaceStatistics(Map<String, String> nodeStatics) {
nodeStatics.put(SpaceStatistics.NON_SCM_USED.getLabel(), nonScmUsed);
}
- private void nodeNonWritableStatistics(Map<String, String> nodeStatics) {
- int nonWritableNodesCount = (int) getAllNodes().parallelStream()
+ private void nodeNonWritableStatistics(Map<String, String> nodeStatics, List<DatanodeInfo> allNodes) {
+ int nonWritableNodesCount = (int) allNodes.parallelStream()
.filter(nonWritableNodeFilter)
.count();
@@ -1566,6 +1602,13 @@ private boolean hasEnoughCommittedVolumeSpace(DatanodeInfo dnInfo) {
}
}
+ private record StorageReportTotals(long capacity, long scmUsed, long remaining) {
+ }
+
+ private record NodeStorageAggregation(long capacityByte, long scmUsedByte, long remainingByte,
+ long totalPending, float[] usages) {
+ }
+
/**
* Based on the current time and the last heartbeat, calculate the time difference
* and get a string of the relative value. E.g. "2s ago", "1m 2s ago", etc.
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@ozone.apache.org
For additional commands, e-mail: commits-help@ozone.apache.org