c# 找出目录下的所有子目录_万丈高楼平地起——大数据配置管理之HDFS(下)...

上篇中,我们共同探讨了HDFS的设计思想、体系结构等问题,现在,让我们开始真正的Hadoop配置管理之旅。

从理论上来说,Hadoop的配置管理是非常简单的,因为它既没有Oracle数据库那样复杂的体系结构,也没有众多的命令,配置文件也非常简单。但实际上,大家会感觉这样的任务很麻烦,特别是初学者。

Hadoop是一个开放式平台,包含很多框架,每个框架都不断变化,版本升级很快,每个框架都有很多BUG,框架之间的兼容性也存在很大的问题。在配置管理Hadoop的过程中,你会遇到很多莫名其妙的问题,这些问题足以让你精神崩溃。以下软件/框架是本人在实验环境中选用的,它们没有出现什么问题,至少没有出现严重的问题。

  • 操作系统:Red Hat Enterprise Linux 7.4

  • JDK:jdk1.8.0_152

  • Hadoop 3.1.1

  • Zookeeper 3.4.12

  • Hbase 1.4.7

一、文件解压缩

在Apache官网下载Hadoop 3.1.1,以hadoop用户登录每个Linux操作系统,对文件解压缩。按照规划,所有用到的框架都解压缩到共同的目录/Hadoop下,这样方便统一管理。hadoop用户需要对这个目录具有读写权限。文件解压缩的命令为:

tar zxvf hadoop-3.1.1.tar.gz

接下来,需要在hadoop用户的HOME目录的.bash_profile文件中修改环境变量,例如:

a8d80d8f0d77dac9d77d5bf39afbf7dc.png

在解压缩所产生的目录中,sbin子目录下是用来启动/关闭node所需要的脚本命令,在bin子目录下包含Hadoop的几个实用工具,在etc/hadoop目录下包含Hadoop的配置文件。

在实际的配置过程中,需要修改很多的文本文件,这样的任务需要在所有操作系统中进行。一个好的做法是,在其中一个操作系统中修改文件,然后通过scp命令把修改之后的文件拷贝到其他操作系统中。

二、单NameNode配置

这是一种典型的分布式配置,包括一个NameNode和多个DataNode,这种配置并没有高可用性,如果唯一的NameNode出现故障,整个HDFS将不可用。

1.  在hadoop-env.sh文件中配置环境变量

在这个文件中,唯一必须指定的环境变量是JAVA_HOME,变量值与.bash_profile文件中的同名变量相同。其他变量如HADOOP_CONF_DIR也可以在这个文件中指定。

2.  在workers文件中定义所有的DataNode

DataNode的定义非常简单,只需要在这个文件中指定DataNode的主机名或者IP地址即可,每行指定一个。例如:

Server1

Server2

Server3

3.  在core-site.xml文件中定义HDFS的全局信息

这个文件的初始内容只包含一对空的标记和,以及少量其他信息。在这对标记之间,需要加入HDFS参数的定义,一般至少需要加入以下定义:

  fs.defaultFS

  hdfs://Server1:8020

  hadoop.tmp.dir

 /Hadoop/hadoop-3.1.1/tmp

其中参数fs.defaultFS用于定义NameNode的地址,也就是HDFS的入口地址,客户端对HDFS的方式是通过这个地址进行的。根据上面的定义,Server1为NameNode,它所监听的端口是8020。参数hadoop.tmp.dir用于定义一个目录,HDFS在运行过程中所产生的一些文件被写入这个目录,默认的参数值为/tmp。在默认情况,NameNode的元数据文件,以及DataNode的数据都被写入这个目录的子目录下。这样的默认定义显然不合理,因为操作系统每次重新启动时,都会将/tmp目录清空。

在Hadoop中,所有的XML文件都具有相同的格式,在每个文件中都需要定义若干参数。为节省篇幅,在本文以后的内容中,将不再罗列每个参数的完整格式,而仅仅列出参数的名称和参数值,至于参数的完整格式,以及文件的完整内容,请读者自行脑补。

4.  在hdfs-site.xml文件中定义HDFS的详细信息

在这个文件中的空标记和之间,加入以下参数的定义。实际上,很多参数可以采用默认值,读者可以参考官方文档,了解默认值的定义。

  • dfs.replication:指定HDFS中数据的拷贝数,默认为3

  • dfs.blocksize:指定HDFS中块的大小,如64M,128M,256M等

  • dfs.namenode.name.dir:指定操作系统的本地目录,NameNode将元数据文件写入这个目录,默认值为/tmp下的子目录

  • dfs.datanode.data.dir:指定操作系统的本地目录,DataNode将数据写入这个目录,默认值为/tmp下的子目录。在这个目录中,一个块对应一个文件

  • dfs.namenode.rpc-address:指定NameNode的RPC地址,如Server1:8020,参数值与core-site.xml定义的入口地址相同

  • dfs.namenode.http-address:指定NameNode的HTTP地址,如Server1:9870。管理与可以在浏览器中输入这个地址,通过WEB访问方式查看HDFS中各个node的状态,以及HDFS中的文件

5.  利用scp命令,将上述1-4步所修改的配置文件拷贝到其他操作系统对应的目录下,即Hadoop的etc/hadoop子目录。例如:

896445d89427d38cdaeee9bd4aba5ca5.png

6.  对NameNode进行格式化

以hadoop用户身份登录NameNode,执行命令:

hdfs namenode -format

此时NameNode的目录将自动产生,也就是参数dfs.namenode.name.dir指定的目录,在这个目录下将产生最初的Fsimage文件。

三、HDFS的启动和关闭

现在,见证奇迹的时刻到了。如果NameNode和DataNode能够顺利启动,那么Hadoop就具有最基本的雏形了。这些node可以分别启动,也可以集中启动。例如,以hadoop用户登录NameNode,执行下面的命令启动NameNode进程:

hdfs --daemon start namenode

以hadoop用户登录每个DataNode,分别执行下面的命令,启动每个DataNode进程:

hdfs --daemon start datanode

对应的关闭命令分别是:

hdfs --daemon stop namenode

hdfs --daemon stop datanode

如果在此之前配置了SSH对等关系,那么HDFS的启动或关闭就非常容易了。以hadoop用户身份登录任何一个操作系统,分别执行下面的命令来启动或关闭整个HDFS:

start-dfs.sh

stop-dfs.sh

当我们启动HDFS之后,还需要查看每个node的状态是否正常。在操作系统中,每个node都表现为一个Java进程,所以借助于JDK提供的命令jps就能够列出这样的进程。例如,在Server1中执行jps命令,不需要任何命令行参数,结果类似如下:

25392 NameNode

25483 DataNode

这表明,在Server1中运行一个NameNode和一个DataNode。每行的第一个列代表进程的pid,第二个列代表进程名称。

由于各种原因,node可能无法正常启动,这时需要判断出错的原因。最好的方法是查看每种node所产生的日志文件。在Hadoop解压缩所产生的目录下,有一个logs子目录,HDFS的日志文件就在这个目录下,每种node对应一个文件,根据文件名称就能够判断它们的对应关系。各种错误,总有一款或多款等着你。

四、hdfs shell的用法

到此为止,我们得到了一个功能完善的Hadoop运行环境,在这里现在可以运行MapReduce任务了。HDFS为Hadoop提供了一个文件系统空间,它采用了类似于传统文件系统那样的层次结构,最顶层是根目录,每个目录下可以包含子目录和文件。HDFS中的文件在操作系统中是看不见的,为此,Hadoop提供了一个hdfs shell,用来对HDFS中的文件和目录进行管理。hdfs shell通过以下两条命令之一来调用:

hdfs dfs -子命令

hadoop fs -子命令

这两条命令实际是等价的,它们提供了一系列相同的子命令,这些子命令的名称和用法类似于Linux的操作系统命令。例如,下面的命令用于在HDFS的根目录下创建子目录input:

hdfs dfs -mkdir /input

下面的命令用于把本地文件系统中的一个.zip文件上传到HDFS的/input目录中:

b18b6113f2d40648bc6c8f39e7627432.png

下面的命令用于列出HDFS的/input目录中的文件:

hdfs dfs -ls /input

五、多NameNode配置

到目前为止,我们配置的Hadoop已经能够正常运行了,但这样的配置有一个缺陷,那就是:NameNode没有高可用性。为了保证NameNode的安全,可以定义多个NameNode,它们的状态可以在Active和Standby之间切换,这种配置就是HDFS集群。在Hadoop 2.x中,可以定义两个NameNode,在3.x中可以定义两个以上NameNode。

HDFS集群的定义与上述第二步介绍的过程相同,启动方法也与第三步介绍的内容相同,只是core-site.xml和hdfs-site.xml文件的内容有所不同。在core-site.xml文件中通过下面的方式定义HDFS的入口地址:

  fs.defaultFS

  hdfs://mycluster

其中字符串mycluster代表集群的名称,也是一个名称空间的名称,这个集群的结构在文件hdfs-site.xml中定义。在hdfs-site.xml中,以下参数的含义与之前相同:

  • dfs.replication

  • dfs.blocksize

  • dfs.namenode.name.dir

  • dfs.datanode.data.dir

为了定义HDFS集群,需要为以下参数指定适当的参数值:

  • dfs.nameservices:定义集群的名称,也就是定义一个名称空间,在这个集群中包含若干Name Node

  • dfs.ha.namenodes.mycluster:定义集群mycluster中各个NameNode的ID,在本例中,参数值为nn1,nn2

  • dfs.namenode.rpc-address.mycluster.nn1:为ID为nn1的NameNode指定RPC地址,在本例中,参数值为Server1:8020

  • dfs.namenode.http-address.mycluster.nn1:为ID为nn1的NameNode指定HTTP地址,在本例中,参数值为Server1:9870

  • dfs.namenode.rpc-address.mycluster.nn2:为ID为nn2的NameNode指定RPC地址,在本例中,参数值为Server2:8020

  • dfs.namenode.http-address.mycluster.nn2:为ID为nn2的NameNode指定HTTP地址,在本例中,参数值为Server2:9870

在这里虽然定义了多个NameNode,但它们之间并不能共享Fsimage和Editlog文件,也就是说,这两个文件在多个NameNode是不一致的,所以,目前的定义并不完整。

六、NameNode高可用性的配置

在正常情况下,多个NameNode中只有一个状态为Active,这就是主NameNode,其余为从NameNode,状态为Standby。主NameNode负责维护最新的Fsimage和Editlog文件。如果HDFS的结构有变化,主NameNode将更新Fsimage和Editlog文件。HDFS可以采用NFS和QJM两种方法,使Fsimage和Editlog文件在主、从NameNode之间保持一致。这里只介绍QJM方法。

通过QJM方法实现NameNode高可用性的配置过程如下。

1.  在第五步配置的基础上,修改hdfs-site.xml文件,加入以下参数定义:

  • dfs.journalnode.edits.dir:为JournalNode指定一个本地目录,每个JournalNode将在这个目录下创建子目录,在本例中,参数值为/Hadoop/hadoop-3.1.1/journal,这个目录需要手工创建

  • dfs.namenode.shared.edits.dir :定义JournalNode的IP地址及端口,以及上述目录的子目录名称,一般来说,这个子目录的名称就是集群的名称。在本例中,这个参数的值为:

c91ab7ca45bee56ad45054e43b1863af.png

  • dfs.client.failover.proxy.provider.mycluster  :指定一个Java类,NameNode类的状态转换通过这个类来实现。这个类是由Hadoop提供的,名称为:

    org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider

  • dfs.ha.fencing.methods:值为sshfence

  • dfs.ha.fencing.ssh.private-key-files:值为/home/hadoop/.ssh/id_rsa,即hadoop用户的私钥文件

2.  利用scp命令,将修改之后的配置文件拷贝到其他操作系统对应的目录下

3. 以hadoop用户登录各个JournalNode,执行下面的命令,启动JournalNode。

hdfs--daemon start journalnode

4.  在选定的主NameNode上,以Hadoop用户登录,执行下面的命令,对NameNode进行格式化。

hdfs name node-format

5.  将NameNode的目录,即dfs.name node.name.dir指定的目录,拷贝到其他NameNode对应的目录下

6.   依次启动各个NameNode和各个DataNode

7.  通过执行jps命令,查看各个node的启动情况。例如,在Server1上,这条命令的执行结果如下所示:

29252 NameNode

29607 JournalNode

29388 DataNode

以后,对HDFS的启动应该按照下面的顺序进行:

首先执行下面的命令,启动各个JournalNode:

hdfs --daemon start journalnode

然后执行下面的命令,启动各个NameNode:

hdfs --daemon start namenode

最后执行下面的命令,启动各个DataNode:

hdfs --daemon start datanode

或者在任何一个node上,执行命令start-dfs.sh,这条命令将启动各个JournalNode,NameNode以及DataNode。

七、NameNode状态的转换

在这里不得不抱歉地告诉大家,HDFS集群虽然已经配置完成,而且能够启动起来,但是这样的配置还是有缺陷的。多个NameNode的状态并不能自动转换,需要通过命令进行手工转换,它们的初始状态都是Standby。如果希望实现NameNode状态的自动转换,请继续关注我们的公众号文章。Hadoop提供了hdfs命令,利用这条命令及其子命令和参数,可以对NameNode进行状态控制。

下面这条命令用于查看各个NameNode的状态:

hdfs haadmin -getAllServiceState

这条命令最初的执行结果为:

Server1:8020  standby  

Server2:8020  standby

下面这条命令用于把ID为nn1的NameNode转换为Active状态:

hdfs haadmin -transitionToActive nn1

下面这条命令用于把ID为nn1的NameNode转换为Standby状态:

hdfs haadmin -transitionToStandby nn1

下面这条命令用于对两个NameNode进行failover,也就是说,把两个NameNode进行状态互换。这条命令执行的前提是其中一个NameNode的状态为Active,另一个为Standby。

hdfs haadmin -failover nn1 nn2

如果希望NameNode能够实现状态的自动切换,就需要进一步配置ZooKeeper。实际上,ZooKeeper可以为Hadoop中的各种集群提供底层支持,所以,它也是大家必须掌握的一个框架。

编辑:小恒

作者简介:

刘宪军,男,1997年毕业于西北大学计算机科学系,获工学硕士学位。目前主要从事小型机、中间件、数据库、大数据的技术支持和培训工作。

历年出版的专著有:

《Oracle数据库备份、恢复与迁移》 机械工业出版社  2017年1月

《Oracle RAC 11g实战指南》 机械工业出版社  2011年1月

《Oracle 11g 数据库管理员指南》 机械工业出版社  2010年8月

《软件过程管理》 水利水电出版社  2004年

《UNIX系统管理教程》清华大学出版社  2002年

《Windows/Linux/UNIX综合组网技术》清华大学出版社  2002年

作者原创:

《万丈高楼平地起——大数据配置管理之HDFS(上)》

《数据的生存之道——MySQL数据库的备份与恢复(上)》

《数据的生存之道——MySQL数据库的备份与恢复(下)》

《IT老司机:大数据的修行之路》

《Oracle与MySQL,谁优谁劣?》

af68c30e9a12019ed51c73083805c84e.png

c63ac9498d9a8679a81beef3289b5c45.png

每周五《大数据可视化周刊》与您不见不散

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值