|
@@ -356,6 +356,7 @@ public class NameNode extends ReconfigurableBase implements
|
|
|
LoggerFactory.getLogger("BlockStateChange");
|
|
|
public static final HAState ACTIVE_STATE = new ActiveState();
|
|
|
public static final HAState STANDBY_STATE = new StandbyState();
|
|
|
+ public static final HAState OBSERVER_STATE = new StandbyState(true);
|
|
|
|
|
|
private static final String NAMENODE_HTRACE_PREFIX = "namenode.htrace.";
|
|
|
|
|
@@ -978,9 +979,11 @@ public class NameNode extends ReconfigurableBase implements
|
|
|
}
|
|
|
|
|
|
protected HAState createHAState(StartupOption startOpt) {
|
|
|
- if (!haEnabled || startOpt == StartupOption.UPGRADE
|
|
|
+ if (!haEnabled || startOpt == StartupOption.UPGRADE
|
|
|
|| startOpt == StartupOption.UPGRADEONLY) {
|
|
|
return ACTIVE_STATE;
|
|
|
+ } else if (startOpt == StartupOption.OBSERVER) {
|
|
|
+ return OBSERVER_STATE;
|
|
|
} else {
|
|
|
return STANDBY_STATE;
|
|
|
}
|
|
@@ -1443,6 +1446,8 @@ public class NameNode extends ReconfigurableBase implements
|
|
|
startOpt = StartupOption.BACKUP;
|
|
|
} else if (StartupOption.CHECKPOINT.getName().equalsIgnoreCase(cmd)) {
|
|
|
startOpt = StartupOption.CHECKPOINT;
|
|
|
+ } else if (StartupOption.OBSERVER.getName().equalsIgnoreCase(cmd)) {
|
|
|
+ startOpt = StartupOption.OBSERVER;
|
|
|
} else if (StartupOption.UPGRADE.getName().equalsIgnoreCase(cmd)
|
|
|
|| StartupOption.UPGRADEONLY.getName().equalsIgnoreCase(cmd)) {
|
|
|
startOpt = StartupOption.UPGRADE.getName().equalsIgnoreCase(cmd) ?
|
|
@@ -1774,6 +1779,11 @@ public class NameNode extends ReconfigurableBase implements
|
|
|
if (!haEnabled) {
|
|
|
throw new ServiceFailedException("HA for namenode is not enabled");
|
|
|
}
|
|
|
+ if (state == OBSERVER_STATE) {
|
|
|
+ // TODO: we may need to remove this when enabling failover for observer
|
|
|
+ throw new ServiceFailedException(
|
|
|
+ "Cannot transition from Observer to Active");
|
|
|
+ }
|
|
|
state.setState(haContext, ACTIVE_STATE);
|
|
|
}
|
|
|
|
|
@@ -1783,6 +1793,11 @@ public class NameNode extends ReconfigurableBase implements
|
|
|
if (!haEnabled) {
|
|
|
throw new ServiceFailedException("HA for namenode is not enabled");
|
|
|
}
|
|
|
+ if (state == OBSERVER_STATE) {
|
|
|
+ // TODO: we may need to remove this when enabling failover for observer
|
|
|
+ throw new ServiceFailedException(
|
|
|
+ "Cannot transition from Observer to Standby");
|
|
|
+ }
|
|
|
state.setState(haContext, STANDBY_STATE);
|
|
|
}
|
|
|
|
|
@@ -1837,6 +1852,7 @@ public class NameNode extends ReconfigurableBase implements
|
|
|
|
|
|
@Override // NameNodeStatusMXBean
|
|
|
public String getState() {
|
|
|
+ // TODO: maybe we should return a different result for observer namenode?
|
|
|
String servStateStr = "";
|
|
|
HAServiceState servState = getServiceState();
|
|
|
if (null != servState) {
|
|
@@ -1937,7 +1953,8 @@ public class NameNode extends ReconfigurableBase implements
|
|
|
@Override
|
|
|
public void startStandbyServices() throws IOException {
|
|
|
try {
|
|
|
- namesystem.startStandbyServices(getConf());
|
|
|
+ namesystem.startStandbyServices(getConf(),
|
|
|
+ state == NameNode.OBSERVER_STATE);
|
|
|
} catch (Throwable t) {
|
|
|
doImmediateShutdown(t);
|
|
|
}
|
|
@@ -1984,6 +2001,9 @@ public class NameNode extends ReconfigurableBase implements
|
|
|
|
|
|
@Override
|
|
|
public boolean allowStaleReads() {
|
|
|
+ if (state == OBSERVER_STATE) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
return allowStaleStandbyReads;
|
|
|
}
|
|
|
|
|
@@ -1997,6 +2017,10 @@ public class NameNode extends ReconfigurableBase implements
|
|
|
return (state.equals(ACTIVE_STATE));
|
|
|
}
|
|
|
|
|
|
+ public boolean isObserverState() {
|
|
|
+ return state.equals(OBSERVER_STATE);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Returns whether the NameNode is completely started
|
|
|
*/
|