[ 
https://issues.apache.org/jira/browse/HDFS-6833?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14098270#comment-14098270
 ] 

Yongjun Zhang commented on HDFS-6833:
-------------------------------------

HI Shinichi,

Thanks for finding this issue and the patch work.

The reason for "blocks is missing in memory" is that the block is already 
removed from the memory map, and deletion of the physical block is to be done 
by FsDatasetAsyncDiskService, which is asynchrous operation. Though the 
DirecotryScanner is only scheduled to run every 6 hours (by default), the 
FsDatasetAsyncDiskService's block deletion could be so delayed that 
DirectoryScanner can see some blocks already removed from memory but still 
exist on disk. I worked out patch that can possibly helps the slowness of the 
disk removal, see HDFS-6788. However, I think this jira should help from a 
different perspective.

Overall the latest patch looks good to me. I have some comments here:

0. suggest to have a version number when you upload new patch.

1. suggest to change {{isDirectoryScanner()}} to {{isDirecotryScannerInited}}.

2, using List<Long> for deletingBlocks may not be efficient since you do search 
in 
{{public void removeDeletedBlocks(String bpid, List<Long> blockIds)}} which 
means sequential search. You might consider using HashSet.

3. DirectoryScanner.java. Not related to your change, but I saw it when looking 
at your change:
{code}
while (m < memReport.length && d < blockpoolReport.length) {
  Block memBlock = memReport[Math.min(m, memReport.length - 1)];
  ScanInfo info = blockpoolReport[Math.min(
      d, blockpoolReport.length - 1)];
{code}

Math.min(m, memReport.length - 1) is guaranteed to be m and 
Math.min(d, blockpoolReport.length - 1) is guaranteed to be d,
the code can be simplified to not call Math.min.

4. DirecotryScanner.java
{code}
while (d < blockpoolReport.length) {
  if (!dataset.isDeletingBlock(bpid, blockpoolReport[d].getBlockId())) {
    statsRecord.missingMemoryBlocks++;
    addDifference(diffRecord, statsRecord, blockpoolReport[d++]);
  } else {
    deletingBlockIds.add(blockpoolReport[d].getBlockId());
    d++;
  }
}
{code}
the "d++" logic can be extracted out to be shared by both branches.

Thanks.


> DirectoryScanner should not register a deleting block with memory of DataNode
> -----------------------------------------------------------------------------
>
>                 Key: HDFS-6833
>                 URL: https://issues.apache.org/jira/browse/HDFS-6833
>             Project: Hadoop HDFS
>          Issue Type: Bug
>          Components: datanode
>    Affects Versions: 3.0.0
>            Reporter: Shinichi Yamashita
>            Assignee: Shinichi Yamashita
>         Attachments: HDFS-6833.patch, HDFS-6833.patch, HDFS-6833.patch, 
> HDFS-6833.patch, HDFS-6833.patch
>
>
> When a block is deleted in DataNode, the following messages are usually 
> output.
> {code}
> 2014-08-07 17:53:11,606 INFO 
> org.apache.hadoop.hdfs.server.datanode.fsdataset.impl.FsDatasetAsyncDiskService:
>  Scheduling blk_1073741825_1001 file 
> /hadoop/data1/dfs/data/current/BP-1887080305-172.28.0.101-1407398838872/current/finalized/subdir0/subdir0/blk_1073741825
>  for deletion
> 2014-08-07 17:53:11,617 INFO 
> org.apache.hadoop.hdfs.server.datanode.fsdataset.impl.FsDatasetAsyncDiskService:
>  Deleted BP-1887080305-172.28.0.101-1407398838872 blk_1073741825_1001 file 
> /hadoop/data1/dfs/data/current/BP-1887080305-172.28.0.101-1407398838872/current/finalized/subdir0/subdir0/blk_1073741825
> {code}
> However, DirectoryScanner may be executed when DataNode deletes the block in 
> the current implementation. And the following messsages are output.
> {code}
> 2014-08-07 17:53:30,519 INFO 
> org.apache.hadoop.hdfs.server.datanode.fsdataset.impl.FsDatasetAsyncDiskService:
>  Scheduling blk_1073741825_1001 file 
> /hadoop/data1/dfs/data/current/BP-1887080305-172.28.0.101-1407398838872/current/finalized/subdir0/subdir0/blk_1073741825
>  for deletion
> 2014-08-07 17:53:31,426 INFO 
> org.apache.hadoop.hdfs.server.datanode.DirectoryScanner: BlockPool 
> BP-1887080305-172.28.0.101-1407398838872 Total blocks: 1, missing metadata 
> files:0, missing block files:0, missing blocks in memory:1, mismatched 
> blocks:0
> 2014-08-07 17:53:31,426 WARN 
> org.apache.hadoop.hdfs.server.datanode.fsdataset.impl.FsDatasetImpl: Added 
> missing block to memory FinalizedReplica, blk_1073741825_1001, FINALIZED
>   getNumBytes()     = 21230663
>   getBytesOnDisk()  = 21230663
>   getVisibleLength()= 21230663
>   getVolume()       = /hadoop/data1/dfs/data/current
>   getBlockFile()    = 
> /hadoop/data1/dfs/data/current/BP-1887080305-172.28.0.101-1407398838872/current/finalized/subdir0/subdir0/blk_1073741825
>   unlinked          =false
> 2014-08-07 17:53:31,531 INFO 
> org.apache.hadoop.hdfs.server.datanode.fsdataset.impl.FsDatasetAsyncDiskService:
>  Deleted BP-1887080305-172.28.0.101-1407398838872 blk_1073741825_1001 file 
> /hadoop/data1/dfs/data/current/BP-1887080305-172.28.0.101-1407398838872/current/finalized/subdir0/subdir0/blk_1073741825
> {code}
> Deleting block information is registered in DataNode's memory.
> And when DataNode sends a block report, NameNode receives wrong block 
> information.
> For example, when we execute recommission or change the number of 
> replication, NameNode may delete the right block as "ExcessReplicate" by this 
> problem.
> And "Under-Replicated Blocks" and "Missing Blocks" occur.
> When DataNode run DirectoryScanner, DataNode should not register a deleting 
> block.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

Reply via email to