前言
我们都知道,HDFS在准备写文件块的时候,必须要做的一个步骤是要从集群内数以千计的节点中选择一个有效的节点作为待写入块的目标节点。那么这里何为”有效的节点”呢?指的是此节点内包含有快文件需要的Storage Type(存储类型)。比如说某block要求的类型是SSD,而当前选出的节点所有数据目录都是DISK的话,那这个节点就不是满足要求的节点,此轮选举就会被废弃,将选过的节点加入exclude列表,然后重新进行下一轮的选取。所以在这里,笔者想要只要聊聊其中选择效率的问题。这种策略其实是有一定问题的,比如说,集群内包含1000个节点,999个节点都是DISK类型,而只有1个节点是SSD类型的,那么要为SSD存储类型的文件选择目标节点,岂不是得经过好几轮选举了?因为目前的策略是每次随机挑选一个节点,然后拿来进行对比。当然如果节点完全是同构的,这当然没问题,但是如果出现多种异构型的节点,这种做法显然不够合理。本文笔者就来聊聊这个话题。
多异构存储的节点选择问题
多异构存储环境下的节点选择问题,并不是笔者直接发现的,而是源自于社区JIRA HDFS-11419(BlockPlacementPolicyDefault is choosing datanode in an inefficient way),大致提到的意思就是笔者在前言中所阐述的。归纳起来一句话,在一些集群环境结构十分特殊的情况下(比如集群存储类型比例完全不平衡时),选择偏少一方的存储类型节点的效率将会非常低。基于这个问题,社区提出了一种改进设想:能否将需要的存储类型传入到选择的节点方法内,提前筛选出包含有目标存储类型的节点,这样可以过滤掉大量无效的节点。换句话说,在这种设想中,选出来的节点是至少能满足块文件要求的候选节点。要想实现以上提到的方案,我们必须要对原始的NetworkTopology结构进行改造,加入StorageType的条件,社区也的确做了这样的改造,名为DFSNetworkTopology。
DFSNetworkTopology的实现
从DFSNetworkTopology这个名字我们能够看出,这是一个专属HDFS内部使用的新的Topology类。此类是NetworkTopology的子类,作者在其内部做的最大的改造是在每个逻辑节点内,添加了StorageType->Count这样的映射值关系。也就是说,在每个节点下,我可以知道此位置下,是否包含有我想要的存储类型的节点,而且我能知道到底有几个满足条件的节点。有了这样一个附加信息,我能够从根节点由上而下选出满足要求的节点。而之前默认的逻辑结构则是盲目的随机进行选择。
那么DFSNetworkTopology拓扑逻辑是如何构建StorageType->Count这样的映射信息的呢?归纳起来一句话:
当节点从拓扑逻辑中添加/移除的时候,获取此节点包含的StorageType信息,进行相应拓扑逻辑节点的map计数更新,往上更新直到根节点。
尽管说上面只用一句话进行了简单的概括,但真正的代码逻辑还是具有一定的复杂性的,里面涉及了比较多的树型结构的状态更新、维护等操作。感兴趣的读者可以自行前往HDFS-11419进行更进一步的学习。
DFSNetworkTopology的应用
既然新的基于存储策略计数值的拓扑逻辑已经实现了,是否意味着我们可以直接将DFSNetworkTopology应用到HDFS默认的副本放置策略中来进行节点的选择呢?答案是否定的。
之前上文中也提到过,DFSNetworkTopology是为了方便于多异构存储环境下而实现的,如果说集群不是异构的,那么原来的方式对于我们来说还是OK的,而且老方法相比较于新方法而言,在单次执行效率上而言,是要高于新方法的,,因为它不用考虑Storage Type因素的条件,随机选择一个就行了。所以在这里,一种比较好的做法是采取二者结合使用的方案。在HDFS-11535中,社区进行了这块内容的讨论。
首先有这么一个初始方案:根据集群所包含的Storage Type类型判断,如果集群内所有节点都是同一种Storage Type,也就是同构集群,则毫无疑问,沿用老的方法。否则,
使用新的选择节点的方法。
这个方法提出之后,笔者发现其中一个弊端,当其中如果某个Storage Type只有1%的比例时,这样也会被迫选择新方法,但是在此集群环境下,绝大多情况是比较适用于第一种情况的。
于是社区讨论提出了方案2.0版本,采用一种“2阶段选择”方案,什么意思呢?第一次采用老方法,就是随机选取方法,如果第一次不成功,则采用新方法。如果集群是同构的,则第一次方法肯定能选出节点来,否则不是的话,说明是存在异构的,则用新方法。这种方案的好处在于说能够同时利用了新,老方法共同的优点。而且也不会过于复杂。
事实上在2阶段选择方案提出之前,笔者曾提出过基于阈值的选择方案,这里的阈值指的是目标Storage Type在集群中的所占比,根据实际占比与阈值进行进行比较,从而来判断选择哪个topology下的方法。更多详细的讨论细节读者可以关注HDFS-11535。
DFSNetworkTopology的展望
目前对于这块的优化工作还在进行当中,笔者目前在HDFS-11530中正在将DFSNetworkTopology应用到HDFS内部的BlockPlacementPolicyDefault中,考虑到这个新的Topology还需要进行更多的压力测试和检验,目前打算采用的做法是将会用一个新的配置名来使用这个类,并将默认值先设置为老的NetworkTopology,等到了未来可以再变为DFSNetworkTopology。
参考资料
[1].HDFS-11419,BlockPlacementPolicyDefault is choosing datanode in an inefficient way, https://issues.apache.org/jira/browse/HDFS-11419
[2].HDFS-11530,Use HDFS specific network topology to choose datanode in BlockPlacementPolicyDefault,https://issues.apache.org/jira/browse/HDFS-11530
[3].HDFS-11535,Performance analysis of new DFSNetworkTopology#chooseRandom, https://issues.apache.org/jira/browse/HDFS-11535