机架感知(Rack Awareness)机制浅述

机架感知(RackAwareness)


通常,大型Hadoop集群会分布在很多机架上。在这种情况下,

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

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

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


机架感知设计思想

首先,一个重要的假设前提是HDFS运行于一个具有树状网络拓扑结构的集群上。

例如集群由多个数据中心组成,每个数据中心里有多个机架,而每个机架上有多台计算机(数据节点)。如下图所示:



网络拓扑(NetworkTopology


Hadoop里,以类似于一种文件目录结构的方式来表示节点。

例如,R1的位置可以表示为 /D1/R1,而H12的位置可以表示为 /D2/R4/H12


当数据节点启动的时候,需要通过一种机制来明确它在集群中的位置,才能构建完整的网络拓扑图。

因此,首先它需要确认它的上级节点(通常也就是机架)的位置。数据节点程序支持选项”-p<id>””-parent<id>”从命令行读入上级节点位置。

如果没有指定这个选项,那么会使用一个默认的上级节点。

至于如何获取上级节点信息,由实施Hadoop的机构自行决定。一个常用的做法是使用脚本打印当前机器的上级节点信息到标准输出stdout

这样数据节点启动的时候就可以获取到上级节点的信息(Hadoop应该是通过接口’DNSToSwitchMapping’来解析这个信息,具体请参考手册的Class说明)。



数据节点会把它的位置信息发给名称节点。

当名称节点收到数据节点的位置信息以后,它会先检查网络拓扑中是否已经有这个数据节点的记录。

如果有,它会把旧的记录删除,加入新的节点位置信息。


副本放置(ReplicaPlacement


数据块的副本放置策略的目的是在以下两者之间取得平衡:

-- 使数据的可靠性和可用性最大化
-- 使写入数据产生的开销最小化

因此,当一个新的数据块被创建的时候,遵循以下规则:


-- 第1个副本放置于本地节点
-- 第2个副本放置于不同的机架
-- 第3个副本放置于本地机架的不同节点
-- 其余的副本在遵循以下限制的前提下随机放置

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

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


当重新复制一个数据块的时候,遵循以下规则:


-- 如果已有1个副本,把第2个副本放置在不同的机架
-- 如果已有2个副本且处于同一机架,把第3个副本放置在不同的机架
-- 如果已有2个副本但不处于同一机架,把第3个副本放置在和第1个副本相同的机架
-- 当可用副本数超过2个的时候,随机放置


当发生数据读取的时候,名称节点首先检查客户端是否位于集群中。

如果是的话,就可以按照由近到远的优先次序决定由哪个数据节点向客户端发送它需要的数据块。

也就是说,对于拥有同一数据块副本的节点来说,在网络拓扑中距离客户端近的节点会优先响应。 



配置范例


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

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

例如:


<property> 
  <name>topology.script.file.name</name> 
  <value>/home/hadoop/topology.py</value>
</property>



Python语言编写的脚本范例:


  
  
  

#!/usr/bin/env python


'''

This script used by hadoop to determine network/rack  topology.  It

should be specified in hadoop-site.xml via  topology.script.file.name

Property.

  

topology.script.file.name

/home/hadoop/topology.py


  

'''

  

import sys

from string import join

  

DEFAULT_RACK = '/default/rack0';

  

RACK_MAP = { '10.72.10.1' : '/datacenter0/rack0',

  

'10.112.110.26' : '/datacenter1/rack0',

'10.112.110.27' : '/datacenter1/rack0',

'10.112.110.28' : '/datacenter1/rack0',


  

'10.2.5.1' : '/datacenter2/rack0',

'10.2.10.1' : '/datacenter2/rack1'

}

  

if len(sys.argv)==1:

print DEFAULT_RACK

else:

print join([RACK_MAP.get(i, DEFAULT_RACK) for i in  sys.argv[1:]]," ")



以上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值