[
https://issues.apache.org/jira/browse/HDFS-630?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12757019#action_12757019
]
Ruyue Ma commented on HDFS-630:
-------------------------------
Ruyue Ma added a comment - 20/Jul/09 11:32 PM
to: dhruba borthakur
> This is not related to HDFS-4379. let me explain why.
> The problem is actually related to HDFS-xxx. The namenode waits for 10
> minutes after losing heartbeats from a datanode to declare it dead. During
> this 10 minutes, the NN is free to choose the dead datanode as a possible
> replica for a newly allocated block.
> If during a write, the dfsclient sees that a block replica location for a
> newly allocated block is not-connectable, it re-requests the NN to get a
> fresh set of replica locations of the block. It tries this
> dfs.client.block.write.retries times (default 3), sleeping 6 seconds between
> each retry ( see DFSClient.nextBlockOutputStream). > This setting works well
> when you have a reasonable size cluster; if u have only 4 datanodes in the
> cluster, every retry picks the dead-datanode and the above logic bails out.
> One solution is to change the value of dfs.client.block.write.retries to a
> much much larger value, say 200 or so. Better still, increase the number of
> nodes in ur cluster.
Our modification: when getting block location from namenode, we give nn the
excluded datanodes. The list of dead datanodes is only for one block allocation.
+++ hadoop-new/src/hdfs/org/apache/hadoop/hdfs/DFSClient.java 2009-07-20
00:19:03.000000000 +0800
@@ -2734,6 +2734,7 @@
LocatedBlock lb = null;
boolean retry = false;
DatanodeInfo[] nodes;
+ DatanodeInfo[] exludedNodes = null;
int count = conf.getInt("dfs.client.block.write.retries", 3);
boolean success;
do {
@@ -2745,7 +2746,7 @@
success = false;
long startTime = System.currentTimeMillis();
* lb = locateFollowingBlock(startTime);
+ lb = locateFollowingBlock(startTime, exludedNodes);
block = lb.getBlock();
nodes = lb.getLocations();
@@ -2755,6 +2756,19 @@
success = createBlockOutputStream(nodes, clientName, false);
if (!success) {
+
+ LOG.info("Excluding node: " + nodes[errorIndex]);
+ // Mark datanode as excluded
+ DatanodeInfo errorNode = nodes[errorIndex];
+ if (exludedNodes != null) { + DatanodeInfo[] newExcludedNodes = new
DatanodeInfo[exludedNodes.length + 1]; + System.arraycopy(exludedNodes, 0,
newExcludedNodes, 0, exludedNodes.length); +
newExcludedNodes[exludedNodes.length] = errorNode; + exludedNodes =
newExcludedNodes; + } else {
+ exludedNodes = new DatanodeInfo[] { errorNode };
+ }
+
LOG.info("Abandoning block " + block);
namenode.abandonBlock(block, src, clientName);
[ Show » ]
Ruyue Ma added a comment - 20/Jul/09 11:32 PM to: dhruba borthakur > This is
not related to HDFS-4379. let me explain why. > The problem is actually related
to HDFS-xxx. The namenode waits for 10 minutes after losing heartbeats from a
datanode to declare it dead. During this 10 minutes, the NN is free to choose
the dead datanode as a possible replica for a newly allocated block. > If
during a write, the dfsclient sees that a block replica location for a newly
allocated block is not-connectable, it re-requests the NN to get a fresh set of
replica locations of the block. It tries this dfs.client.block.write.retries
times (default 3), sleeping 6 seconds between each retry ( see
DFSClient.nextBlockOutputStream). > This setting works well when you have a
reasonable size cluster; if u have only 4 datanodes in the cluster, every retry
picks the dead-datanode and the above logic bails out. > One solution is to
change the value of dfs.client.block.write.retries to a much much larger value,
say 200 or so. Better still, increase the number of nodes in ur cluster. Our
modification: when getting block location from namenode, we give nn the
excluded datanodes. The list of dead datanodes is only for one block
allocation. +++ hadoop-new/src/hdfs/org/apache/hadoop/hdfs/DFSClient.java
2009-07-20 00:19:03.000000000 +0800 @@ -2734,6 +2734,7 @@ LocatedBlock lb =
null; boolean retry = false; DatanodeInfo[] nodes; + DatanodeInfo[]
exludedNodes = null; int count = conf.getInt("dfs.client.block.write.retries",
3); boolean success; do { @@ -2745,7 +2746,7 @@ success = false; long startTime
= System.currentTimeMillis();
* lb = locateFollowingBlock(startTime); + lb =
locateFollowingBlock(startTime, exludedNodes); block = lb.getBlock(); nodes =
lb.getLocations();
@@ -2755,6 +2756,19 @@ success = createBlockOutputStream(nodes, clientName,
false); if (!success) { + + LOG.info("Excluding node: " + nodes[errorIndex]); +
// Mark datanode as excluded + DatanodeInfo errorNode = nodes[errorIndex]; + if
(exludedNodes != null) { + DatanodeInfo[] newExcludedNodes = new
DatanodeInfo[exludedNodes.length + 1]; + System.arraycopy(exludedNodes, 0,
newExcludedNodes, 0, exludedNodes.length); +
newExcludedNodes[exludedNodes.length] = errorNode; + exludedNodes =
newExcludedNodes; + } else { + exludedNodes = new DatanodeInfo[] { errorNode };
+ } + LOG.info("Abandoning block " + block); namenode.abandonBlock(block, src,
clientName);
[ Permlink | « Hide ]
dhruba borthakur added a comment - 22/Jul/09 07:14 AM
Hi Ruyue, your option of excluding specific datanodes (specified by the client)
sounds reasonable. This might help in the case of network partitioning where a
specific client loses access to a set of datanodes while the datanode is alive
and well and is able to send heartbeats to the namenode. Can you pl create a
separate JIRA for your prosposed fix and attach your patch there? Thanks.
[ Show » ]
dhruba borthakur added a comment - 22/Jul/09 07:14 AM Hi Ruyue, your option of
excluding specific datanodes (specified by the client) sounds reasonable. This
might help in the case of network partitioning where a specific client loses
access to a set of datanodes while the datanode is alive and well and is able
to send heartbeats to the namenode. Can you pl create a separate JIRA for your
prosposed fix and attach your patch there? Thanks.
> In DFSOutputStream.nextBlockOutputStream(), the client can exclude specific
> datanodes when locating the next block.
> -------------------------------------------------------------------------------------------------------------------
>
> Key: HDFS-630
> URL: https://issues.apache.org/jira/browse/HDFS-630
> Project: Hadoop HDFS
> Issue Type: New Feature
> Components: hdfs client
> Affects Versions: 0.20.1, 0.21.0
> Reporter: Ruyue Ma
> Assignee: Ruyue Ma
> Priority: Minor
> Fix For: 0.21.0
>
>
> created from hdfs-200.
> If during a write, the dfsclient sees that a block replica location for a
> newly allocated block is not-connectable, it re-requests the NN to get a
> fresh set of replica locations of the block. It tries this
> dfs.client.block.write.retries times (default 3), sleeping 6 seconds between
> each retry ( see DFSClient.nextBlockOutputStream).
> This setting works well when you have a reasonable size cluster; if u have
> few datanodes in the cluster, every retry maybe pick the dead-datanode and
> the above logic bails out.
> Our solution: when getting block location from namenode, we give nn the
> excluded datanodes. The list of dead datanodes is only for one block
> allocation.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.