You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by ha...@apache.org on 2009/04/07 20:02:25 UTC
svn commit: r762882 - in /hadoop/core/branches/branch-0.20: ./ CHANGES.txt
src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java
src/hdfs/org/apache/hadoop/hdfs/server/namenode/UnderReplicatedBlocks.java
Author: hairong
Date: Tue Apr 7 18:02:24 2009
New Revision: 762882
URL: http://svn.apache.org/viewvc?rev=762882&view=rev
Log:
Merge -r 762878:762879 from trunk to move the change of HADOOP-3810 to branch 0.20.
Modified:
hadoop/core/branches/branch-0.20/ (props changed)
hadoop/core/branches/branch-0.20/CHANGES.txt (contents, props changed)
hadoop/core/branches/branch-0.20/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java
hadoop/core/branches/branch-0.20/src/hdfs/org/apache/hadoop/hdfs/server/namenode/UnderReplicatedBlocks.java
Propchange: hadoop/core/branches/branch-0.20/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Apr 7 18:02:24 2009
@@ -1,2 +1,2 @@
/hadoop/core/branches/branch-0.19:713112
-/hadoop/core/trunk:727001,727117,727191,727212,727217,727228,727255,727869,728187,729052,729987,732385,732572,732613,732777,732838,732869,733887,734870,734916,736426,738328,738697,740077,740157,741703,741762,743745,743816,743892,744894,745180,746010,746206,746227,746233,746274,746338,746902-746903,746925,746944,746968,746970,747279,747289,747802,748084,748090,748783,749262,749318,749863,750533,752073,752609,752834,752836,752913,752932,753112-753113,753346,754645,754847,754927,755035,755226,755348,755370,755418,755426,755790,755905,755938,755960,755986,755998,756352,757448,757624,757849,758156,759398,759932,760502,760783,761046,761482,761632,762216
+/hadoop/core/trunk:727001,727117,727191,727212,727217,727228,727255,727869,728187,729052,729987,732385,732572,732613,732777,732838,732869,733887,734870,734916,736426,738328,738697,740077,740157,741703,741762,743745,743816,743892,744894,745180,746010,746206,746227,746233,746274,746338,746902-746903,746925,746944,746968,746970,747279,747289,747802,748084,748090,748783,749262,749318,749863,750533,752073,752609,752834,752836,752913,752932,753112-753113,753346,754645,754847,754927,755035,755226,755348,755370,755418,755426,755790,755905,755938,755960,755986,755998,756352,757448,757624,757849,758156,759398,759932,760502,760783,761046,761482,761632,762216,762879
Modified: hadoop/core/branches/branch-0.20/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/core/branches/branch-0.20/CHANGES.txt?rev=762882&r1=762881&r2=762882&view=diff
==============================================================================
--- hadoop/core/branches/branch-0.20/CHANGES.txt (original)
+++ hadoop/core/branches/branch-0.20/CHANGES.txt Tue Apr 7 18:02:24 2009
@@ -851,6 +851,9 @@
HADOOP-5548. Add synchronization for JobTracker methods in RecoveryManager.
(Amareshwari Sriramadasu via sharad)
+ HADOOP-3810. NameNode seems unstable on a cluster with little space left.
+ (hairong)
+
Release 0.19.2 - Unreleased
BUG FIXES
Propchange: hadoop/core/branches/branch-0.20/CHANGES.txt
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Apr 7 18:02:24 2009
@@ -1,3 +1,3 @@
/hadoop/core/branches/branch-0.18/CHANGES.txt:727226
/hadoop/core/branches/branch-0.19/CHANGES.txt:713112
-/hadoop/core/trunk/CHANGES.txt:727001,727117,727191,727212,727228,727255,727869,728187,729052,729987,732385,732572,732613,732777,732838,732869,733887,734870,734916,735082,736426,738602,738697,739416,740077,740157,741703,741762,743296,743745,743816,743892,744894,745180,745268,746010,746193,746206,746227,746233,746274,746902-746903,746925,746944,746968,746970,747279,747289,747802,748084,748090,748783,749262,749318,749863,750533,752073,752514,752555,752590,752609,752834,752836,752913,752932,753112-753113,753346,754645,754847,754927,755035,755226,755348,755370,755418,755426,755790,755905,755938,755986,755998,756352,757448,757624,757849,758156,759398,759932,760502,760783,761046,761482,761632,762216
+/hadoop/core/trunk/CHANGES.txt:727001,727117,727191,727212,727228,727255,727869,728187,729052,729987,732385,732572,732613,732777,732838,732869,733887,734870,734916,735082,736426,738602,738697,739416,740077,740157,741703,741762,743296,743745,743816,743892,744894,745180,745268,746010,746193,746206,746227,746233,746274,746902-746903,746925,746944,746968,746970,747279,747289,747802,748084,748090,748783,749262,749318,749863,750533,752073,752514,752555,752590,752609,752834,752836,752913,752932,753112-753113,753346,754645,754847,754927,755035,755226,755348,755370,755418,755426,755790,755905,755938,755986,755998,756352,757448,757624,757849,758156,759398,759932,760502,760783,761046,761482,761632,762216,762879
Modified: hadoop/core/branches/branch-0.20/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java
URL: http://svn.apache.org/viewvc/hadoop/core/branches/branch-0.20/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java?rev=762882&r1=762881&r2=762882&view=diff
==============================================================================
--- hadoop/core/branches/branch-0.20/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java (original)
+++ hadoop/core/branches/branch-0.20/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java Tue Apr 7 18:02:24 2009
@@ -39,6 +39,7 @@
import org.apache.hadoop.net.NetworkTopology;
import org.apache.hadoop.net.ScriptBasedMapping;
import org.apache.hadoop.hdfs.server.namenode.LeaseManager.Lease;
+import org.apache.hadoop.hdfs.server.namenode.UnderReplicatedBlocks.BlockIterator;
import org.apache.hadoop.hdfs.server.protocol.BlocksWithLocations;
import org.apache.hadoop.hdfs.server.protocol.BlocksWithLocations.BlockWithLocations;
import org.apache.hadoop.hdfs.server.protocol.DatanodeCommand;
@@ -2375,30 +2376,57 @@
*
* @return number of blocks scheduled for replication during this iteration.
*/
- private synchronized int computeReplicationWork(
+ private int computeReplicationWork(
int blocksToProcess) throws IOException {
- int scheduledReplicationCount = 0;
+ // Choose the blocks to be replicated
+ List<List<Block>> blocksToReplicate =
+ chooseUnderReplicatedBlocks(blocksToProcess);
+ // replicate blocks
+ int scheduledReplicationCount = 0;
+ for (int i=0; i<blocksToReplicate.size(); i++) {
+ for(Block block : blocksToReplicate.get(i)) {
+ if (computeReplicationWorkForBlock(block, i)) {
+ scheduledReplicationCount++;
+ }
+ }
+ }
+ return scheduledReplicationCount;
+ }
+
+ /** Get a list of block lists to be replicated
+ * The index of block lists represents the
+ *
+ * @param blocksToProcess
+ * @return Return a list of block lists to be replicated.
+ * The block list index represents its replication priority.
+ */
+ synchronized List<List<Block>> chooseUnderReplicatedBlocks(int blocksToProcess) {
+ // initialize data structure for the return value
+ List<List<Block>> blocksToReplicate =
+ new ArrayList<List<Block>>(UnderReplicatedBlocks.LEVEL);
+ for (int i=0; i<UnderReplicatedBlocks.LEVEL; i++) {
+ blocksToReplicate.add(new ArrayList<Block>());
+ }
+
synchronized(neededReplications) {
if (neededReplications.size() == 0) {
missingBlocksInCurIter = 0;
missingBlocksInPrevIter = 0;
+ return blocksToReplicate;
}
- // # of blocks to process equals either twice the number of live
- // data-nodes or the number of under-replicated blocks whichever is less
- blocksToProcess = Math.min(blocksToProcess, neededReplications.size());
- if(blocksToProcess == 0)
- return scheduledReplicationCount;
-
+
// Go through all blocks that need replications.
- // Select source and target nodes for replication.
- Iterator<Block> neededReplicationsIterator = neededReplications.iterator();
+ BlockIterator neededReplicationsIterator = neededReplications.iterator();
// skip to the first unprocessed block, which is at replIndex
for(int i=0; i < replIndex && neededReplicationsIterator.hasNext(); i++) {
neededReplicationsIterator.next();
}
- // process blocks
- for(int blkCnt = 0; blkCnt < blocksToProcess; blkCnt++, replIndex++) {
+ // # of blocks to process equals either twice the number of live
+ // data-nodes or the number of under-replicated blocks whichever is less
+ blocksToProcess = Math.min(blocksToProcess, neededReplications.size());
+
+ for (int blkCnt = 0; blkCnt < blocksToProcess; blkCnt++, replIndex++) {
if( ! neededReplicationsIterator.hasNext()) {
// start from the beginning
replIndex = 0;
@@ -2413,52 +2441,100 @@
}
Block block = neededReplicationsIterator.next();
-
+ int priority = neededReplicationsIterator.getPriority();
+ if (priority < 0 || priority >= blocksToReplicate.size()) {
+ LOG.warn("Unexpected replication priority: " + priority + " " + block);
+ } else {
+ blocksToReplicate.get(priority).add(block);
+ }
+ } // end for
+ } // end synchronized
+ return blocksToReplicate;
+ }
+
+ /** Replicate a block
+ *
+ * @param block block to be replicated
+ * @param priority a hint of its priority in the neededReplication queue
+ * @return if the block gets replicated or not
+ */
+ boolean computeReplicationWorkForBlock(Block block, int priority) {
+ int requiredReplication, numEffectiveReplicas;
+ List<DatanodeDescriptor> containingNodes;
+ DatanodeDescriptor srcNode;
+
+ synchronized (this) {
+ synchronized (neededReplications) {
// block should belong to a file
INodeFile fileINode = blocksMap.getINode(block);
// abandoned block or block reopened for append
if(fileINode == null || fileINode.isUnderConstruction()) {
- neededReplicationsIterator.remove(); // remove from neededReplications
+ neededReplications.remove(block, priority); // remove from neededReplications
replIndex--;
- continue;
+ return false;
}
- int requiredReplication = fileINode.getReplication();
+ requiredReplication = fileINode.getReplication();
// get a source data-node
- List<DatanodeDescriptor> containingNodes =
- new ArrayList<DatanodeDescriptor>();
+ containingNodes = new ArrayList<DatanodeDescriptor>();
NumberReplicas numReplicas = new NumberReplicas();
- DatanodeDescriptor srcNode =
- chooseSourceDatanode(block, containingNodes, numReplicas);
-
+ srcNode = chooseSourceDatanode(block, containingNodes, numReplicas);
if ((numReplicas.liveReplicas() + numReplicas.decommissionedReplicas())
<= 0) {
missingBlocksInCurIter++;
}
if(srcNode == null) // block can not be replicated from any node
- continue;
+ return false;
// do not schedule more if enough replicas is already pending
- int numEffectiveReplicas = numReplicas.liveReplicas() +
+ numEffectiveReplicas = numReplicas.liveReplicas() +
pendingReplications.getNumReplicas(block);
if(numEffectiveReplicas >= requiredReplication) {
- neededReplicationsIterator.remove(); // remove from neededReplications
+ neededReplications.remove(block, priority); // remove from neededReplications
+ replIndex--;
+ NameNode.stateChangeLog.info("BLOCK* "
+ + "Removing block " + block
+ + " from neededReplications as it has enough replicas.");
+ return false;
+ }
+ }
+ }
+
+ // choose replication targets: NOT HODING THE GLOBAL LOCK
+ DatanodeDescriptor targets[] = replicator.chooseTarget(
+ requiredReplication - numEffectiveReplicas,
+ srcNode, containingNodes, null, block.getNumBytes());
+ if(targets.length == 0)
+ return false;
+
+ synchronized (this) {
+ synchronized (neededReplications) {
+ // Recheck since global lock was released
+ // block should belong to a file
+ INodeFile fileINode = blocksMap.getINode(block);
+ // abandoned block or block reopened for append
+ if(fileINode == null || fileINode.isUnderConstruction()) {
+ neededReplications.remove(block, priority); // remove from neededReplications
+ replIndex--;
+ return false;
+ }
+ requiredReplication = fileINode.getReplication();
+
+ // do not schedule more if enough replicas is already pending
+ NumberReplicas numReplicas = countNodes(block);
+ numEffectiveReplicas = numReplicas.liveReplicas() +
+ pendingReplications.getNumReplicas(block);
+ if(numEffectiveReplicas >= requiredReplication) {
+ neededReplications.remove(block, priority); // remove from neededReplications
replIndex--;
NameNode.stateChangeLog.info("BLOCK* "
+ "Removing block " + block
+ " from neededReplications as it has enough replicas.");
- continue;
+ return false;
}
- // choose replication targets
- DatanodeDescriptor targets[] = replicator.chooseTarget(
- requiredReplication - numEffectiveReplicas,
- srcNode, containingNodes, null, block.getNumBytes());
- if(targets.length == 0)
- continue;
// Add block to the to be replicated list
srcNode.addBlockToBeReplicated(block, targets);
- scheduledReplicationCount++;
for (DatanodeDescriptor dn : targets) {
dn.incBlocksScheduled();
@@ -2471,10 +2547,10 @@
NameNode.stateChangeLog.debug(
"BLOCK* block " + block
+ " is moved from neededReplications to pendingReplications");
-
+
// remove from neededReplications
if(numEffectiveReplicas + targets.length >= requiredReplication) {
- neededReplicationsIterator.remove(); // remove from neededReplications
+ neededReplications.remove(block, priority); // remove from neededReplications
replIndex--;
}
if (NameNode.stateChangeLog.isInfoEnabled()) {
@@ -2493,7 +2569,8 @@
}
}
}
- return scheduledReplicationCount;
+
+ return true;
}
/**
Modified: hadoop/core/branches/branch-0.20/src/hdfs/org/apache/hadoop/hdfs/server/namenode/UnderReplicatedBlocks.java
URL: http://svn.apache.org/viewvc/hadoop/core/branches/branch-0.20/src/hdfs/org/apache/hadoop/hdfs/server/namenode/UnderReplicatedBlocks.java?rev=762882&r1=762881&r2=762882&view=diff
==============================================================================
--- hadoop/core/branches/branch-0.20/src/hdfs/org/apache/hadoop/hdfs/server/namenode/UnderReplicatedBlocks.java (original)
+++ hadoop/core/branches/branch-0.20/src/hdfs/org/apache/hadoop/hdfs/server/namenode/UnderReplicatedBlocks.java Tue Apr 7 18:02:24 2009
@@ -26,7 +26,7 @@
* Blocks have only one replicas has the highest
*/
class UnderReplicatedBlocks implements Iterable<Block> {
- private static final int LEVEL = 3;
+ static final int LEVEL = 3;
private List<TreeSet<Block>> priorityQueues = new ArrayList<TreeSet<Block>>();
/* constructor */
@@ -129,7 +129,7 @@
}
/* remove a block from a under replication queue given a priority*/
- private boolean remove(Block block, int priLevel) {
+ boolean remove(Block block, int priLevel) {
if(priLevel >= 0 && priLevel < LEVEL
&& priorityQueues.get(priLevel).remove(block)) {
NameNode.stateChangeLog.debug(
@@ -182,12 +182,15 @@
}
}
- /* return a iterator of all the under replication blocks */
- public synchronized Iterator<Block> iterator() {
- return new Iterator<Block>() {
+ /* return an iterator of all the under replication blocks */
+ public synchronized BlockIterator iterator() {
+ return new BlockIterator();
+ }
+
+ class BlockIterator implements Iterator<Block> {
private int level;
private List<Iterator<Block>> iterators = new ArrayList<Iterator<Block>>();
-
+ BlockIterator()
{
level=0;
for(int i=0; i<LEVEL; i++) {
@@ -214,6 +217,9 @@
public void remove() {
iterators.get(level).remove();
}
+
+ public int getPriority() {
+ return level;
};
}
}