HDFS Decommission改进设计
前言
在大型HDFS集群中,每天个别节点由于硬件问题导致掉线是常用发生的事情。因此很多时候,我们会对集群中的故障节点做下线操作,就是我们常说的Decommission操作。简单地来说,DataNode节点的Decommission操作在大规模体量的集群下是日常维护行为。因此Decommission行为会涉及到上面数据拷贝的情况,因此下线操作效率的好坏在一定程度上也会影响到集群的处理性能。现有HDFS Decommission方式从某些角度来看并不是高效的,本文笔者来聊聊社区目前在实现的另外一套Decommission的实现方式。
现有Decommission机制以及不足之处
这里首先我们需要有对现有Decommission机制有一个大致地了解,现有Decommission的流程可简单概括为如下:
- 将目标下线节点加入到下线列表中
- Decommission Monitor程序逐一处理待下线节点,将待下线节点中的块加入到副本队列内
- 另外Decommission Monitor程序还将检查待下线节点内的block副本数是否都已经达到预期大小,如果达到则标志节点下线成功,否则继续等待节点下线。
在以上3个步骤内,笔者省略了许多的细节实现描述,其中部分细节实现存在以下的问题:
- 每次新加节点进行decommission时,Monitor程序会持有较长时间的锁去处理下线节点中的所有的块。当目标下线节点中含有大量block块时,就有可能出现持NN锁时间过长的问题。
- HDFS副本队列replication queue在处理块时的方式是FIFO方式的。而下线节点在添加副本块时的顺序是按照一个接单一个个disk来添加的。这意味着会存在潜在一段时间的磁盘IO热点现象,当Monitor程序处理到某盘下的块数据的时候。
- 待下线节点以FIFO的顺序将其上的block块加入到replication queue中,这意味着第二个下线的节点块需要等待第一个节点的所有块被处理后,再执行第二个块,但其实后面的块和前面的块会存在重复块的情况,第一个块的速度往往比后续的块处理得要快。但在replication queue FIFO的模式下,decommission的速率实际上被限制了。
- 在现有Decommission逻辑下,Decommission Monitor程序会通过检查每个副本的replica块数来判断block块是否满足期待值,但其实这里会存在大部分重复块的检查,尤其当有大量块还需要replication出去的时候,剩余积压的待复制快将会在每次循环内被检查。更为关键的一点是,这些大量无效检查是需要持有FSN的写锁的。
Decommission新模型设计
针对上述现有Decommission机制的不足之处,社区目前在讨论实现新的一套机制。
新的Decommission过程将会如下步骤所示:
- 1)当节点被加入到待下线列表内时,扫描其上的块,保存到hashmap内,作为unprocessedBlocks,不做replication处理。
- 2)从unprocessedBlocks中移动一定数量的块到pendingRep内。然后将pendingRep中的块加入到replication queue内。检查副本块是否足够式,也只检查pendingRep里的副本数。
- 3)周期检查pendingRep里的块副本数是否足够,直到待下线节点decommission完成。
这里还有几点实现的细节来解决上述提到的Decommission低效执行的优化:
- 各个待下线节点的block块会以round-robin的节点方式加入到replication queue中,避免单节点的长时间处理阻塞后续下线节点。
- 在检查副本块时只检查小数量集的replica set,避免了大量的无效检查。
更多设计细节可以参考引用社区JIRA。
引用
[1].https://issues.apache.org/jira/browse/HDFS-14854 . Create improved decommission monitor implementation