HDFS-9412. getBlocks occupies FSLock and takes too long to complete. Contributed by He Tianyi.

This commit is contained in:
Walter Su 2016-04-18 09:28:02 +08:00
parent fdc46bfb37
commit 67523ffcf4
2 changed files with 23 additions and 2 deletions

View File

@ -305,6 +305,14 @@ public class BlockManager implements BlockStatsMXBean {
* processed again after aquiring lock again. * processed again after aquiring lock again.
*/ */
private int numBlocksPerIteration; private int numBlocksPerIteration;
/**
* Minimum size that a block can be sent to Balancer through getBlocks.
* And after HDFS-8824, the small blocks are unused anyway, so there's no
* point to send them to balancer.
*/
private long getBlocksMinBlockSize = -1;
/** /**
* Progress of the Reconstruction queues initialisation. * Progress of the Reconstruction queues initialisation.
*/ */
@ -414,6 +422,9 @@ public class BlockManager implements BlockStatsMXBean {
this.numBlocksPerIteration = conf.getInt( this.numBlocksPerIteration = conf.getInt(
DFSConfigKeys.DFS_BLOCK_MISREPLICATION_PROCESSING_LIMIT, DFSConfigKeys.DFS_BLOCK_MISREPLICATION_PROCESSING_LIMIT,
DFSConfigKeys.DFS_BLOCK_MISREPLICATION_PROCESSING_LIMIT_DEFAULT); DFSConfigKeys.DFS_BLOCK_MISREPLICATION_PROCESSING_LIMIT_DEFAULT);
this.getBlocksMinBlockSize = conf.getLongBytes(
DFSConfigKeys.DFS_BALANCER_GETBLOCKS_MIN_BLOCK_SIZE_KEY,
DFSConfigKeys.DFS_BALANCER_GETBLOCKS_MIN_BLOCK_SIZE_DEFAULT);
this.blockReportLeaseManager = new BlockReportLeaseManager(conf); this.blockReportLeaseManager = new BlockReportLeaseManager(conf);
bmSafeMode = new BlockManagerSafeMode(this, namesystem, haEnabled, conf); bmSafeMode = new BlockManagerSafeMode(this, namesystem, haEnabled, conf);
@ -1179,6 +1190,9 @@ public class BlockManager implements BlockStatsMXBean {
while(totalSize<size && iter.hasNext()) { while(totalSize<size && iter.hasNext()) {
curBlock = iter.next(); curBlock = iter.next();
if(!curBlock.isComplete()) continue; if(!curBlock.isComplete()) continue;
if (curBlock.getNumBytes() < getBlocksMinBlockSize) {
continue;
}
totalSize += addBlock(curBlock, results); totalSize += addBlock(curBlock, results);
} }
if(totalSize<size) { if(totalSize<size) {
@ -1186,6 +1200,9 @@ public class BlockManager implements BlockStatsMXBean {
for(int i=0; i<startBlock&&totalSize<size; i++) { for(int i=0; i<startBlock&&totalSize<size; i++) {
curBlock = iter.next(); curBlock = iter.next();
if(!curBlock.isComplete()) continue; if(!curBlock.isComplete()) continue;
if (curBlock.getNumBytes() < getBlocksMinBlockSize) {
continue;
}
totalSize += addBlock(curBlock, results); totalSize += addBlock(curBlock, results);
} }
} }

View File

@ -179,11 +179,15 @@ public class TestGetBlocks {
final int DEFAULT_BLOCK_SIZE = 1024; final int DEFAULT_BLOCK_SIZE = 1024;
CONF.setLong(DFSConfigKeys.DFS_BLOCK_SIZE_KEY, DEFAULT_BLOCK_SIZE); CONF.setLong(DFSConfigKeys.DFS_BLOCK_SIZE_KEY, DEFAULT_BLOCK_SIZE);
CONF.setLong(DFSConfigKeys.DFS_BALANCER_GETBLOCKS_MIN_BLOCK_SIZE_KEY,
DEFAULT_BLOCK_SIZE);
MiniDFSCluster cluster = new MiniDFSCluster.Builder(CONF).numDataNodes( MiniDFSCluster cluster = new MiniDFSCluster.Builder(CONF).numDataNodes(
REPLICATION_FACTOR).build(); REPLICATION_FACTOR).build();
try { try {
cluster.waitActive(); cluster.waitActive();
long fileLen = 2 * DEFAULT_BLOCK_SIZE; // the third block will not be visible to getBlocks
long fileLen = 2 * DEFAULT_BLOCK_SIZE + 1;
DFSTestUtil.createFile(cluster.getFileSystem(), new Path("/tmp.txt"), DFSTestUtil.createFile(cluster.getFileSystem(), new Path("/tmp.txt"),
fileLen, REPLICATION_FACTOR, 0L); fileLen, REPLICATION_FACTOR, 0L);
@ -196,7 +200,7 @@ public class TestGetBlocks {
DFSUtilClient.getNNAddress(CONF), CONF); DFSUtilClient.getNNAddress(CONF), CONF);
locatedBlocks = dfsclient.getNamenode() locatedBlocks = dfsclient.getNamenode()
.getBlockLocations("/tmp.txt", 0, fileLen).getLocatedBlocks(); .getBlockLocations("/tmp.txt", 0, fileLen).getLocatedBlocks();
assertEquals(2, locatedBlocks.size()); assertEquals(3, locatedBlocks.size());
notWritten = false; notWritten = false;
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
dataNodes = locatedBlocks.get(i).getLocations(); dataNodes = locatedBlocks.get(i).getLocations();