Hadoop分为存储和计算,即HDFS与mapred两大块。其中HDFS为hadoop的根基,知识点也很多。大家知道,block存放出于数据安全考虑,会有多个冗余备份(默认为3)。那么,这个副本又是如何存放,是根据什么策略呢?
考虑点主要有2点:
1.减小因datanode挂掉等原因导致数据丢失的不安全性
2.考虑数据传输,要在保证安全的情况下尽可能地使数据传输带宽更大
对于以下场景,可用带宽依次减少:
1)相同节点的进程
2)同机架不同节点
3)同一数据中心的不同机架上的节点
4)不同数据中心的节点
所以,hdfs采用机架感知策略,可以很智能地放置副本,在性能和适应力上权衡。策略如下:
第一个副本,在客户端相同的节点(如果客户端是集群外的一台机器,就随机算节点,但是系统会避免挑选太满或者太忙的节点)
第二个副本,放在不同机架(随机选择)的节点
第三个副本,放在与第二个副本同机架但是不同节点上。
其他更多副本(如果有的话),随机放置在集群节点,不过系统会尽可能避免在相同机架上放置太多副本。具体可看图:
那么放置好副本后,读取时又是采用什么策略呢?很简单:
客户端向namenode节点询问这个数据块存储在那些datanode节点上(告诉namenode需要的文件路径、读取文件的起始位置、读取文件的长度),namenode向该客户端返回它所要读取文件内容所在的位置——LocatedBlock对象(该对象包含对应的数据块所有副本所在的DataNode节点的位置信息),客户端接着就会依次从这些DataNode节点上读取该数据块,直到成功读取为止。
从性能角度出发,客户端应该选择从距离它最近的可用DataNode节点上读取需要的数据块,
那么,如何来计算客户端与DataNode节点之间的最小距离?
NameNode按照客户端与DataNode节点之间的距离进行排序,距客户端越近的DataNode节点越被放在LocatedBlock的前面,该算法的基本思路如下:
1.客户端优先从本地读取数据块(如果有的话);
2.如果1没有或者读取1失败,则客户端优先读取与客户端同机架上其他节点的副本(如果有的话);
3.如果1,2都没有,则随机选择一个DataNode节点作为优先节点。
这个计算距离的问题涉及到NetworkTopology,这种数据结构被NameNode节点用来形象的表示HDFS集群中所有DataNode节点的物理位置,自然这个优化工作就交由NameNode来处理了。