何为健康检查

HDFS这类分布式存储系统,有个核心设计思想是硬件故障是常态,所以需要一些机制来在软件层面处理硬件故障问题。健康检查就是这些机制之一。
健康检查有个关键要点是检查期间尽可能不占用过多资源从而影响线上使用。
一共有三种检查机制:Block Scanner & Volume Scanner、Directory Scanner、Disk Checker。分别对磁盘、内存缓存、磁盘进行健康检查。下面将对三种机制分别讲解。

Block Scanner & Volume Scanner(块和卷扫描)

概述

dfs.datanode.data.dir配置的每个目录对应一个卷(Volume)。Block Scanner包含一组Volume Scanner,每个Volume Scanner起一个线程扫描某个卷。Volume Scanner有一个可疑块列表,会优先扫描可疑块。跟踪过去10分钟内扫描过的可疑块,防止重复扫描。
http://datanode:50070/blockScannerReport查看扫描情况

可疑列表

如果来自客户端或者另一个DataNode的IO请求报非网络的IOException错误(除了Socket超时、连接重置等),则把此块加入可以列表。

游标

scanner.cursor保存扫描进度。下次扫描读取之前的进度,不用从头开始。

提前唤醒

当一个块被标记为可疑,此时还没发生扫描,则提前唤醒扫描器。提前唤醒也会把整个DataNode扫描一遍。

对应配置

  • dfs.block.scanner.volume.bytes.per.second:每秒最多扫描的字节数默认1M,0表示禁用。
  • dfs.datanode.scan.period.hours:默认504小时3周 每次扫描间隔多长时间。设置0将使用默认值。负值表示禁用。如果设置过短,比扫描整个DataNode时间还短,设置就没有意义了,就会变成每时每刻都在扫描。
  • dfs.block.scanner.cursor.save.interval.ms:游标保存间隔默认十分钟。

坏块(corrupted block)处理

corrupted block会汇报给,NN调用namesystem.reportBadBlocks处理,会把block标记为corrupt,如果副本数满足一定条件,会把那个副本删掉。存活的副本数低于要求的副本数时,会触发副本复制。

Directory Scanners(目录扫描)

概述

主要检查并修复缓存和磁盘文件不一致。定期扫描块数据文件和块元数据文件。只检查finalized状态的块。

对应配置

  • dfs.datanode.directoryscan.throttle.limit.ms.per.sec:每秒限制运行多久,针对每个线程默认1000,即全程限制根本不执行。小于1000才开启。
  • dfs.datanode.directoryscan.threads:扫描器拥有最大并发线程数。默认为1。
  • dfs.datanode.directoryscan.interval:默认21600秒,即6小时。设置负值表示禁用。

Disk Checker(磁盘检查)

概述

一旦发现卷有问题,则停止该卷写入,并重新复制该卷的数据块,保证副本个数。

检查过程

创建线程检查。递归遍历finalized、tmp、rbw三个目录。检查子目录是否有创建新子目录和读写执行三权限。
由于已经有Block Scanner,即使没有Disk Checker,也会锁定磁盘全部块,并且为了减少IO对线上影响,所以只执行上诉轻量检查。
磁盘检查与上诉两种扫描不同,不是周期进行,而是按需进行。只在常规I/O操作(例如关闭块或元数据文件、目录扫描误等)期间捕捉到DataNode上的IOException时才运行。

对应配置

  • dfs.datanode.failed.volumes.allowed:故障卷大于该值,则DataNode失效。默认值为0。