|
@@ -18,7 +18,11 @@
|
|
|
package org.apache.hadoop.hdfs.server.balancer;
|
|
|
|
|
|
import org.apache.hadoop.classification.InterfaceAudience;
|
|
|
-import org.apache.hadoop.hdfs.protocol.DatanodeInfo;
|
|
|
+import org.apache.hadoop.hdfs.StorageType;
|
|
|
+import org.apache.hadoop.hdfs.server.protocol.DatanodeStorageReport;
|
|
|
+import org.apache.hadoop.hdfs.server.protocol.StorageReport;
|
|
|
+import org.apache.hadoop.hdfs.util.EnumCounters;
|
|
|
+import org.apache.hadoop.hdfs.util.EnumDoubles;
|
|
|
|
|
|
/**
|
|
|
* Balancing policy.
|
|
@@ -28,31 +32,43 @@ import org.apache.hadoop.hdfs.protocol.DatanodeInfo;
|
|
|
*/
|
|
|
@InterfaceAudience.Private
|
|
|
abstract class BalancingPolicy {
|
|
|
- long totalCapacity;
|
|
|
- long totalUsedSpace;
|
|
|
- private double avgUtilization;
|
|
|
+ final EnumCounters<StorageType> totalCapacities
|
|
|
+ = new EnumCounters<StorageType>(StorageType.class);
|
|
|
+ final EnumCounters<StorageType> totalUsedSpaces
|
|
|
+ = new EnumCounters<StorageType>(StorageType.class);
|
|
|
+ final EnumDoubles<StorageType> avgUtilizations
|
|
|
+ = new EnumDoubles<StorageType>(StorageType.class);
|
|
|
|
|
|
void reset() {
|
|
|
- totalCapacity = 0L;
|
|
|
- totalUsedSpace = 0L;
|
|
|
- avgUtilization = 0.0;
|
|
|
+ totalCapacities.reset();
|
|
|
+ totalUsedSpaces.reset();
|
|
|
+ avgUtilizations.reset();
|
|
|
}
|
|
|
|
|
|
/** Get the policy name. */
|
|
|
abstract String getName();
|
|
|
|
|
|
/** Accumulate used space and capacity. */
|
|
|
- abstract void accumulateSpaces(DatanodeInfo d);
|
|
|
+ abstract void accumulateSpaces(DatanodeStorageReport r);
|
|
|
|
|
|
void initAvgUtilization() {
|
|
|
- this.avgUtilization = totalUsedSpace*100.0/totalCapacity;
|
|
|
+ for(StorageType t : StorageType.asList()) {
|
|
|
+ final long capacity = totalCapacities.get(t);
|
|
|
+ if (capacity > 0L) {
|
|
|
+ final double avg = totalUsedSpaces.get(t)*100.0/capacity;
|
|
|
+ avgUtilizations.set(t, avg);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- double getAvgUtilization() {
|
|
|
- return avgUtilization;
|
|
|
+
|
|
|
+ double getAvgUtilization(StorageType t) {
|
|
|
+ return avgUtilizations.get(t);
|
|
|
}
|
|
|
|
|
|
- /** Return the utilization of a datanode */
|
|
|
- abstract double getUtilization(DatanodeInfo d);
|
|
|
+ /** @return the utilization of a particular storage type of a datanode;
|
|
|
+ * or return null if the datanode does not have such storage type.
|
|
|
+ */
|
|
|
+ abstract Double getUtilization(DatanodeStorageReport r, StorageType t);
|
|
|
|
|
|
@Override
|
|
|
public String toString() {
|
|
@@ -84,14 +100,25 @@ abstract class BalancingPolicy {
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- void accumulateSpaces(DatanodeInfo d) {
|
|
|
- totalCapacity += d.getCapacity();
|
|
|
- totalUsedSpace += d.getDfsUsed();
|
|
|
+ void accumulateSpaces(DatanodeStorageReport r) {
|
|
|
+ for(StorageReport s : r.getStorageReports()) {
|
|
|
+ final StorageType t = s.getStorage().getStorageType();
|
|
|
+ totalCapacities.add(t, s.getCapacity());
|
|
|
+ totalUsedSpaces.add(t, s.getDfsUsed());
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- double getUtilization(DatanodeInfo d) {
|
|
|
- return d.getDfsUsed()*100.0/d.getCapacity();
|
|
|
+ Double getUtilization(DatanodeStorageReport r, final StorageType t) {
|
|
|
+ long capacity = 0L;
|
|
|
+ long dfsUsed = 0L;
|
|
|
+ for(StorageReport s : r.getStorageReports()) {
|
|
|
+ if (s.getStorage().getStorageType() == t) {
|
|
|
+ capacity += s.getCapacity();
|
|
|
+ dfsUsed += s.getDfsUsed();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return capacity == 0L? null: dfsUsed*100.0/capacity;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -108,14 +135,25 @@ abstract class BalancingPolicy {
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- void accumulateSpaces(DatanodeInfo d) {
|
|
|
- totalCapacity += d.getCapacity();
|
|
|
- totalUsedSpace += d.getBlockPoolUsed();
|
|
|
+ void accumulateSpaces(DatanodeStorageReport r) {
|
|
|
+ for(StorageReport s : r.getStorageReports()) {
|
|
|
+ final StorageType t = s.getStorage().getStorageType();
|
|
|
+ totalCapacities.add(t, s.getCapacity());
|
|
|
+ totalUsedSpaces.add(t, s.getBlockPoolUsed());
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- double getUtilization(DatanodeInfo d) {
|
|
|
- return d.getBlockPoolUsed()*100.0/d.getCapacity();
|
|
|
+ Double getUtilization(DatanodeStorageReport r, final StorageType t) {
|
|
|
+ long capacity = 0L;
|
|
|
+ long blockPoolUsed = 0L;
|
|
|
+ for(StorageReport s : r.getStorageReports()) {
|
|
|
+ if (s.getStorage().getStorageType() == t) {
|
|
|
+ capacity += s.getCapacity();
|
|
|
+ blockPoolUsed += s.getBlockPoolUsed();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return capacity == 0L? null: blockPoolUsed*100.0/capacity;
|
|
|
}
|
|
|
}
|
|
|
}
|