HDFS-16865. The source path is always / after RBF proxied the complete, addBlock and getAdditionalDatanode RPC. (#5200). Contributed by ZanderXu.
Reviewed-by: Inigo Goiri <inigoiri@apache.org> Signed-off-by: Ayush Saxena <ayushsaxena@apache.org>
This commit is contained in:
parent
cda9863d54
commit
4ee92efb73
@ -483,12 +483,10 @@ public class RouterClientProtocol implements ClientProtocol {
|
|||||||
new RemoteParam(), clientName, previous, excludedNodes, fileId,
|
new RemoteParam(), clientName, previous, excludedNodes, fileId,
|
||||||
favoredNodes, addBlockFlags);
|
favoredNodes, addBlockFlags);
|
||||||
|
|
||||||
|
final List<RemoteLocation> locations = rpcServer.getLocationsForPath(src, true);
|
||||||
if (previous != null) {
|
if (previous != null) {
|
||||||
return rpcClient.invokeSingle(previous, method, LocatedBlock.class);
|
return rpcClient.invokeSingle(previous, method, locations, LocatedBlock.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<RemoteLocation> locations =
|
|
||||||
rpcServer.getLocationsForPath(src, true);
|
|
||||||
// TODO verify the excludedNodes and favoredNodes are acceptable to this NN
|
// TODO verify the excludedNodes and favoredNodes are acceptable to this NN
|
||||||
return rpcClient.invokeSequential(
|
return rpcClient.invokeSequential(
|
||||||
locations, method, LocatedBlock.class, null);
|
locations, method, LocatedBlock.class, null);
|
||||||
@ -513,12 +511,11 @@ public class RouterClientProtocol implements ClientProtocol {
|
|||||||
new RemoteParam(), fileId, blk, existings, existingStorageIDs, excludes,
|
new RemoteParam(), fileId, blk, existings, existingStorageIDs, excludes,
|
||||||
numAdditionalNodes, clientName);
|
numAdditionalNodes, clientName);
|
||||||
|
|
||||||
|
final List<RemoteLocation> locations = rpcServer.getLocationsForPath(src, false);
|
||||||
if (blk != null) {
|
if (blk != null) {
|
||||||
return rpcClient.invokeSingle(blk, method, LocatedBlock.class);
|
return rpcClient.invokeSingle(blk, method, locations, LocatedBlock.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<RemoteLocation> locations =
|
|
||||||
rpcServer.getLocationsForPath(src, false);
|
|
||||||
return rpcClient.invokeSequential(
|
return rpcClient.invokeSequential(
|
||||||
locations, method, LocatedBlock.class, null);
|
locations, method, LocatedBlock.class, null);
|
||||||
}
|
}
|
||||||
@ -532,7 +529,9 @@ public class RouterClientProtocol implements ClientProtocol {
|
|||||||
new Class<?>[] {ExtendedBlock.class, long.class, String.class,
|
new Class<?>[] {ExtendedBlock.class, long.class, String.class,
|
||||||
String.class},
|
String.class},
|
||||||
b, fileId, new RemoteParam(), holder);
|
b, fileId, new RemoteParam(), holder);
|
||||||
rpcClient.invokeSingle(b, method);
|
|
||||||
|
final List<RemoteLocation> locations = rpcServer.getLocationsForPath(src, false);
|
||||||
|
rpcClient.invokeSingle(b, method, locations, Void.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -545,12 +544,11 @@ public class RouterClientProtocol implements ClientProtocol {
|
|||||||
long.class},
|
long.class},
|
||||||
new RemoteParam(), clientName, last, fileId);
|
new RemoteParam(), clientName, last, fileId);
|
||||||
|
|
||||||
|
final List<RemoteLocation> locations = rpcServer.getLocationsForPath(src, true);
|
||||||
if (last != null) {
|
if (last != null) {
|
||||||
return rpcClient.invokeSingle(last, method, Boolean.class);
|
return rpcClient.invokeSingle(last, method, locations, Boolean.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<RemoteLocation> locations =
|
|
||||||
rpcServer.getLocationsForPath(src, true);
|
|
||||||
// Complete can return true/false, so don't expect a result
|
// Complete can return true/false, so don't expect a result
|
||||||
return rpcClient.invokeSequential(locations, method, Boolean.class, null);
|
return rpcClient.invokeSequential(locations, method, Boolean.class, null);
|
||||||
}
|
}
|
||||||
@ -580,7 +578,7 @@ public class RouterClientProtocol implements ClientProtocol {
|
|||||||
new Class<?>[] {String.class, ExtendedBlock.class, ExtendedBlock.class,
|
new Class<?>[] {String.class, ExtendedBlock.class, ExtendedBlock.class,
|
||||||
DatanodeID[].class, String[].class},
|
DatanodeID[].class, String[].class},
|
||||||
clientName, oldBlock, newBlock, newNodes, newStorageIDs);
|
clientName, oldBlock, newBlock, newNodes, newStorageIDs);
|
||||||
rpcClient.invokeSingle(oldBlock, method);
|
rpcClient.invokeSingleBlockPool(oldBlock.getBlockPoolId(), method);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -848,6 +848,26 @@ public class RouterRpcClient {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to get the remote location whose bpId is same with the input bpId from the input locations.
|
||||||
|
* @param locations the input RemoteLocations.
|
||||||
|
* @param bpId the input bpId.
|
||||||
|
* @return the remote location whose bpId is same with the input.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private RemoteLocation getLocationWithBPID(List<RemoteLocation> locations, String bpId)
|
||||||
|
throws IOException {
|
||||||
|
String nsId = getNameserviceForBlockPoolId(bpId);
|
||||||
|
for (RemoteLocation l : locations) {
|
||||||
|
if (l.getNameserviceId().equals(nsId)) {
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG.debug("Can't find remote location for the {} from {}", bpId, locations);
|
||||||
|
return new RemoteLocation(nsId, "/", "/");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invokes a ClientProtocol method. Determines the target nameservice via a
|
* Invokes a ClientProtocol method. Determines the target nameservice via a
|
||||||
* provided block.
|
* provided block.
|
||||||
@ -857,13 +877,15 @@ public class RouterRpcClient {
|
|||||||
*
|
*
|
||||||
* @param block Block used to determine appropriate nameservice.
|
* @param block Block used to determine appropriate nameservice.
|
||||||
* @param method The remote method and parameters to invoke.
|
* @param method The remote method and parameters to invoke.
|
||||||
|
* @param locations The remote locations will be used.
|
||||||
|
* @param clazz – Class for the return type.
|
||||||
* @return The result of invoking the method.
|
* @return The result of invoking the method.
|
||||||
* @throws IOException If the invoke generated an error.
|
* @throws IOException If the invoke generated an error.
|
||||||
*/
|
*/
|
||||||
public Object invokeSingle(final ExtendedBlock block, RemoteMethod method)
|
public <T> T invokeSingle(final ExtendedBlock block, RemoteMethod method,
|
||||||
throws IOException {
|
final List<RemoteLocation> locations, Class<T> clazz) throws IOException {
|
||||||
String bpId = block.getBlockPoolId();
|
RemoteLocation location = getLocationWithBPID(locations, block.getBlockPoolId());
|
||||||
return invokeSingleBlockPool(bpId, method);
|
return invokeSingle(location, method, clazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,6 +73,7 @@ import org.apache.hadoop.ipc.RemoteException;
|
|||||||
import org.apache.hadoop.ipc.StandbyException;
|
import org.apache.hadoop.ipc.StandbyException;
|
||||||
import org.apache.hadoop.test.GenericTestUtils;
|
import org.apache.hadoop.test.GenericTestUtils;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.slf4j.event.Level;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The RPC interface of the {@link getRouter()} implemented by
|
* The RPC interface of the {@link getRouter()} implemented by
|
||||||
@ -275,6 +276,14 @@ public class TestRouterRpcMultiDestination extends TestRouterRpc {
|
|||||||
@Test
|
@Test
|
||||||
public void testPreviousBlockNotNull()
|
public void testPreviousBlockNotNull()
|
||||||
throws IOException, URISyntaxException {
|
throws IOException, URISyntaxException {
|
||||||
|
final GenericTestUtils.LogCapturer stateChangeLog =
|
||||||
|
GenericTestUtils.LogCapturer.captureLogs(NameNode.stateChangeLog);
|
||||||
|
GenericTestUtils.setLogLevel(NameNode.stateChangeLog, Level.DEBUG);
|
||||||
|
|
||||||
|
final GenericTestUtils.LogCapturer nameNodeLog =
|
||||||
|
GenericTestUtils.LogCapturer.captureLogs(NameNode.LOG);
|
||||||
|
GenericTestUtils.setLogLevel(NameNode.LOG, Level.DEBUG);
|
||||||
|
|
||||||
final FederationRPCMetrics metrics = getRouterContext().
|
final FederationRPCMetrics metrics = getRouterContext().
|
||||||
getRouter().getRpcServer().getRPCMetrics();
|
getRouter().getRpcServer().getRPCMetrics();
|
||||||
final ClientProtocol clientProtocol = getRouterProtocol();
|
final ClientProtocol clientProtocol = getRouterProtocol();
|
||||||
@ -305,6 +314,7 @@ public class TestRouterRpcMultiDestination extends TestRouterRpc {
|
|||||||
long proxyNumAddBlock = metrics.getProcessingOps();
|
long proxyNumAddBlock = metrics.getProcessingOps();
|
||||||
assertEquals(2, proxyNumAddBlock - proxyNumCreate);
|
assertEquals(2, proxyNumAddBlock - proxyNumCreate);
|
||||||
|
|
||||||
|
stateChangeLog.clearOutput();
|
||||||
// Add a block via router and previous block is not null.
|
// Add a block via router and previous block is not null.
|
||||||
LocatedBlock blockTwo = clientProtocol.addBlock(
|
LocatedBlock blockTwo = clientProtocol.addBlock(
|
||||||
testPath, clientName, blockOne.getBlock(), null,
|
testPath, clientName, blockOne.getBlock(), null,
|
||||||
@ -312,7 +322,9 @@ public class TestRouterRpcMultiDestination extends TestRouterRpc {
|
|||||||
assertNotNull(blockTwo);
|
assertNotNull(blockTwo);
|
||||||
long proxyNumAddBlock2 = metrics.getProcessingOps();
|
long proxyNumAddBlock2 = metrics.getProcessingOps();
|
||||||
assertEquals(1, proxyNumAddBlock2 - proxyNumAddBlock);
|
assertEquals(1, proxyNumAddBlock2 - proxyNumAddBlock);
|
||||||
|
assertTrue(stateChangeLog.getOutput().contains("BLOCK* getAdditionalBlock: " + testPath));
|
||||||
|
|
||||||
|
nameNodeLog.clearOutput();
|
||||||
// Get additionalDatanode via router and block is not null.
|
// Get additionalDatanode via router and block is not null.
|
||||||
DatanodeInfo[] exclusions = DatanodeInfo.EMPTY_ARRAY;
|
DatanodeInfo[] exclusions = DatanodeInfo.EMPTY_ARRAY;
|
||||||
LocatedBlock newBlock = clientProtocol.getAdditionalDatanode(
|
LocatedBlock newBlock = clientProtocol.getAdditionalDatanode(
|
||||||
@ -322,12 +334,15 @@ public class TestRouterRpcMultiDestination extends TestRouterRpc {
|
|||||||
assertNotNull(newBlock);
|
assertNotNull(newBlock);
|
||||||
long proxyNumAdditionalDatanode = metrics.getProcessingOps();
|
long proxyNumAdditionalDatanode = metrics.getProcessingOps();
|
||||||
assertEquals(1, proxyNumAdditionalDatanode - proxyNumAddBlock2);
|
assertEquals(1, proxyNumAdditionalDatanode - proxyNumAddBlock2);
|
||||||
|
assertTrue(nameNodeLog.getOutput().contains("getAdditionalDatanode: src=" + testPath));
|
||||||
|
|
||||||
|
stateChangeLog.clearOutput();
|
||||||
// Complete the file via router and last block is not null.
|
// Complete the file via router and last block is not null.
|
||||||
clientProtocol.complete(testPath, clientName,
|
clientProtocol.complete(testPath, clientName,
|
||||||
newBlock.getBlock(), status.getFileId());
|
newBlock.getBlock(), status.getFileId());
|
||||||
long proxyNumComplete = metrics.getProcessingOps();
|
long proxyNumComplete = metrics.getProcessingOps();
|
||||||
assertEquals(1, proxyNumComplete - proxyNumAdditionalDatanode);
|
assertEquals(1, proxyNumComplete - proxyNumAdditionalDatanode);
|
||||||
|
assertTrue(stateChangeLog.getOutput().contains("DIR* NameSystem.completeFile: " + testPath));
|
||||||
} finally {
|
} finally {
|
||||||
clientProtocol.delete(testPath, true);
|
clientProtocol.delete(testPath, true);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user