|
@@ -34,6 +34,7 @@ import org.apache.hadoop.io.erasurecode.ErasureCodeConstants;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
|
|
+import java.io.IOException;
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
@@ -79,6 +80,15 @@ public final class ErasureCodingPolicyManager {
|
|
*/
|
|
*/
|
|
private ErasureCodingPolicyInfo[] allPolicies;
|
|
private ErasureCodingPolicyInfo[] allPolicies;
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * All policies in the state as it will be persisted in the fsimage.
|
|
|
|
+ *
|
|
|
|
+ * The difference between persisted policies and all policies is that
|
|
|
|
+ * if a default policy is only enabled at startup,
|
|
|
|
+ * it will appear as disabled in the persisted policy list and in the fsimage.
|
|
|
|
+ */
|
|
|
|
+ private Map<Byte, ErasureCodingPolicyInfo> allPersistedPolicies;
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* All enabled policies sorted by name for fast querying, including built-in
|
|
* All enabled policies sorted by name for fast querying, including built-in
|
|
* policy, user defined policy.
|
|
* policy, user defined policy.
|
|
@@ -89,6 +99,7 @@ public final class ErasureCodingPolicyManager {
|
|
*/
|
|
*/
|
|
private ErasureCodingPolicy[] enabledPolicies;
|
|
private ErasureCodingPolicy[] enabledPolicies;
|
|
|
|
|
|
|
|
+ private String defaultPolicyName;
|
|
|
|
|
|
private volatile static ErasureCodingPolicyManager instance = null;
|
|
private volatile static ErasureCodingPolicyManager instance = null;
|
|
|
|
|
|
@@ -101,14 +112,11 @@ public final class ErasureCodingPolicyManager {
|
|
|
|
|
|
private ErasureCodingPolicyManager() {}
|
|
private ErasureCodingPolicyManager() {}
|
|
|
|
|
|
- public void init(Configuration conf) {
|
|
|
|
- // Load erasure coding default policy
|
|
|
|
- final String defaultPolicyName = conf.getTrimmed(
|
|
|
|
- DFSConfigKeys.DFS_NAMENODE_EC_SYSTEM_DEFAULT_POLICY,
|
|
|
|
- DFSConfigKeys.DFS_NAMENODE_EC_SYSTEM_DEFAULT_POLICY_DEFAULT);
|
|
|
|
|
|
+ public void init(Configuration conf) throws IOException {
|
|
this.policiesByName = new TreeMap<>();
|
|
this.policiesByName = new TreeMap<>();
|
|
this.policiesByID = new TreeMap<>();
|
|
this.policiesByID = new TreeMap<>();
|
|
this.enabledPoliciesByName = new TreeMap<>();
|
|
this.enabledPoliciesByName = new TreeMap<>();
|
|
|
|
+ this.allPersistedPolicies = new TreeMap<>();
|
|
|
|
|
|
/**
|
|
/**
|
|
* TODO: load user defined EC policy from fsImage HDFS-7859
|
|
* TODO: load user defined EC policy from fsImage HDFS-7859
|
|
@@ -124,31 +132,12 @@ public final class ErasureCodingPolicyManager {
|
|
final ErasureCodingPolicyInfo info = new ErasureCodingPolicyInfo(policy);
|
|
final ErasureCodingPolicyInfo info = new ErasureCodingPolicyInfo(policy);
|
|
policiesByName.put(policy.getName(), info);
|
|
policiesByName.put(policy.getName(), info);
|
|
policiesByID.put(policy.getId(), info);
|
|
policiesByID.put(policy.getId(), info);
|
|
|
|
+ allPersistedPolicies.put(policy.getId(),
|
|
|
|
+ new ErasureCodingPolicyInfo(policy));
|
|
}
|
|
}
|
|
|
|
|
|
- if (!defaultPolicyName.isEmpty()) {
|
|
|
|
- final ErasureCodingPolicyInfo info =
|
|
|
|
- policiesByName.get(defaultPolicyName);
|
|
|
|
- if (info == null) {
|
|
|
|
- String names = policiesByName.values()
|
|
|
|
- .stream().map((pi) -> pi.getPolicy().getName())
|
|
|
|
- .collect(Collectors.joining(", "));
|
|
|
|
- String msg = String.format("EC policy '%s' specified at %s is not a "
|
|
|
|
- + "valid policy. Please choose from list of available "
|
|
|
|
- + "policies: [%s]",
|
|
|
|
- defaultPolicyName,
|
|
|
|
- DFSConfigKeys.DFS_NAMENODE_EC_SYSTEM_DEFAULT_POLICY,
|
|
|
|
- names);
|
|
|
|
- throw new HadoopIllegalArgumentException(msg);
|
|
|
|
- }
|
|
|
|
- info.setState(ErasureCodingPolicyState.ENABLED);
|
|
|
|
- enabledPoliciesByName.put(info.getPolicy().getName(), info.getPolicy());
|
|
|
|
- }
|
|
|
|
- enabledPolicies =
|
|
|
|
- enabledPoliciesByName.values().toArray(new ErasureCodingPolicy[0]);
|
|
|
|
- allPolicies =
|
|
|
|
- policiesByName.values().toArray(new ErasureCodingPolicyInfo[0]);
|
|
|
|
-
|
|
|
|
|
|
+ enableDefaultPolicy(conf);
|
|
|
|
+ updatePolicies();
|
|
maxCellSize = conf.getInt(
|
|
maxCellSize = conf.getInt(
|
|
DFSConfigKeys.DFS_NAMENODE_EC_POLICIES_MAX_CELLSIZE_KEY,
|
|
DFSConfigKeys.DFS_NAMENODE_EC_POLICIES_MAX_CELLSIZE_KEY,
|
|
DFSConfigKeys.DFS_NAMENODE_EC_POLICIES_MAX_CELLSIZE_DEFAULT);
|
|
DFSConfigKeys.DFS_NAMENODE_EC_POLICIES_MAX_CELLSIZE_DEFAULT);
|
|
@@ -199,6 +188,21 @@ public final class ErasureCodingPolicyManager {
|
|
return allPolicies;
|
|
return allPolicies;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Get all system defined policies and user defined policies
|
|
|
|
+ * as it is written out in the fsimage.
|
|
|
|
+ *
|
|
|
|
+ * The difference between persisted policies and all policies is that
|
|
|
|
+ * if a default policy is only enabled at startup,
|
|
|
|
+ * it will appear as disabled in the persisted policy list and in the fsimage.
|
|
|
|
+ *
|
|
|
|
+ * @return persisted policies
|
|
|
|
+ */
|
|
|
|
+ public ErasureCodingPolicyInfo[] getPersistedPolicies() {
|
|
|
|
+ return allPersistedPolicies.values()
|
|
|
|
+ .toArray(new ErasureCodingPolicyInfo[0]);
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Get a {@link ErasureCodingPolicy} by policy ID, including system policy
|
|
* Get a {@link ErasureCodingPolicy} by policy ID, including system policy
|
|
* and user defined policy.
|
|
* and user defined policy.
|
|
@@ -298,6 +302,8 @@ public final class ErasureCodingPolicyManager {
|
|
this.policiesByID.put(policy.getId(), pi);
|
|
this.policiesByID.put(policy.getId(), pi);
|
|
allPolicies =
|
|
allPolicies =
|
|
policiesByName.values().toArray(new ErasureCodingPolicyInfo[0]);
|
|
policiesByName.values().toArray(new ErasureCodingPolicyInfo[0]);
|
|
|
|
+ allPersistedPolicies.put(policy.getId(),
|
|
|
|
+ new ErasureCodingPolicyInfo(policy));
|
|
return policy;
|
|
return policy;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -334,7 +340,8 @@ public final class ErasureCodingPolicyManager {
|
|
}
|
|
}
|
|
info.setState(ErasureCodingPolicyState.REMOVED);
|
|
info.setState(ErasureCodingPolicyState.REMOVED);
|
|
LOG.info("Remove erasure coding policy " + name);
|
|
LOG.info("Remove erasure coding policy " + name);
|
|
-
|
|
|
|
|
|
+ allPersistedPolicies.put(ecPolicy.getId(),
|
|
|
|
+ createPolicyInfo(ecPolicy, ErasureCodingPolicyState.REMOVED));
|
|
/*
|
|
/*
|
|
* TODO HDFS-12405 postpone the delete removed policy to Namenode restart
|
|
* TODO HDFS-12405 postpone the delete removed policy to Namenode restart
|
|
* time.
|
|
* time.
|
|
@@ -369,6 +376,9 @@ public final class ErasureCodingPolicyManager {
|
|
enabledPoliciesByName.values().toArray(new ErasureCodingPolicy[0]);
|
|
enabledPoliciesByName.values().toArray(new ErasureCodingPolicy[0]);
|
|
info.setState(ErasureCodingPolicyState.DISABLED);
|
|
info.setState(ErasureCodingPolicyState.DISABLED);
|
|
LOG.info("Disable the erasure coding policy " + name);
|
|
LOG.info("Disable the erasure coding policy " + name);
|
|
|
|
+ allPersistedPolicies.put(info.getPolicy().getId(),
|
|
|
|
+ createPolicyInfo(info.getPolicy(),
|
|
|
|
+ ErasureCodingPolicyState.DISABLED));
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
return false;
|
|
@@ -384,6 +394,12 @@ public final class ErasureCodingPolicyManager {
|
|
name + " does not exist");
|
|
name + " does not exist");
|
|
}
|
|
}
|
|
if (enabledPoliciesByName.containsKey(name)) {
|
|
if (enabledPoliciesByName.containsKey(name)) {
|
|
|
|
+ if (defaultPolicyName.equals(name)) {
|
|
|
|
+ allPersistedPolicies.put(info.getPolicy().getId(),
|
|
|
|
+ createPolicyInfo(info.getPolicy(),
|
|
|
|
+ ErasureCodingPolicyState.ENABLED));
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
final ErasureCodingPolicy ecPolicy = info.getPolicy();
|
|
final ErasureCodingPolicy ecPolicy = info.getPolicy();
|
|
@@ -391,6 +407,8 @@ public final class ErasureCodingPolicyManager {
|
|
info.setState(ErasureCodingPolicyState.ENABLED);
|
|
info.setState(ErasureCodingPolicyState.ENABLED);
|
|
enabledPolicies =
|
|
enabledPolicies =
|
|
enabledPoliciesByName.values().toArray(new ErasureCodingPolicy[0]);
|
|
enabledPoliciesByName.values().toArray(new ErasureCodingPolicy[0]);
|
|
|
|
+ allPersistedPolicies.put(ecPolicy.getId(),
|
|
|
|
+ createPolicyInfo(info.getPolicy(), ErasureCodingPolicyState.ENABLED));
|
|
LOG.info("Enable the erasure coding policy " + name);
|
|
LOG.info("Enable the erasure coding policy " + name);
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
@@ -413,6 +431,8 @@ public final class ErasureCodingPolicyManager {
|
|
if (info.isEnabled()) {
|
|
if (info.isEnabled()) {
|
|
enablePolicy(policy.getName());
|
|
enablePolicy(policy.getName());
|
|
}
|
|
}
|
|
|
|
+ allPersistedPolicies.put(policy.getId(),
|
|
|
|
+ createPolicyInfo(policy, info.getState()));
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -422,12 +442,51 @@ public final class ErasureCodingPolicyManager {
|
|
*
|
|
*
|
|
*/
|
|
*/
|
|
public synchronized void loadPolicies(
|
|
public synchronized void loadPolicies(
|
|
- List<ErasureCodingPolicyInfo> ecPolicies) {
|
|
|
|
|
|
+ List<ErasureCodingPolicyInfo> ecPolicies, Configuration conf)
|
|
|
|
+ throws IOException{
|
|
Preconditions.checkNotNull(ecPolicies);
|
|
Preconditions.checkNotNull(ecPolicies);
|
|
for (ErasureCodingPolicyInfo p : ecPolicies) {
|
|
for (ErasureCodingPolicyInfo p : ecPolicies) {
|
|
loadPolicy(p);
|
|
loadPolicy(p);
|
|
}
|
|
}
|
|
|
|
+ enableDefaultPolicy(conf);
|
|
|
|
+ updatePolicies();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void enableDefaultPolicy(Configuration conf) throws IOException {
|
|
|
|
+ defaultPolicyName = conf.getTrimmed(
|
|
|
|
+ DFSConfigKeys.DFS_NAMENODE_EC_SYSTEM_DEFAULT_POLICY,
|
|
|
|
+ DFSConfigKeys.DFS_NAMENODE_EC_SYSTEM_DEFAULT_POLICY_DEFAULT);
|
|
|
|
+ if (!defaultPolicyName.isEmpty()) {
|
|
|
|
+ final ErasureCodingPolicyInfo info =
|
|
|
|
+ policiesByName.get(defaultPolicyName);
|
|
|
|
+ if (info == null) {
|
|
|
|
+ String names = policiesByName.values()
|
|
|
|
+ .stream().map((pi) -> pi.getPolicy().getName())
|
|
|
|
+ .collect(Collectors.joining(", "));
|
|
|
|
+ String msg = String.format("EC policy '%s' specified at %s is not a "
|
|
|
|
+ + "valid policy. Please choose from list of available "
|
|
|
|
+ + "policies: [%s]",
|
|
|
|
+ defaultPolicyName,
|
|
|
|
+ DFSConfigKeys.DFS_NAMENODE_EC_SYSTEM_DEFAULT_POLICY,
|
|
|
|
+ names);
|
|
|
|
+ throw new IOException(msg);
|
|
|
|
+ }
|
|
|
|
+ info.setState(ErasureCodingPolicyState.ENABLED);
|
|
|
|
+ enabledPoliciesByName.put(info.getPolicy().getName(), info.getPolicy());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void updatePolicies() {
|
|
|
|
+ enabledPolicies =
|
|
|
|
+ enabledPoliciesByName.values().toArray(new ErasureCodingPolicy[0]);
|
|
allPolicies =
|
|
allPolicies =
|
|
policiesByName.values().toArray(new ErasureCodingPolicyInfo[0]);
|
|
policiesByName.values().toArray(new ErasureCodingPolicyInfo[0]);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ private ErasureCodingPolicyInfo createPolicyInfo(ErasureCodingPolicy p,
|
|
|
|
+ ErasureCodingPolicyState s) {
|
|
|
|
+ ErasureCodingPolicyInfo policyInfo = new ErasureCodingPolicyInfo(p);
|
|
|
|
+ policyInfo.setState(s);
|
|
|
|
+ return policyInfo;
|
|
|
|
+ }
|
|
}
|
|
}
|