红联Linux门户
Linux帮助

Ubuntu上使用Hadoop 2.x+HDFS Federation

发布时间:2015-04-08 21:59:25来源:linux网站作者:linux人繁体

为什么需要Federation

HDFS Federation能解决一下问题:

1. 支持多个namespace, 为什么需要多个namespace呢,因为一个namespace由于JVM内存的限制,存放的元数据有限,因此支持的datanode数目也有限制。

下面的分析来自另一篇文章,这里转一下:

由于Namenode在内存中存储所有的元数据(metadata),因此单个Namenode所能存储的对象(文件+块)数目受到Namenode所在JVM的heap size的限制。50G的
heap能够存储20亿(200 million)个对象,这20亿个对象支持4000个datanode,12PB的存储(假设文件平均大小为40MB)。
随着数据的飞速增长,存储的需求也随之增长。单个datanode从4T增长到36T,集群的尺寸增长到8000个datanode。存储的需求从12PB增长到大于100PB。

2. 水平扩展出多个namenode后,就可以避免网络架构上的性能瓶颈问题

3. 多个应用可以使用各自的namenode,从而相互隔离。

不过还是没有解决单点故障问题。


架构图

官方文档:http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-hdfs/Federation.html

架构图如下:
Ubuntu上使用Hadoop 2.x+HDFS Federation


测试环境

现在准备两个namenode server: namenode1和namenode2, /etc/hosts里面的配置如下:

#hdfs cluster
192.168.1.71 namenode1
192.168.1.72 namenode2
192.168.1.73 datanode1
192.168.1.74 datanode2
192.168.1.75 datanode3

现在来看看上面5台server的配置:

namenode1和namenode2的配置
core-site.xml

<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://namenode1:9000</value>
</property>
<property>
<name>io.file.buffer.size</name>
<value>131072</value>
</property>
<property>
<name>net.topology.node.switch.mapping.impl</name>
<value>org.apache.hadoop.net.ScriptBasedMapping</value>
<description> The default implementation of the DNSToSwitchMapping. It  
invokes a script specified in net.topology.script.file.name to resolve  
node names. If the value for net.topology.script.file.name is not set, the  
default value of DEFAULT_RACK is returned for all node names.
</description>
</property>
<property>
<name>net.topology.script.file.name</name>
<value>/opt/rack.lsp</value>
</property>
<property>
<name>net.topology.script.number.args</name>
<value>100</value>
<description> The max number of args that the script configured with
net.topology.script.file.name should be run with. Each arg is an
IP address. 
</description>
</property>
</configuration>

注意,hdfs://namenode1:9000在另一个namenode2上配置为hdfs://namenode2:9000刷新namenode的方法是:

hduser@namenode1:~$ refresh-namenodes.sh
Refreshing namenode [namenode1:9000]
Refreshing namenode [namenode2:9000]

拓扑查询仍然可以使用:

hdfs dfsadmin -printTopology

hdfs-site.xml

<configuration>
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:/home/hduser/mydata/hdfs/namenode</value>
</property>
<property>
<name>dfs.namenode.hosts</name>
<value>datanode1,datanode2,datanode3</value>
</property>
<property>
<name>dfs.blocksize</name>
<value>268435456</value>
</property>
<property>
<name>dfs.namenode.handler.count</name>
<value>100</value>
</property>
<!--hdfs federation begin-->
<property>
<name>dfs.federation.nameservices</name>
<value>ns1,ns2</value>
</property>
<property>
<name>dfs.namenode.rpc-address.ns1</name>
<value>namenode1:9000</value>
</property>
<property>
<name>dfs.namenode.rpc-address.ns2</name>
<value>namenode2:9000</value>
</property>
<!--hdfs federation end-->
</configuration>

注意添加了hdfs federation的配置,里面有两个namespaces: ns1和ns2,分别位于namenode1和namenode2上。


slaves文件

把datanode的hostname都写进去

datanode1
datanode2
datanode3

datanode的配置
core-site.xml
<configuration>
<property>
<name>io.file.buffer.size</name>
<value>131072</value>
</property>
</configuration>

hdfs-site.xml

<configuration>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:/home/hduser/mydata/hdfs/datanode</value>
</property>
<!--hdfs federation begin-->
<property>
<name>dfs.federation.nameservices</name>
<value>ns1,ns2</value>
</property>
<property>
<name>dfs.namenode.rpc-address.ns1</name>
<value>namenode1:9000</value>
</property>
<property>
<name>dfs.namenode.rpc-address.ns2</name>
<value>namenode2:9000</value>
</property>
<!--hdfs federation end-->
</configuration>


总体上来说,namenode的配置比较多,包括rack awareness的设置。
现在在两个namenode上格式化,并启动:

hdfs namenode -format -clusterId csfreebird
hadoop-daemon.sh --config $HADOOP_CONF_DIR --script hdfs start namenode

因为曾经格式化过namenode,要回答y表示重新格式化。


管理站点

在任何一个namenode节点上,仍然使用端口50070, 访问的网址变成下面:http://namenode1:50070/dfsclusterhealth.jsp网页截屏:
Ubuntu上使用Hadoop 2.x+HDFS Federation

注:以上图片上传到红联Linux系统教程频道中。


远程命令

为了能够集中管理各个节点,需要能够在一台namenode server上执行命令,远程管理所有节点,因此需要在每个节点上libexec/Hadoop-config.sh文件中开头添加一行JAVA_HOME变量配置:

export JAVA_HOME=/usr/lib/jvm/java-7-Oracle/

现在再namenode1上执行下面的命令,停止所有hdfs的服务:

hduser@namenode1:~$ stop-dfs.sh
Stopping namenodes on [namenode1 namenode2]
namenode2: no namenode to stop
namenode1: no namenode to stop
datanode2: no datanode to stop
datanode1: no datanode to stop
datanode3: no datanode to stop


负载均衡

在namenode1上可以启动balancer程序,采用默认的node策略。参考文档:http://hadoop.apache.org/docs/r2.3.0/hadoop-project-dist/hadoop-hdfs/Federation.html#Balancer

hduser@namenode1:~$ hadoop-daemon.sh --config $HADOOP_CONF_DIR --script "$bin"/hdfs start balancer
starting balancer, logging to /usr/local/hadoop/logs/hadoop-hduser-balancer-namenode1.out


错误处理
cluster id 不兼容

如果在启动datanode的时候日志中报错:

java.io.IOException: Incompatible clusterIDs

就把dfs.datanode.data.dir配置的目录删除,然后再次启动。