This is an automated email from the ASF dual-hosted git repository.
tasanuma pushed a commit to branch branch-3.3
in repository https://gitbox.apache.org/repos/asf/hadoop.git
The following commit(s) were added to refs/heads/branch-3.3 by this push:
new 6349597 HDFS-16268. Balancer stuck when moving striped blocks due to
NPE (#3546)
6349597 is described below
commit 63495978b29a20b4db439394430f0cce697b8210
Author: LeonGao <[email protected]>
AuthorDate: Wed Oct 13 18:14:03 2021 -0700
HDFS-16268. Balancer stuck when moving striped blocks due to NPE (#3546)
(cherry picked from commit 7279fe8661d694fb0775f4f84333c1317f4e6899)
---
.../hadoop/hdfs/server/balancer/Dispatcher.java | 20 +++++++++----
.../hadoop/hdfs/server/balancer/TestBalancer.java | 33 ++++++++++++++++++++++
2 files changed, 48 insertions(+), 5 deletions(-)
diff --git
a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/balancer/Dispatcher.java
b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/balancer/Dispatcher.java
index e19fbeb..5411b5c 100644
---
a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/balancer/Dispatcher.java
+++
b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/balancer/Dispatcher.java
@@ -239,7 +239,7 @@ public class Dispatcher {
private DDatanode proxySource;
private StorageGroup target;
- private PendingMove(Source source, StorageGroup target) {
+ PendingMove(Source source, StorageGroup target) {
this.source = source;
this.target = target;
}
@@ -280,12 +280,18 @@ public class Dispatcher {
/**
* @return true if the given block is good for the tentative move.
*/
- private boolean markMovedIfGoodBlock(DBlock block, StorageType
targetStorageType) {
+ boolean markMovedIfGoodBlock(DBlock block, StorageType targetStorageType) {
synchronized (block) {
synchronized (movedBlocks) {
if (isGoodBlockCandidate(source, target, targetStorageType, block)) {
if (block instanceof DBlockStriped) {
reportedBlock = ((DBlockStriped) block).getInternalBlock(source);
+ if (reportedBlock == null) {
+ LOG.info(
+ "No striped internal block on source {}, block {}.
Skipping.",
+ source, block);
+ return false;
+ }
} else {
reportedBlock = block;
}
@@ -497,7 +503,7 @@ public class Dispatcher {
this.cellSize = cellSize;
}
- public DBlock getInternalBlock(StorageGroup storage) {
+ DBlock getInternalBlock(StorageGroup storage) {
int idxInLocs = locations.indexOf(storage);
if (idxInLocs == -1) {
return null;
@@ -516,7 +522,11 @@ public class Dispatcher {
@Override
public long getNumBytes(StorageGroup storage) {
- return getInternalBlock(storage).getNumBytes();
+ DBlock block = getInternalBlock(storage);
+ if (block == null) {
+ return 0;
+ }
+ return block.getNumBytes();
}
}
@@ -1305,7 +1315,7 @@ public class Dispatcher {
* 2. the block does not have a replica/internalBlock on the target;
* 3. doing the move does not reduce the number of racks that the block has
*/
- private boolean isGoodBlockCandidate(StorageGroup source, StorageGroup
target,
+ boolean isGoodBlockCandidate(StorageGroup source, StorageGroup target,
StorageType targetStorageType, DBlock block) {
if (source.equals(target)) {
return false;
diff --git
a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/balancer/TestBalancer.java
b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/balancer/TestBalancer.java
index f253b1e..3c624cd 100644
---
a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/balancer/TestBalancer.java
+++
b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/balancer/TestBalancer.java
@@ -41,11 +41,16 @@ import static
org.apache.hadoop.hdfs.DFSConfigKeys.DFS_WEB_AUTHENTICATION_KERBER
import org.apache.hadoop.hdfs.protocol.ErasureCodingPolicy;
import org.junit.AfterClass;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyLong;
import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
import java.io.File;
import java.io.IOException;
@@ -1614,11 +1619,39 @@ public class TestBalancer {
// verify locations of striped blocks
locatedBlocks = client.getBlockLocations(fileName, 0, fileLen);
StripedFileTestUtil.verifyLocatedStripedBlocks(locatedBlocks, groupSize);
+
+ // Test handling NPE with striped blocks
+ testNullStripedBlocks(conf);
+
} finally {
cluster.shutdown();
}
}
+ private void testNullStripedBlocks(Configuration conf) throws IOException {
+ NameNodeConnector nnc = NameNodeConnector.newNameNodeConnectors(
+ DFSUtil.getInternalNsRpcUris(conf),
+ Balancer.class.getSimpleName(), Balancer.BALANCER_ID_PATH, conf,
+ BalancerParameters.DEFAULT.getMaxIdleIteration()).get(0);
+ Dispatcher dispatcher = new Dispatcher(nnc, Collections.emptySet(),
+ Collections.<String> emptySet(), 1, 1, 0,
+ 1, 1, conf);
+ Dispatcher spyDispatcher = spy(dispatcher);
+ Dispatcher.PendingMove move = spyDispatcher.new PendingMove(
+ mock(Dispatcher.Source.class),
+ mock(Dispatcher.DDatanode.StorageGroup.class));
+ Dispatcher.DBlockStriped block = mock(Dispatcher.DBlockStriped.class);
+
+ doReturn(null).when(block).getInternalBlock(any());
+ doReturn(true)
+ .when(spyDispatcher)
+ .isGoodBlockCandidate(any(), any(), any(), any());
+
+ when(move.markMovedIfGoodBlock(block, DEFAULT)).thenCallRealMethod();
+
+ assertFalse(move.markMovedIfGoodBlock(block, DEFAULT));
+ }
+
/**
* Test Balancer runs fine when logging in with a keytab in kerberized env.
* Reusing testUnknownDatanode here for basic functionality testing.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]