Author: rangadi
Date: Wed Jul 16 12:14:37 2008
New Revision: 677380
URL: http://svn.apache.org/viewvc?rev=677380&view=rev
Log:
HADOOP-3707. NameNode keeps a count of number of blocks scheduled
to be written to a datanode and uses it to avoid allocating more
blocks than a datanode can hold. (rangadi)
Added:
hadoop/core/branches/branch-0.18/src/test/org/apache/hadoop/dfs/TestBlocksScheduledCounter.java
Modified:
hadoop/core/branches/branch-0.18/CHANGES.txt
hadoop/core/branches/branch-0.18/src/hdfs/org/apache/hadoop/dfs/DatanodeDescriptor.java
hadoop/core/branches/branch-0.18/src/hdfs/org/apache/hadoop/dfs/FSNamesystem.java
hadoop/core/branches/branch-0.18/src/hdfs/org/apache/hadoop/dfs/ReplicationTargetChooser.java
hadoop/core/branches/branch-0.18/src/webapps/dfs/dfshealth.jsp
Modified: hadoop/core/branches/branch-0.18/CHANGES.txt
URL:
http://svn.apache.org/viewvc/hadoop/core/branches/branch-0.18/CHANGES.txt?rev=677380&r1=677379&r2=677380&view=diff
==============================================================================
--- hadoop/core/branches/branch-0.18/CHANGES.txt (original)
+++ hadoop/core/branches/branch-0.18/CHANGES.txt Wed Jul 16 12:14:37 2008
@@ -762,6 +762,10 @@
BUG FIXES
+ HADOOP-3707. NameNode keeps a count of number of blocks scheduled
+ to be written to a datanode and uses it to avoid allocating more
+ blocks than a datanode can hold. (rangadi)
+
HADOOP-3760. Fix a bug with HDFS file close() mistakenly introduced
by HADOOP-3681. (Lohit Vijayarenu via rangadi)
Modified:
hadoop/core/branches/branch-0.18/src/hdfs/org/apache/hadoop/dfs/DatanodeDescriptor.java
URL:
http://svn.apache.org/viewvc/hadoop/core/branches/branch-0.18/src/hdfs/org/apache/hadoop/dfs/DatanodeDescriptor.java?rev=677380&r1=677379&r2=677380&view=diff
==============================================================================
---
hadoop/core/branches/branch-0.18/src/hdfs/org/apache/hadoop/dfs/DatanodeDescriptor.java
(original)
+++
hadoop/core/branches/branch-0.18/src/hdfs/org/apache/hadoop/dfs/DatanodeDescriptor.java
Wed Jul 16 12:14:37 2008
@@ -93,6 +93,16 @@
boolean processedBlockReport = false;
+ /* Variables for maintaning number of blocks scheduled to be written to
+ * this datanode. This count is approximate and might be slightly higger
+ * in case of errors (e.g. datanode does not report if an error occurs
+ * while writing the block).
+ */
+ private int currApproxBlocksScheduled = 0;
+ private int prevApproxBlocksScheduled = 0;
+ private long lastBlocksScheduledRollTime = 0;
+ private static final int BLOCKS_SCHEDULED_ROLL_INTERVAL = 600*1000; //10min
+
/** Default constructor */
public DatanodeDescriptor() {}
@@ -211,6 +221,7 @@
this.remaining = remaining;
this.lastUpdate = System.currentTimeMillis();
this.xceiverCount = xceiverCount;
+ rollBlocksScheduled(lastUpdate);
}
/**
@@ -396,4 +407,43 @@
this.hostName = Text.readString(in);
setAdminState(WritableUtils.readEnum(in, AdminStates.class));
}
+
+ /**
+ * @return Approximate number of blocks currently scheduled to be written
+ * to this datanode.
+ */
+ public int getBlocksScheduled() {
+ return currApproxBlocksScheduled + prevApproxBlocksScheduled;
+ }
+
+ /**
+ * Increments counter for number of blocks scheduled.
+ */
+ void incBlocksScheduled() {
+ currApproxBlocksScheduled++;
+ }
+
+ /**
+ * Decrements counter for number of blocks scheduled.
+ */
+ void decBlocksScheduled() {
+ if (prevApproxBlocksScheduled > 0) {
+ prevApproxBlocksScheduled--;
+ } else if (currApproxBlocksScheduled > 0) {
+ currApproxBlocksScheduled--;
+ }
+ // its ok if both counters are zero.
+ }
+
+ /**
+ * Adjusts curr and prev number of blocks scheduled every few minutes.
+ */
+ private void rollBlocksScheduled(long now) {
+ if ((now - lastBlocksScheduledRollTime) >
+ BLOCKS_SCHEDULED_ROLL_INTERVAL) {
+ prevApproxBlocksScheduled = currApproxBlocksScheduled;
+ currApproxBlocksScheduled = 0;
+ lastBlocksScheduledRollTime = now;
+ }
+ }
}
Modified:
hadoop/core/branches/branch-0.18/src/hdfs/org/apache/hadoop/dfs/FSNamesystem.java
URL:
http://svn.apache.org/viewvc/hadoop/core/branches/branch-0.18/src/hdfs/org/apache/hadoop/dfs/FSNamesystem.java?rev=677380&r1=677379&r2=677380&view=diff
==============================================================================
---
hadoop/core/branches/branch-0.18/src/hdfs/org/apache/hadoop/dfs/FSNamesystem.java
(original)
+++
hadoop/core/branches/branch-0.18/src/hdfs/org/apache/hadoop/dfs/FSNamesystem.java
Wed Jul 16 12:14:37 2008
@@ -1130,6 +1130,10 @@
// allocate new block record block locations in INode.
newBlock = allocateBlock(src, pendingFile);
pendingFile.setTargets(targets);
+
+ for (DatanodeDescriptor dn : targets) {
+ dn.incBlocksScheduled();
+ }
}
// Create next block
@@ -2334,6 +2338,10 @@
srcNode.addBlockToBeReplicated(block, targets);
scheduledReplicationCount++;
+ for (DatanodeDescriptor dn : targets) {
+ dn.incBlocksScheduled();
+ }
+
// Move the block-replication into a "pending" state.
// The reason we use 'pending' is so we can retry
// replications that fail after an appropriate amount of time.
@@ -2500,6 +2508,9 @@
getReplication(timedOutItems[i]));
}
}
+ /* If we know the the target datanodes where the replication timedout,
+ * we could invoke decBlocksScheduled() on it. Its ok for now.
+ */
}
}
@@ -3119,6 +3130,9 @@
throw new DisallowedDatanodeException(node);
}
+ // decrement number of blocks scheduled to this datanode.
+ node.decBlocksScheduled();
+
// get the deletion hint node
DatanodeDescriptor delHintNode = null;
if(delHint!=null && delHint.length()!=0) {
Modified:
hadoop/core/branches/branch-0.18/src/hdfs/org/apache/hadoop/dfs/ReplicationTargetChooser.java
URL:
http://svn.apache.org/viewvc/hadoop/core/branches/branch-0.18/src/hdfs/org/apache/hadoop/dfs/ReplicationTargetChooser.java?rev=677380&r1=677379&r2=677380&view=diff
==============================================================================
---
hadoop/core/branches/branch-0.18/src/hdfs/org/apache/hadoop/dfs/ReplicationTargetChooser.java
(original)
+++
hadoop/core/branches/branch-0.18/src/hdfs/org/apache/hadoop/dfs/ReplicationTargetChooser.java
Wed Jul 16 12:14:37 2008
@@ -398,8 +398,10 @@
return false;
}
+ long remaining = node.getRemaining() -
+ (node.getBlocksScheduled() * blockSize);
// check the remaining capacity of the target machine
- if (blockSize* FSConstants.MIN_BLOCKS_FOR_WRITE>node.getRemaining()) {
+ if (blockSize* FSConstants.MIN_BLOCKS_FOR_WRITE>remaining) {
logr.debug("Node "+NodeBase.getPath(node)+
" is not chosen because the node does not have enough space");
return false;
Added:
hadoop/core/branches/branch-0.18/src/test/org/apache/hadoop/dfs/TestBlocksScheduledCounter.java
URL:
http://svn.apache.org/viewvc/hadoop/core/branches/branch-0.18/src/test/org/apache/hadoop/dfs/TestBlocksScheduledCounter.java?rev=677380&view=auto
==============================================================================
---
hadoop/core/branches/branch-0.18/src/test/org/apache/hadoop/dfs/TestBlocksScheduledCounter.java
(added)
+++
hadoop/core/branches/branch-0.18/src/test/org/apache/hadoop/dfs/TestBlocksScheduledCounter.java
Wed Jul 16 12:14:37 2008
@@ -0,0 +1,63 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.dfs;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.dfs.DFSClient.DFSOutputStream;
+import org.apache.hadoop.fs.FSDataOutputStream;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+
+import junit.framework.TestCase;
+
+/**
+ * This class tests DatanodeDescriptor.getBlocksScheduled() at the
+ * NameNode. This counter is supposed to keep track of blocks currently
+ * scheduled to a datanode.
+ */
+public class TestBlocksScheduledCounter extends TestCase {
+
+ public void testBlocksScheduledCounter() throws IOException {
+
+ MiniDFSCluster cluster = new MiniDFSCluster(new Configuration(), 1,
+ true, null);
+ cluster.waitActive();
+ FileSystem fs = cluster.getFileSystem();
+
+ //open a file an write a few bytes:
+ FSDataOutputStream out = fs.create(new Path("/testBlockScheduledCounter"));
+ for (int i=0; i<1024; i++) {
+ out.write(i);
+ }
+ // flush to make sure a block is allocated.
+ ((DFSOutputStream)(out.getWrappedStream())).sync();
+
+ ArrayList<DatanodeDescriptor> dnList = new ArrayList<DatanodeDescriptor>();
+ cluster.getNameNode().namesystem.DFSNodesStatus(dnList, dnList);
+ DatanodeDescriptor dn = dnList.get(0);
+
+ assertEquals(1, dn.getBlocksScheduled());
+
+ // close the file and the counter should go to zero.
+ out.close();
+ assertEquals(0, dn.getBlocksScheduled());
+ }
+}
Modified: hadoop/core/branches/branch-0.18/src/webapps/dfs/dfshealth.jsp
URL:
http://svn.apache.org/viewvc/hadoop/core/branches/branch-0.18/src/webapps/dfs/dfshealth.jsp?rev=677380&r1=677379&r2=677380&view=diff
==============================================================================
--- hadoop/core/branches/branch-0.18/src/webapps/dfs/dfshealth.jsp (original)
+++ hadoop/core/branches/branch-0.18/src/webapps/dfs/dfshealth.jsp Wed Jul 16
12:14:37 2008
@@ -106,7 +106,8 @@
JspHelper.percentageGraph( (int)Double.parseDouble(percentUsed) ,
100) +
"<td class=\"size\">" +
FsShell.limitDecimalTo2(d.getRemaining()*1.0/diskBytes) +
- "<td class=\"blocks\">" + d.numBlocks() + "\n");
+ "<td title=" + "\"blocks scheduled : " + d.getBlocksScheduled()
+
+ "\" class=\"blocks\">" + d.numBlocks() + "\n");
}
public void generateDFSHealthReport(JspWriter out,