[
https://issues.apache.org/jira/browse/HDFS-5922?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13897137#comment-13897137
]
Aaron T. Myers commented on HDFS-5922:
--------------------------------------
In the heartbeat thread in BPServiceActor, we have the following:
{code}
if (waitTime > 0 && pendingReceivedRequests == 0) {
try {
pendingIncrementalBRperStorage.wait(waitTime);
{code}
This means that if for some reason the value of {{pendingReceivedRequests}}
permanently stays positive then we will never sleep in the heartbeat thread.
The question, then, is what can cause this value to stay positive.
I believe the issue is that in
{{BPServiceActor#addPendingReplicationBlockInfo}} we might not increase the
size of the {{PerStoragePendingIncrementalBR}} if there is already an entry for
a given block in there:
{code}
// Make sure another entry for the same block is first removed.
// There may only be one such entry.
for (Map.Entry<String, PerStoragePendingIncrementalBR> entry :
pendingIncrementalBRperStorage.entrySet()) {
if (entry.getValue().removeBlockInfo(bInfo)) {
break;
}
}
getIncrementalBRMapForStorage(storageUuid).putBlockInfo(bInfo);
{code}
But in {{BPServiceActor#notifyNamenodeBlockImmediately}} we will always
increment {{pendingReceivedRequests}} regardless of whether or not there was
already an entry for the block:
{code}
void notifyNamenodeBlockImmediately(
ReceivedDeletedBlockInfo bInfo, String storageUuid) {
synchronized (pendingIncrementalBRperStorage) {
addPendingReplicationBlockInfo(bInfo, storageUuid);
pendingReceivedRequests++;
pendingIncrementalBRperStorage.notifyAll();
}
}
{code}
Then, in {{BPServiceActor#reportReceivedDeletedBlocks}}, we will only subtract
the number of blocks that are actually in the
{{PerStoragePendingIncrementalBR}} from {{pendingReceivedRequests}}:
{code}
ReceivedDeletedBlockInfo[] rdbi = perStorageMap.dequeueBlockInfos();
pendingReceivedRequests =
(pendingReceivedRequests > rdbi.length ?
(pendingReceivedRequests - rdbi.length) : 0);
{code}
This means that if we ever call
{{BPServiceActor#notifyNamenodeBlockImmediately}} twice without calling
{{BPServiceActor#reportReceivedDeletedBlocks}} in between, we will have
{{pendingReceivedRequests}} at 2, but then only subtract 1 from it.
[~andrew.wang] also pointed out offline that it is perhaps incorrect to be
subtracting the number of _deleted_ blocks from {{pendingReceivedRequests}} in
{{BPServiceActor#reportReceivedDeletedBlocks}}, but the result of that is
somewhat less serious, since in that case the worst case is just that we send a
somewhat delayed IBR.
> DN heartbeat thread can get stuck in tight loop
> -----------------------------------------------
>
> Key: HDFS-5922
> URL: https://issues.apache.org/jira/browse/HDFS-5922
> Project: Hadoop HDFS
> Issue Type: Bug
> Components: datanode
> Affects Versions: 2.3.0
> Reporter: Aaron T. Myers
>
> We saw an issue recently on a test cluster where one of the DN threads was
> consuming 100% of a single CPU. Running jstack indicated that it was the DN
> heartbeat thread. I believe I've tracked down the cause to a bug in the
> accounting around the value of {{pendingReceivedRequests}}.
> More details in the first comment.
--
This message was sent by Atlassian JIRA
(v6.1.5#6160)