|
@@ -132,7 +132,7 @@ public class RouterRpcClient {
|
|
|
Pattern.compile("\\tat (.*)\\.(.*)\\((.*):(\\d*)\\)");
|
|
|
|
|
|
/** Fairness manager to control handlers assigned per NS. */
|
|
|
- private RouterRpcFairnessPolicyController routerRpcFairnessPolicyController;
|
|
|
+ private volatile RouterRpcFairnessPolicyController routerRpcFairnessPolicyController;
|
|
|
private Map<String, LongAdder> rejectedPermitsPerNs = new ConcurrentHashMap<>();
|
|
|
private Map<String, LongAdder> acceptedPermitsPerNs = new ConcurrentHashMap<>();
|
|
|
|
|
@@ -451,7 +451,8 @@ public class RouterRpcClient {
|
|
|
* @throws StandbyException If all Namenodes are in Standby.
|
|
|
* @throws IOException If it cannot invoke the method.
|
|
|
*/
|
|
|
- private Object invokeMethod(
|
|
|
+ @VisibleForTesting
|
|
|
+ public Object invokeMethod(
|
|
|
final UserGroupInformation ugi,
|
|
|
final List<? extends FederationNamenodeContext> namenodes,
|
|
|
final Class<?> protocol, final Method method, final Object... params)
|
|
@@ -828,7 +829,8 @@ public class RouterRpcClient {
|
|
|
public Object invokeSingle(final String nsId, RemoteMethod method)
|
|
|
throws IOException {
|
|
|
UserGroupInformation ugi = RouterRpcServer.getRemoteUser();
|
|
|
- acquirePermit(nsId, ugi, method);
|
|
|
+ RouterRpcFairnessPolicyController controller = getRouterRpcFairnessPolicyController();
|
|
|
+ acquirePermit(nsId, ugi, method, controller);
|
|
|
try {
|
|
|
List<? extends FederationNamenodeContext> nns =
|
|
|
getNamenodesForNameservice(nsId);
|
|
@@ -838,7 +840,7 @@ public class RouterRpcClient {
|
|
|
Object[] params = method.getParams(loc);
|
|
|
return invokeMethod(ugi, nns, proto, m, params);
|
|
|
} finally {
|
|
|
- releasePermit(nsId, ugi, method);
|
|
|
+ releasePermit(nsId, ugi, method, controller);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -989,6 +991,7 @@ public class RouterRpcClient {
|
|
|
Class<T> expectedResultClass, Object expectedResultValue)
|
|
|
throws IOException {
|
|
|
|
|
|
+ RouterRpcFairnessPolicyController controller = getRouterRpcFairnessPolicyController();
|
|
|
final UserGroupInformation ugi = RouterRpcServer.getRemoteUser();
|
|
|
final Method m = remoteMethod.getMethod();
|
|
|
List<IOException> thrownExceptions = new ArrayList<>();
|
|
@@ -996,7 +999,7 @@ public class RouterRpcClient {
|
|
|
// Invoke in priority order
|
|
|
for (final RemoteLocationContext loc : locations) {
|
|
|
String ns = loc.getNameserviceId();
|
|
|
- acquirePermit(ns, ugi, remoteMethod);
|
|
|
+ acquirePermit(ns, ugi, remoteMethod, controller);
|
|
|
List<? extends FederationNamenodeContext> namenodes =
|
|
|
getNamenodesForNameservice(ns);
|
|
|
try {
|
|
@@ -1031,7 +1034,7 @@ public class RouterRpcClient {
|
|
|
"Unexpected exception proxying API " + e.getMessage(), e);
|
|
|
thrownExceptions.add(ioe);
|
|
|
} finally {
|
|
|
- releasePermit(ns, ugi, remoteMethod);
|
|
|
+ releasePermit(ns, ugi, remoteMethod, controller);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1356,7 +1359,8 @@ public class RouterRpcClient {
|
|
|
// Shortcut, just one call
|
|
|
T location = locations.iterator().next();
|
|
|
String ns = location.getNameserviceId();
|
|
|
- acquirePermit(ns, ugi, method);
|
|
|
+ RouterRpcFairnessPolicyController controller = getRouterRpcFairnessPolicyController();
|
|
|
+ acquirePermit(ns, ugi, method, controller);
|
|
|
final List<? extends FederationNamenodeContext> namenodes =
|
|
|
getNamenodesForNameservice(ns);
|
|
|
try {
|
|
@@ -1369,7 +1373,7 @@ public class RouterRpcClient {
|
|
|
// Localize the exception
|
|
|
throw processException(ioe, location);
|
|
|
} finally {
|
|
|
- releasePermit(ns, ugi, method);
|
|
|
+ releasePermit(ns, ugi, method, controller);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1419,7 +1423,8 @@ public class RouterRpcClient {
|
|
|
this.router.getRouterClientMetrics().incInvokedConcurrent(m);
|
|
|
}
|
|
|
|
|
|
- acquirePermit(CONCURRENT_NS, ugi, method);
|
|
|
+ RouterRpcFairnessPolicyController controller = getRouterRpcFairnessPolicyController();
|
|
|
+ acquirePermit(CONCURRENT_NS, ugi, method, controller);
|
|
|
try {
|
|
|
List<Future<Object>> futures = null;
|
|
|
if (timeOutMs > 0) {
|
|
@@ -1477,7 +1482,7 @@ public class RouterRpcClient {
|
|
|
throw new IOException(
|
|
|
"Unexpected error while invoking API " + ex.getMessage(), ex);
|
|
|
} finally {
|
|
|
- releasePermit(CONCURRENT_NS, ugi, method);
|
|
|
+ releasePermit(CONCURRENT_NS, ugi, method, controller);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1558,13 +1563,14 @@ public class RouterRpcClient {
|
|
|
* @param nsId Identifier of the block pool.
|
|
|
* @param ugi UserGroupIdentifier associated with the user.
|
|
|
* @param m Remote method that needs to be invoked.
|
|
|
+ * @param controller fairness policy controller to acquire permit from
|
|
|
* @throws IOException If permit could not be acquired for the nsId.
|
|
|
*/
|
|
|
- private void acquirePermit(
|
|
|
- final String nsId, final UserGroupInformation ugi, final RemoteMethod m)
|
|
|
+ private void acquirePermit(final String nsId, final UserGroupInformation ugi,
|
|
|
+ final RemoteMethod m, RouterRpcFairnessPolicyController controller)
|
|
|
throws IOException {
|
|
|
- if (routerRpcFairnessPolicyController != null) {
|
|
|
- if (!routerRpcFairnessPolicyController.acquirePermit(nsId)) {
|
|
|
+ if (controller != null) {
|
|
|
+ if (!controller.acquirePermit(nsId)) {
|
|
|
// Throw StandByException,
|
|
|
// Clients could fail over and try another router.
|
|
|
if (rpcMonitor != null) {
|
|
@@ -1585,21 +1591,20 @@ public class RouterRpcClient {
|
|
|
/**
|
|
|
* Release permit for specific nsId after processing against downstream
|
|
|
* nsId is completed.
|
|
|
- *
|
|
|
- * @param nsId Identifier of the block pool.
|
|
|
+ * @param nsId Identifier of the block pool.
|
|
|
* @param ugi UserGroupIdentifier associated with the user.
|
|
|
* @param m Remote method that needs to be invoked.
|
|
|
+ * @param controller fairness policy controller to release permit from
|
|
|
*/
|
|
|
- private void releasePermit(
|
|
|
- final String nsId, final UserGroupInformation ugi, final RemoteMethod m) {
|
|
|
- if (routerRpcFairnessPolicyController != null) {
|
|
|
- routerRpcFairnessPolicyController.releasePermit(nsId);
|
|
|
+ private void releasePermit(final String nsId, final UserGroupInformation ugi,
|
|
|
+ final RemoteMethod m, RouterRpcFairnessPolicyController controller) {
|
|
|
+ if (controller != null) {
|
|
|
+ controller.releasePermit(nsId);
|
|
|
LOG.trace("Permit released for ugi: {} for method: {}", ugi,
|
|
|
m.getMethodName());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- @VisibleForTesting
|
|
|
public RouterRpcFairnessPolicyController
|
|
|
getRouterRpcFairnessPolicyController() {
|
|
|
return routerRpcFairnessPolicyController;
|
|
@@ -1622,4 +1627,35 @@ public class RouterRpcClient {
|
|
|
return acceptedPermitsPerNs.containsKey(ns) ?
|
|
|
acceptedPermitsPerNs.get(ns).longValue() : 0L;
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Refreshes/changes the fairness policy controller implementation if possible
|
|
|
+ * and returns the controller class name
|
|
|
+ * @param conf Configuration
|
|
|
+ * @return New controller class name if successfully refreshed, else old controller class name
|
|
|
+ */
|
|
|
+ public synchronized String refreshFairnessPolicyController(Configuration conf) {
|
|
|
+ RouterRpcFairnessPolicyController newController;
|
|
|
+ try {
|
|
|
+ newController = FederationUtil.newFairnessPolicyController(conf);
|
|
|
+ } catch (RuntimeException e) {
|
|
|
+ LOG.error("Failed to create router fairness policy controller", e);
|
|
|
+ return getCurrentFairnessPolicyControllerClassName();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (newController != null) {
|
|
|
+ if (routerRpcFairnessPolicyController != null) {
|
|
|
+ routerRpcFairnessPolicyController.shutdown();
|
|
|
+ }
|
|
|
+ routerRpcFairnessPolicyController = newController;
|
|
|
+ }
|
|
|
+ return getCurrentFairnessPolicyControllerClassName();
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getCurrentFairnessPolicyControllerClassName() {
|
|
|
+ if (routerRpcFairnessPolicyController != null) {
|
|
|
+ return routerRpcFairnessPolicyController.getClass().getCanonicalName();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
}
|