洋哥YARN和HDFS实践系列大作,这是第三篇,前面两篇分别是:
Yarn【label-based scheduling】实战总结(一)
Yarn【label-based scheduling】实战总结(二)

1.1 机架感知(RackAwareness)概述
通常,大型Hadoop集群会分布在很多机架上。在这种情况下,

-- 希望不同节点之间的通信能够尽量发生在同一个机架之内,而不是跨机架。

-- 为了提高容错能力,名称节点会尽可能把数据块的副本放到多个机架上。

综合考虑这两点的基础上Hadoop设计了机架感知功能。

1.1.1 外在脚本实现机架感知
HDFS不能够自动判断集群中各个datanode的网络拓扑情况。这种机架感知需要topology.script.file.name属性定义的可执行文件(或者脚本)来实现,文件提供了IP->rackid的翻译。NameNode通过这个得到集群中各个datanode机器的rackid。如果topology.script.file.name没有设定,则每个IP都会翻译成/default-rack。

为了获取机架id,可以写一个小脚本来定义IP(或者DNS名),并把想要的机架id打印到标准输出stdout。

这个脚本必须要在配置文件hadoop-site.xml里通过属性’topology.script.file.name’来指定。

例如:

用Python语言编写的脚本范例:

1.1.2 内部Java类实现机架感知
该处采用配置topology.node.switch.mapping.impl来实现机架感知,需在core-site.xml配置文件中加入以下配置项:

<property>

<name>topology.node.switch.mapping.impl</name>

<value>com.dmp.hadoop.cluster.topology.JavaTestBasedMapping</value>

</property>

还需编写一个JAVA类,一个示例如下所示:

public class JavaTestBasedMapping implements DNSToSwitchMapping {

   //key:ip value:rack   private staticConcurrentHashMap<String,String> cache = new ConcurrentHashMap<String,String>();   static {          //rack0 16          cache.put("192.168.5.116","/ht_dc/rack0");          cache.put("192.168.5.117","/ht_dc/rack0");          cache.put("192.168.5.118","/ht_dc/rack0");          cache.put("192.168.5.120","/ht_dc/rack0");          cache.put("192.168.5.121","/ht_dc/rack0");          cache.put("host116","/ht_dc/rack0");          cache.put("host117","/ht_dc/rack0");          cache.put("host118","/ht_dc/rack0");          cache.put("host120","/ht_dc/rack0");          cache.put("host121","/ht_dc/rack0");   }   @Override   publicList<String> resolve(List<String> names) {          List<String>m = new ArrayList<String>();          if (names ==null || names.size() == 0) {                m.add("/default-rack");                return m;          }          for (Stringname : names) {                Stringrack = cache.get(name);                if (rack!= null) {                       m.add(rack);                }          }          return m;   }

}

将上述Java类打成jar包,加上执行权限;然后放到$HADOOP_HOME/lib目录下运行。

1.1.3 网络拓扑(NetworkTopology)
有了机架感知,NameNode就可以画出上图所示的datanode网络拓扑图。D1,R1都是交换机,最底层是datanode。则H1的rackid=/D1/R1/H1,H1的parent是R1,R1的是D1。这些rackid信息可以通过topology.script.file.name配置。有了这些rackid信息就可以计算出任意两台datanode之间的距离。

distance(/D1/R1/H1,/D1/R1/H1)=0 相同的datanode

distance(/D1/R1/H1,/D1/R1/H2)=2 同一rack下的不同datanode

distance(/D1/R1/H1,/D1/R1/H4)=4 同一IDC下的不同datanode

distance(/D1/R1/H1,/D2/R3/H7)=6 不同IDC下的datanode

1.2 副本放置策略(BPP:blockplacement policy)
第一个block副本放在和client所在的node里(如果client不在集群范围内,则这第一个node是随机选取的,当然系统会尝试不选择哪些太满或者太忙的node)。

第二个副本放置在与第一个节点不同的机架中的node中(随机选择)。

第三个副本和第二个在同一个机架,随机放在不同的node中。

如果还有更多的副本,则在遵循以下限制的前提下随机放置

--1个节点最多放置1个副本

-- 如果副本数少于2倍机架数,不可以在同一机架放置超过2个副本

当发生数据读取的时候,名称节点首先检查客户端是否位于集群中。如果是的话,就可以按照由近到远的优先次序决定由哪个数据节点向客户端发送它需要的数据块。也就是说,对于拥有同一数据块副本的节点来说,在网络拓扑中距离客户端近的节点会优先响应。

Hadoop的副本放置策略在可靠性(block在不同的机架)和带宽(一个管道只需要穿越一个网络节点)中做了一个很好的平衡。下图是备份参数是3的情况下一个管道的三个datanode的分布情况。

©著作权归作者所有:来自51CTO博客作者mob604756ec296f的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. Kafka源码系列之topic创建分区分配及leader选举
  2. Kafka源码系列之副本同步机制及isr列表更新
  3. Kubernetes Pod水平自动伸缩(HPA)
  4. 9:VMware Horizon View 8.0-安装副本连接服务器
  5. [灾备] 数据副本管理技术(CDM)
  6. kafka架构
  7. netcore使用 jenkins + supervisor 实现standalone下多副本自动
  8. Docker快速搭建Clickhouse集群(3分片3副本)
  9. android修改或添加SettingsProvider的默认值

随机推荐

  1. 谷歌浏览器团队:感谢 Flash 所做的一切
  2. 动态规划之空间优化与总结回顾
  3. 万字长文!动态规划的终极难题:字符匹配类
  4. Excel数据处理(缺失值/重复值/异常值/拆分
  5. 超详细!详解一道高频算法题:括号生成
  6. 苹果拒绝支持PWA的行为对Web贻害无穷!
  7. 为什么程序员应该写博客?用什么博客系统?在
  8. Excel有哪些相见恨晚的技巧?
  9. 图解一道腾讯笔试算法题:「最长上升子序列
  10. 前端程序员有必要学一点C语言吗?