第2章,文件夹怎么加密

文件夹 3
第2章 CentOS7集群环境配置 本章内容 在安装好操作系统后,需要对系统进行环境配置,以便后续能够轻松进行Hadoop集群的搭建。
本章2.1节和2.2节在第1章安装好的操作系统的基础上继续讲解系统集群环境的配置和JDK的安装;2.3节讲解对前面配置好的系统进行克隆,克隆出其他两个节点,而不需要重新新建虚拟机和安装操作系统;2.4节讲解对三个节点进行主机名与IP的映射配置,为后面集群的搭建做好准备。
本章目标 了解CentOS7用户的添加和权限的修改。
掌握CentOS7中主机名与IP的修改。
掌握CentOS7中JDK的安装。
掌握虚拟机的克隆。
掌握CentOS7中主机IP映射的配置。
2.1系统环境配置 本节讲解在安装软件及搭建集群之前对CentOS7系统环境的一些配置操作。
第2章CentOS7集群环境配置|17 2.1.1新建用户 本书中使用1.3节安装操作系统时新建的hadoop用户进行后续的操作,读者若想使用其他用户,可按照下面的步骤新建用户。
例如,新建用户tom:
(1)使用“su-”命令切换为root用户,然后执行以下命令:$addusertom
(2)执行以下命令,设置用户tom的密码:$passwdtom到此,用户tom新建成功。
2.1.2修改用户权限 为了使普通用户可以使用root权限执行相关命令(例如,系统文件的修改等),而不需要切换到root用户,可以在命令前面加入指令sudo。
文件/etc/sudoers中设置了可执行sudo指令的用户,因此需要修改该文件,添加相关用户。
例如,使hadoop用户可以执行sudo指令,操作步骤如下:使用“su-”命令切换为root用户,然后执行以下命令,修改文件sudoers:$vi/etc/sudoers在文本rootALL=(ALL)ALL的下方加入以下代码,使hadoop用户可以使用sudo指令:hadoopALL=(ALL)ALL执行sudo指令对系统文件进行修改时需要验证当前用户的密码,默认5分钟后密码过期,下次使用sudo需要重新输入密码。
如果不想输入密码,则把上方的代码换成以下内容即可:hadoopALL=(ALL)NOPASSWD:ALL执行exit命令回到hadoop用户,此时使用root权限的命令只需要在命令前面加入sudo即可,无须输入密码。
例如,以下命令:$sudocat/etc/sudoers 注意安装操作系统时创建的管理员用户hadoop,默认可以执行sudo指令,但需要验证hadoop用户的密码。
可对其按照上面的步骤配置无须密码使用sudo指令。
2.1.3关闭防火墙 集群通常都是内网搭建的,如果内网开启防火墙,内网集群通信则会受到防火墙的干扰,因此需要关闭集群中所有节点的防火墙。
18|Hadoop大数据技术开发实战执行以下命令关闭防火墙:$sudosystemctlfirewalld.service然后执行以下命令,禁止防火墙开机启动:$sudosystemctldisablefirewalld.service若需要查看防火墙是否已经关闭,可以执行以下命令,查看防火墙的状态:$sudofirewall-cmd--state此外,开启防火墙的命令如下:$sudosystemctlstartfirewalld.service 2.1.4设置固定IP 为了避免后续启动操作系统后,IP地址改变了,导致集群间通信失败,节点间无法正常访问,需要将操作系统的IP状态设置为固定IP,具体操作步骤如下。

1.查看VMware网关IP单击VMware菜单栏中的【编辑】/【虚拟网络编辑器】,在弹出的【虚拟网络编辑器】窗口的上方表格中选择最后一行,即外部连接为【NAT模式】,然后单击下方的【NAT设置】按钮,如图2-1所示。
图2-1选择外部NAT模式在弹出的【NAT设置】窗口中,查看VMware分配的【网关IP】。
可以看到,本例中的网关IP为192.168.170.2(网段为170),如图2-2所示。
需要注意的是,后续给VMware中的操作系统设置IP时,网关IP应与图2-2中的网关IP保 持一致。
第2章CentOS7集群环境配置|19 图2-2查看VMware网关IP
2.配置系统IPCentOS7系统IP的配置方法有两种:桌面配置方式和命令行配置方式,下面分别进行讲解。

(1)桌面配置方式。
单击系统桌面右上角的倒三角按钮,在弹出的窗口中单击【有线设置】,如图2-3所示。
图2-3系统有线网络设置 20|Hadoop大数据技术开发实战在弹出的窗口中单击下方的【添加配置】按钮,如图2-4所示。
图2-4添加网络配置在弹出的【网络配置】窗口中,左侧选择【IPv4】,右侧的【地址】选择【手动】,如图2-5所示。
图2-5网络连接信息配置界面接着输入IP地址、网络掩码、网关和DNS服务器信息。
IP地址可以自定义,范围在1~254之间,IP地址的网段应与网关一致,此处将IP地址设置为192.168.170.133。
输入完毕后单击【添加】按钮,如图2-6所示。
第2章CentOS7集群环境配置|21 图2-6填写网络配置信息
(2)命令行配置方式。
在系统终端命令行窗口执行以下命令,修改文件ifcfg-ens33:$sudovim/etc/work-scripts/ifcfg-ens33完整修改后的内容如下:TYPE=BOOTPROTO=staticDEFROUTE=yesPEERDNS=yesPEERROUTES=yesIPV4_FAILURE_FATAL=noIPV6INIT=yesIPV6_AUTOCONF=yesIPV6_DEFROUTE=yesIPV6_PEERDNS=yesIPV6_PEERROUTES=yesIPV6_FAILURE_FATAL=noIPV6_ADDR_GEN_MODE=stable-privacyNAME=ens33UUID=cd0d7046-b038-47c1-babe-6442444e9fa9DEVICE=ens33ONBOOT=yesIPADDR=192.168.170.133NETMASK=255.255.255.0GATEWAY=192.168.170.2DNS1=192.168.170.2DNS2=114.114.114.114 22|Hadoop大数据技术开发实战 上述内容中,实线框标注的是修改的内容,虚线框标注的是添加的内容。
需要修改的属性及解析如下: BOOTPROTO:值static表示静态IP(固定IP),默认值是dhcp,表示动态IP。
ONBOOT:yes表示开机启用本配置。
需要添加的属性及解析如下:IPADDR:IP地址。
NETMASK:子网掩码。
GATEWAY:默认网关。
虚拟机安装的话,通常是
2,即8的网关设置。
DNS1:DNS配置。
虚拟机安装的话,与网关一致。
若需要连接外网,需要配置DNS。
DNS2:网络运营商公众DNS,此处也可省略。
修改完成后执行以下命令,重启网络服务,使修改生效:$sudoworkrestart重启完成后,可以通过ifconfig命令或者以下命令,查看改动后的IP:$ipaddr在输出的信息中,若网卡ens33对应的IP地址已显示为设置的地址,说明IP修改成功,如图2-7所示。
图2-7查看系统IP地址
3.测试本地访问在本地Windows系统打开cmd命令行窗口,使用ping命令访问虚拟机中操作系统的IP地址,命令如下: $ping192.168.170.133若能成功返回数据,说明从本地Windows可以成功访问虚拟机中的操作系统,便于后续从本地系统进行远程操作。
2.1.5修改主机名 在分布式集群中,主机名用于区分不同的节点,方便节点之间相互访问,因此需要修改主机 第2章CentOS7集群环境配置|23 的主机名。
具体操作步骤如下:
(1)使用hadoop用户登录系统,进入系统的终端命令行,输入以下命令,查看主机名:$hostnamelocalhost.localdomain从输出信息中可以看到,当前主机的默认主机名为localhost.localdomain。

(2)执行以下命令,设置主机名为centos01:$sudohostnamecentos01此时系统的主机名已修改为centos01,但是重启系统后修改将失效,要想永久改变主机名,需 要修改/etc/hostname文件。
执行以下命令,修改hostname文件,将其中的默认主机名改为centos01:1$sudovi/etc/hostname
(3)执行reboot命令,重启系统使修改生效。
需要注意的是,修改主机名后需要重启操作系统才能生效。
2.1.6新建资源目录 在目录/opt下创建两个文件夹softwares和modules,分别用于存放软件安装包和软件安装后的程序文件,命令如下: $sudomkdir/opt/softwares$sudomkdir/opt/modules将目录/opt及其子目录中所有文件的所有者和组更改为用户hadoop和组hadoop,命令如下:$sudochown-Rhadoop:hadoop/opt/*查看目录权限是否修改成功,命令及输出信息如下:$ll总用量0drwxr-xr-x.2hadoophadoop63月809:55modulesdrwxr-xr-x.2hadoophadoop63月262015rhdrwxr-xr-x.2hadoophadoop2313月809:07softwares 2.2安装JDK Hadoop等很多大数据框架使用Java开发,依赖于Java环境,因此在搭建Hadoop集群之前需要安装好JDK。
JDK的安装步骤如下。
24|Hadoop大数据技术开发实战
1.卸载系统自带的JDK执行以下命令,查询系统已安装的JDK: $rpm-qa|grepjavajava-1.8.0-openjdk-1.8.0.102-4.b14.el7.x86_64javapackages-tools-3.4.1-11.el7.noarchjava-1.8.0-openjdk-headless-1.8.0.102-4.b14.el7.x86_64tzdata-java-2016g-2.el7.noarchpython-javapackages-3.4.1-11.el7.noarchjava-1.7.0-openjdk-headless-1.7.0.111-2.6.7.8.el7.x86_64java-1.7.0-openjdk-1.7.0.111-2.6.7.8.el7.x86_64 执行以下命令,卸载以上查询出的系统自带的JDK: $sudorpm-e--nodepsjava-1.8.0-openjdk-1.8.0.102-4.b14.el7.x86_64$sudorpm-e--nodepsjavapackages-tools-3.4.1-11.el7.noarch$sudorpm-e--nodepsjava-1.8.0-openjdk-headless-1.8.0.102-4.b14.el7.x86_64$sudorpm-e--nodepstzdata-java-2016g-2.el7.noarch$sudorpm-e--nodepspython-javapackages-3.4.1-11.el7.noarch$sudorpm-e--nodepsjava-1.7.0-openjdk-headless-1.7.0.111-2.6.7.8.el7.x86_64$sudorpm-e--nodepsjava-1.7.0-openjdk-1.7.0.111-2.6.7.8.el7.x86_64
2.安装JDK
(1)上传解压安装包。
上传JDK安装包jdk-8u144-linux-x64.tar.gz到目录/opt/softwares中,然后进入该目录,解压jdk-8u144-linux-x64.tar.gz到目录/opt/modules中,解压命令如下: $tar-zxfjdk-8u144-linux-x64.tar.gz-C/opt/modules/
(2)配置JDK环境变量。
执行以下命令,修改文件/etc/profile,配置JDK系统环境变量: $sudovi/etc/profile 在文件末尾加入以下内容: exportJAVA_HOME=/opt/modules/jdk1.8.0_144exportPATH=$PATH:$JAVA_HOME/bin 执行以下命令,刷新profile文件,使修改生效: $source/etc/profile 执行java-version命令,若能成功输出以下JDK版本信息,说明安装成功: javaversion"1.8.0_144"Java(TM)SERuntimeEnvironment(build1.8.0_144-b13)JavaHotSpot(TM)64-BitServerVM(build25.144-b13,mixedmode) 第2章CentOS7集群环境配置|25 2.3克隆虚拟机 由于集群环境需要多个节点,当一个节点配置完毕后,可以通过VMware的克隆功能,将配置好的节点进行完整克隆,而不需要重新新建虚拟机和安装操作系统。
接下来讲解通过克隆已经安装好JDK的centos01节点的方法,新建两个节点centos02和centos03,具体操作步骤如下。

1.克隆centos01节点到centos02关闭虚拟机centos01,然后在VMware左侧的虚拟机列表中右键单击centos01虚拟机,选择【管理】/【克隆】,如图2-8所示。
图2-8选择克隆虚拟机在弹出的【克隆虚拟机向导】窗口中直接单击【下一步】按钮即可,如图2-9所示。
26|Hadoop大数据技术开发实战 图2-9克隆虚拟机向导在弹出的【克隆源】窗口中,选择【虚拟机中的当前状态】选项,然后单击【下一步】按钮,如图2-10所示。
图2-10选择克隆状态在弹出的【克隆类型】窗口中,选择【创建完整克隆】选项,然后单击【下一步】按钮,如图2-11所示。
第2章CentOS7集群环境配置|27 图2-11选择克隆类型在弹出的新窗口中,【虚拟机名称】一栏填写为“centos02”,并单击【浏览】按钮,修改新虚拟机的存储位置,然后单击【完成】按钮,开始进行克隆,如图2-12所示。
图2-12填写虚拟机名称并选择虚拟机存放位置虚拟机的克隆过程如图2-13和图2-14所示。
28|Hadoop大数据技术开发实战 图2-13虚拟机克隆进度 图2-14虚拟机克隆完成
2.克隆centos01节点到centos03centos02节点克隆完成后,再次克隆节点centos01,将克隆后的虚拟机名称改为“centos03”。
克隆完成后,所有节点如图2-15左侧列表所示。
第2章CentOS7集群环境配置|29 图2-15VMware中的三个节点列表展示
3.修改节点主机名与IP由于节点centos02与centos03是从centos01克隆而来,主机名和IP与centos01完全一样,因此需要修改这两个节点的主机名与IP。
本例中,分别将节点centos02和centos03的主机名修改为“centos02”和“centos03”,IP修改为固定IP192.168.170.134和192.168.170.135,修改方法参考本章2.1.4节、2.1.5节,此处不再赘述。
2.4配置主机IP映射 通过修改各节点的主机IP映射,可以方便地使用主机名访问集群中的其他主机,而不需要输入IP地址。
这就好比我们通过域名访问网站一样,方便快捷。
接下来讲解配置节点centos01、centos02、centos03的主机IP映射,具体操作步骤如下: 依次启动三个节点:centos01、centos02、centos03。
使用ifconfig命令查看三个节点的IP,本例三个节点的IP分别为:192.168.170.133192.168.170.134192.168.170.135 在各个节点上分别执行以下命令,修改hosts文件: $sudovi/etc/hosts 在hosts文件末尾追加以下内容: 192.168.170.133192.168.170.134 centos01centos02 30|Hadoop大数据技术开发实战 192.168.170.135 centos03 需要注意的是,主机名后面不要有空格,且每个节点的hosts文件中都要加入同样的内容,这样可以保证每个节点都可以通过主机名访问到其他节点,防止后续的集群节点间通信产生问题。
配置完后,在各节点使用ping命令检查是否配置成功,如下: $pingcentos01$pingcentos02$pingcentos03 配置本地Windows系统的主机IP映射,以便后续可以在本地通过主机名直接访问集群节点资源。
编辑Windows操作系统的C:\Windows\System32\drivers\etc\hosts文件,在文件末尾加入以下内容即可: 192.168.170.133centos01192.168.170.134centos02192.168.170.135centos03 第3章 Hadoop 本章内容 本章讲解Hadoop的基本概念与架构原理,并重点讲解YARN集群的架构和工作流程,最后在第2章搭建好的三个节点(centos01、centos02和centos03)上继续讲解Hadoop集群的搭建。
本章目标 了解Hadoop生态系统组成。
掌握Hadoop核心架构。
掌握YARN的基本架构。
掌握YARN的主要组件。
掌握SSH无密钥登录的配置。
掌握Hadoop分布式集群的搭建。
3.1Hadoop简介 当今互联网发展迅速,大型网站系统的日志量呈指数级增长,而日志对互联网公司是非常重要的,可以通过分析用户操作日志获取用户行为,从而有针对性地对用户进行推荐,提高产品的价值。
假如一天产生的日志量为300GB,一年产生的日志量则为300GB×365=107TB,这么大的数据量如何进行备份和容错?又如何进行分析呢? ApacheHadoop是大数据开发所使用的一个核心框架,是一个允许使用简单编程模型跨计算机集群分布式处理大型数据集的系统。
使用Hadoop可以方便地管理分布式集群,将海量数据分布式 32|Hadoop大数据技术开发实战地存储在集群中,并使用分布式并行程序来处理这些数据。
它被设计成从单个服务器扩展到数千台计算机,每台计算机都提供本地计算和存储。
Hadoop本身的设计目的不是依靠硬件来提供高可用性,而是在应用层检测和处理故障。
3.1.1Hadoop生态系统架构 Hadoop的生态系统主要组成架构,如图3-1所示。
图3-1Hadoop生态系统主要组成架构随着Hadoop生态系统的成长,出现了越来越多新的项目,这些项目有的需要依赖于Hadoop,有的可以独立运行,有的对Hadoop提供了很好的补充。
下面对Hadoop生态系统架构中的关键技术进行简要介绍,本书后续章节将对每一项技术进行详细讲解。
Hadoop的核心主要包含以下模块。
HDFS(HadoopDistributedFileSystem):可提供高吞吐量访问的分布式文件系统。
YARN:用于任务调度和集群资源管理的框架。
MapReduce:基于YARN之上,用于大型数据集并行处理的系统。
其他Hadoop相关的系统。
ZooKeeper:一个高性能的分布式应用程序的协调服务。
Flume:一个日志收集系统,用于将大量日志数据从许多不同的源进行收集、聚合,最终移 第3章Hadoop|33动到一个集中的数据中心进行存储。
Sqoop:用于在关系型数据库与Hadoop平台之间进行数据导入和导出的工具。
Kafka:一种高吞吐量的分布式发布订阅消息系统。
HBase:一个可伸缩的分布式数据库,支持大型表的结构化数据存储。
底层使用HDFS存储数据,同时依赖ZooKeeper进行集群协调服务。
Elasticsearch:一个基于Lucene的分布式全文搜索引擎。
Hive:基于Hadoop的数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的SQL查询功能,可以将SQL语句转换为MapReduce任务运行。
Storm:一个分布式的实时计算系统。
Spark:一种快速通用的Hadoop数据计算引擎。
Spark提供了一个简单而有表现力的编程模型,该模型支持广泛的应用程序,包括ETL、机器学习、流处理和图形计算。
3.1.2Hadoop1.x与2.x的架构对比 Hadoop1.x与2.x的架构对比如图3-2所示。
图3-2Hadoop1.x与2.x架构对比Hadoop1.x的主要核心组成是MapReduce和HDFS。
MapReduce不仅负责数据的计算,而且负责集群作业调度和资源(内存、CPU)管理;HDFS负责数据的存储。
Hadoop2.x在原来的基础上引入了新的框架YARN(YetAnotherResourceNegotiator)。
YARN负责集群资源管理和统一调度,而MapReduce功能变得单
一,其运行于YARN之上,只负责进行数据的计算。
由于YARN具有通用性,因此YARN也可以作为其他计算框架(例如,Spark、Storm等)的资源管理系统,不仅限于MapReduce。
这种基于YARN的共享集群方式有以下好处: 提高了资源利用率。
如果不同框架组成的集群相互独立,必然会导致资源的利用不充分,甚至出现资源紧张的情况,而共享集群的方式可以使多个框架共享集群资源,提高了资源利用率。
降低了运维成本。
使用共享集群的方式,往往只需要少数的运维人员进行集群的统一管理, 34|Hadoop大数据技术开发实战 从而降低了运维成本。
数据可以共享。
如果不同框架组成的集群相互独立,随着数据的增长,跨集群间的数据移动需要耗费更长的时间,而共享集群方式通过共享集群间的数据和资源,大大节省了数据移动时间并降低了成本。
以YARN为中心的共享集群资源架构如图3-3所示。
图3-3以YARN为中心的共享集群资源说到底,YARN其实是一个通用的资源管理系统。
所谓资源管理,就是按照一定的策略将资源(内存、CPU)分配给各个应用程序使用,并且会采取一定的隔离机制防止应用程序之间彼此抢占资源而相互干扰。
3.2YARN基本架构及组件 YARN集群总体上是经典的主/从(Master/Slave)架构,主要由ResourceManager、NodeManager、ApplicationMaster和Container等组件构成。
YARN集群架构如图3-4所示。
Client ResourceManager 程序提交节点状态资源请求任务状态 Task ContainerNodeManager 各个组件的解析如下。
ApplicationMaster Container NodeManager Task Task Container Container NodeManager 图3-4YARN集群架构 第3章Hadoop|35
1.ResourceManager ResourceManager以后台进程的形式运行,负责对集群资源进行统一管理和任务调度。
ResourceManager的主要职责如下: 接收来自客户端的请求。
启动和管理各个应用程序的ApplicationMaster。
接收来自ApplicationMaster的资源申请,并为其分配Container。
管理NodeManager,接收来自NodeManager的资源和节点健康情况汇报。

2.NodeManagerNodeManager是集群中每个节点上的资源和任务管理器,以后台进程的形式运行。
它会定时向ResourceManager汇报本节点上的资源(内存、CPU)使用情况和各个Container的运行状态,同时会接收并处理来自ApplicationMaster的Container启动/停止等请求。
NodeManager不会监视任务,它仅监视Container中的资源使用情况。
例如,如果一个Container消耗的内存比最初分配的更多,它会结束该Container。

3.Task Task是应用程序的具体执行任务。
一个应用程序可能有多个任务,如一个MapReduce程序可以有多个Map任务和多个Reduce任务(本书第5章会对MapReduce进行详细讲解)。

4.Container Container是YARN中资源分配的基本单位,封装了CPU和内存资源的一个容器,相当于是一个Task运行环境的抽象。
从实现上看,Container是一个Java抽象类,定义了资源信息。
应用程序的Task将会被发布到Container中运行,从而限定了Task使用的资源量。
Container类的部分源码如下: publicabstractclassContainerimplementsComparable{publicContainer(){} publicstaticContainernewInstance(ContainerIdcontainerId,NodeIdnodeId,StringnodeHttpAddress,Resourceresource,Prioritypriority,TokencontainerToken){ Containercontainer=(Container)Records.newRecord(Container.class);container.setId(containerId);container.setNodeId(nodeId);container.setNodeHttpAddress(nodeHttpAddress);container.setResource(resource);container.setPriority(priority);container.setContainerToken(containerToken);returncontainer;} } 从上述代码中可以看出,Container类中定义的一个重要属性类型是Resource,内存和CPU的 36|Hadoop大数据技术开发实战 资源信息正是存储于Resource类中。
Resource类也是一个抽象类,其中定义了内存和CPU核心数,该类的部分源码如下: publicabstractclassResourceimplementsComparable{publicResource(){} publicstaticResourcenewInstance(longmemory,intvCores){Resourceresource=(Resource)Records.newRecord(Resource.class);resource.setMemorySize(memory);resource.setVirtualCores(vCores);returnresource; } } Container的大小取决于它所包含的资源量。
一个节点上的Container数量,由节点空闲资源总量(总CPU数和总内存)决定。
在YARN的NodeManager节点上拥有许多动态创建的Container。
NodeManager会将计算机的CPU和内存的一定值抽离成虚拟的值,然后这些虚拟的值根据配置组成多个Container,当应用程序提出申请时,就会对其分配相应的Container。
此外,一个应用程序所需的Container分为两类:运行ApplicationMaster的Container和运行各类Task的Container。
前者是由ResourceManager向内部的资源调度器申请和启动,后者是由ApplicationMaster向ResourceManager申请的,并由ApplicationMaster请求NodeManager进行启动。
我们可以将Container类比成数据库连接池中的连接,需要的时候进行申请,使用完毕后进行释放,而不需要每次独自创建。

5.ApplicationMaster ApplicationMaster即应用程序管理者,主要负责应用程序的管理,以后台进程的形式运行。
它为应用程序向ResourceManager申请资源(CPU、内存),并将资源分配给所管理的应用程序的Task。
一个应用程序对应一个ApplicationMaster。
例如,一个MapReduce应用程序会对应一个ApplicationMaster(MapReduce应用程序运行时,会在NodeManager节点上启动一个名为“MRAppMaster”的进程,该进程则是MapReduce的ApplicationMaster实现);一个Spark应用程序也会对应一个ApplicationMaster。
在用户提交一个应用程序时,会启动一个ApplicationMaster实例,ApplicationMaster会启动所有需要的Task来完成它负责的应用程序,并且监视Task运行状态和运行进度、重新启动失败的Task等。
应用程序完成后,ApplicationMaster会关闭自己并释放自己的Container,以便其他应用程序的ApplicationMaster或Task转移至该Container中运行,提高资源利用率。
ApplicationMaster自身和应用程序的Task都在Container中运行。
ApplicationMaster可在Container内运行任何类型的Task。
例如,MapReduceApplicationMaster请求一个容器来启动MapTask或ReduceTask。
也可以实现一个自定义的ApplicationMaster来运行特定的Task,以便任何分布式框架都可以受YARN支持,只要实现了相应的ApplicationMaster 第3章Hadoop|37 即可。
总结来说,我们可以这样认为:ResourceManager管理整个集群,NodeManager管理集群中单 个节点,ApplicationMaster管理单个应用程序(集群中可能同时有多个应用程序在运行,每个应用程序都有各自的ApplicationMaster)。
3.3YARN工作流程 YARN集群中应用程序的执行流程如图3-5所示。
Client1.提交应用程序ResourceManager
2.启动ApplicationMaster3.申请资源(Container) ApplicationMaster Container NodeManager Task Container Task ContainerNodeManager Task ContainerNodeManager 图3-5YARN应用程序执行流程
(1)客户端提交应用程序(可以是MapReduce程序、Spark程序等)到ResourceManager。

(2)ResourceManager分配用于运行ApplicationMaster的Container,然后与NodeManager通信,要求它在该Container中启动ApplicationMaster。
ApplicationMaster启动后,它将负责此应用程序的整个生命周期。

(3)ApplicationMaster向ResourceManager注册(注册后可以通过ResourceManager查看应用程序的运行状态)并请求运行应用程序各个Task所需的Container(资源请求是对一些Container的请求)。
如果符合条件,ResourceManager会分配给ApplicationMaster所需的Container(表达为ContainerID和主机名)。

(4)ApplicationMaster请求NodeManager使用这些Container来运行应用程序的相应Task(即将Task发布到指定的Container中运行)。
38|Hadoop大数据技术开发实战此外,各个运行中的Task会通过RPC协议向ApplicationMaster汇报自己的状态和进度,这样 一旦某个Task运行失败时,ApplicationMaster可以对其重新启动。
当应用程序运行完成时,ApplicationMaster会向ResourceManager申请注销自己。
3.4配置集群各节点SSH无密钥登录 Hadoop的进程间通信使用SSH(SecureShell)方式。
SSH是一种通信加密协议,使用非对称加密方式,可以避免网络窃听。
为了使Hadoop各节点之间能够无密钥相互访问,使彼此之间相互信任,通信不受阻碍,在搭建Hadoop集群之前需要配置各节点的SSH无密钥登录。
3.4.1无密钥登录原理 SSH无密钥登录的原理如图3-6所示。
图3-6SSH无密钥登录原理从A服务器无密钥登录到B服务器的具体流程如下:
(1)在A服务器中生成密钥对,包括公钥和私钥。

(2)将公钥复制到B服务器的授权文件(authorized_keys)中。

(3)A服务器将访问数据用私钥加密,然后发送给B服务器。

(4)B服务器接收到数据以后,到授权文件中查找A服务器的公钥,并使用该公钥将数据解密。

(5)B服务器将需要返回的数据用A服务器的公钥加密后,返回给A服务器。

(6)A服务器接收到数据后,用私钥将其解密。
总结来说,判定是否允许无密钥登录,关键在于登录节点的密钥信息是否存在于被登录节点的授权文件中,如果存在,则允许登录。
第3章Hadoop|39 3.4.2无密钥登录操作步骤 Hadoop集群需要确保在每一个节点上都能无密钥登录到其他节点。
本例在第2章的基础上继续使用hadoop用户进行操作,使用三个节点(centos01、centos02和centos03)配置无密钥登录,无密钥登录架构如图3-7所示。
centos01节点 无密钥登录无密钥登录 centos02节点 centos03节点 图3-7无密钥登录架构 具体配置方式有两种:手动复制和命令复制,下面分别进行讲解。

1.手动复制方式
(1)将各节点的公钥加入到同一个授权文件中。
1)在centos01节点中,生成密钥文件,并将公钥信息加入到授权文件中,所需命令如下: $cd~/.ssh/ #若没有该目录,请先执行一次sshlocalhost命令 $ssh-keygen-trsa #生成密钥文件,会有提示输入加密信息,都按回车键即可 $cat./id_rsa.pub>>./authorized_keys#将密钥内容加入到授权文件中 其中.ssh文件夹为系统隐藏文件夹,若无此目录,可以执行一次sshlocalhost命令,则会生成该目录。
或者直接手动创建该目录。
2)在centos02节点中,生成密钥文件,并将公钥文件远程复制到centos01节点的相同目录,且重命名为id_rsa.pub.centos02,相关命令如下: $cd~/.ssh/ #若没有该目录,请先执行一次sshlocalhost命令 $ssh-keygen-trsa #生成密钥文件,会有提示输入加密信息,都按回车键即可 $scp~/.ssh/id_rsa.pubhadoop@centos01:~/.ssh/id_rsa.pub.centos02#远程复制 3)在centos03节点中,执行与centos02相同的操作(生成密钥文件,并将公钥文件远程复制到centos01节点的相同目录,且重命名为id_rsa.pub.centos03),相关命令如下: $cd~/.ssh/ #若没有该目录,请先执行一次sshlocalhost命令 $ssh-keygen-trsa #生成密钥文件,会有提示输入加密信息,都按回车键即可 $scp~/.ssh/id_rsa.pubhadoop@centos01:~/.ssh/id_rsa.pub.centos03#远程复制 4)回到centos01节点,将centos02和centos03节点的密钥文件信息都加入到授权文件中,相关命令如下: 40|Hadoop大数据技术开发实战 $cat./id_rsa.pub.centos02>>./authorized_keys#将centos02的密钥加入到授权文件$cat./id_rsa.pub.centos03>>./authorized_keys#将centos03的密钥加入到授权文件
(2)复制授权文件到各个节点。
将centos01节点中的授权文件远程复制到其他节点的相同目录,命令如下: $scp~/.ssh/authorized_keyshadoop@centos02:~/.ssh/$scp~/.ssh/authorized_keyshadoop@centos03:~/.ssh/
(3)测试无密钥登录。
接下来可以使用ssh命令测试从一个节点无密钥登录到另一个节点。
例如,从centos01节点无密钥登录到centos02节点,命令如下: $sshcentos02 成功登录后,记得执行exit命令退出登录。
如果登录失败,可能的原因是授权文件authorized_keys权限分配问题,分别在每个节点上执行以下命令,更改文件权限: $chmod700~/.ssh#只有拥有者有读、写权限$chmod600~/.ssh/authorized_keys#只有拥有者有读、写、执行权限 到此,各节点的SSH无密钥登录就配置完成了。

2.命令复制方式 ssh-copy-id命令可以把本地主机的公钥复制并追加到远程主机的authorized_keys文件中,该命令也会给远程主机的用户主目录(home)、~/.ssh目录和~/.ssh/authorized_keys设置合适的权限。

(1)分别在三个节点中执行以下命令,生成密钥文件: $cd~/.ssh/$ssh-keygen-trsa #若没有该目录,请先执行一次sshlocalhost命令#生成密钥文件,会有提示输入加密信息,都按回车键即可
(2)分别在三个节点中执行以下命令,将公钥信息复制并追加到对方节点的授权文件authorized_keys中: $ssh-copy-idcentos01$ssh-copy-idcentos02$ssh-copy-idcentos03 命令执行过程中需要输入当前用户的密码。

(3)测试SSH无密钥登录。
仍然使用ssh命令进行测试登录即可。
具体见本节手动复制方式的步骤
(3)
注意 如果不配置无密钥登录,Hadoop集群也是可以正常运行的,只是每次启动Hadoop都要输入密码以登录到每台计算机的DataNode(存储数据的节点)上,而一般的Hadoop集群动辄数百甚至上千台计算机,因此配置SSH无密钥登录是必要的。
第3章Hadoop|41 3.5搭建Hadoop2.x分布式集群 本例的搭建思路是,在节点centos01中安装Hadoop并修改配置文件,然后将配置好的Hadoop安装文件远程复制到集群中的其他节点。
集群各节点的角色分配如表3-1所示。
节点centos01 centos02centos03 表3-1Hadoop集群角色分配 角色NameNodeSecondaryNameNodeDataNodeResourceManagerNodeManagerDataNodeNodeManagerDataNodeNodeManager 表3-1中的角色指的是Hadoop集群各节点所启动的守护进程,其中的NameNode、DataNode和SecondaryNameNode是HDFS集群所启动的进程(HDFS将在第4章进行详细讲解);ResourceManager和NodeManager是YARN集群所启动的进程。
Hadoop集群搭建的操作步骤如下。

1.上传Hadoop并解压 在centos01节点中,将Hadoop安装文件hadoop-2.8.2.tar.gz上传到/opt/softwares/目录,然后进入该目录,解压安装文件到/opt/modules/,命令如下: $cd/opt/softwares/$tar-zxfhadoop-2.8.2.tar.gz-C/opt/modules/
2.配置系统环境变量 为了可以方便地在任意目录下执行Hadoop命令,而不需要进入到Hadoop安装目录,需要配置Hadoop系统环境变量。
此处只需要配置centos01节点即可。
执行以下命令,修改文件/etc/profile: $sudovi/etc/profile 在文件末尾加入以下内容: exportHADOOP_HOME=/opt/modules/hadoop-2.8.2exportPATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin 执行以下命令,刷新profile文件,使修改生效。
$source/etc/profile 42|Hadoop大数据技术开发实战 执行hadoop命令,若能成功输出以下返回信息,说明Hadoop系统变量配置成功: Usage:hadoop[--configconfdir][COMMAND|CLASSNAME] CLASSNAME runtheclassnamedCLASSNAME or whereCOMMANDisoneof: fs runagenericfilesystemuserclient version printtheversion jar runajarfile
3.配置Hadoop环境变量 Hadoop所有的配置文件都存在于安装目录下的etc/hadoop中,进入该目录,修改以下配置文件: hadoop-env.shmapred-env.shyarn-env.sh 三个文件分别加入JAVA_HOME环境变量,如下: exportJAVA_HOME=/opt/modules/jdk1.8.0_144
4.配置HDFS
(1)修改配置文件core-site.xml,加入以下内容: fs.defaultFShdfs://centos01:9000hadoop.tmp.dirfile:/opt/modules/hadoop-2.8.2/tmp 上述配置属性解析如下: fs.defaultFS:HDFS的默认访问路径,也是NameNode的访问地址。
hadoop.tmp.dir:Hadoop数据文件的存放目录。
该参数如果不配置,默认指向/tmp目录,而/tmp目录在系统重启后会自动被清空,从而导致Hadoop的文件系统数据丢失。

(2)修改配置文件hdfs-site.xml,加入以下内容: dfs.replication2--不检查用户权限-->dfs.permissions.enabledfalse 第3章Hadoop|43 dfs.namenode.name.dirfile:/opt/modules/hadoop-2.8.2/tmp/dfs/namedfs.datanode.data.dirfile:/opt/modules/hadoop-2.8.2/tmp/dfs/data 上述配置属性解析如下: dfs.replication:文件在HDFS系统中的副本数。
dfs.namenode.name.dir:NameNode节点数据在本地文件系统的存放位置。
dfs.datanode.data.dir:DataNode节点数据在本地文件系统的存放位置。

(3)修改slaves文件,配置DataNode节点。
slaves文件原本无任何内容,需要将所有DataNode节点的主机名都添加进去,每个主机名占一整行(注意不要有空格)。
本例中,DataNode为三个节点,配置信息如下: centos01centos02centos03
5.配置YARN
(1)重命名mapred-site.xml.template文件为mapred-site.xml,修改mapred-site.xml文件,添加以下内容,指定任务执行框架为YARN。
mapreduce.framework.nameyarn
(2)修改yarn-site.xml文件,添加以下内容: yarn.nodemanager.aux-servicesmapreduce_shuffle 上述配置属性解析如下: yarn.nodemanager.aux-services:NodeManager上运行的附属服务,需配置成mapreduce_shuffle才可运行MapReduce程序。
YARN提供了该配置项用于在NodeManager上扩展自定义服务,MapReduce的Shuffle功能正是一种扩展服务。
44|Hadoop大数据技术开发实战 也可以继续在yarn-site.xml文件中添加以下属性内容,指定ResourceManager所在的节点与访问端口(默认端口为8032),此处指定ResourceManager运行在centos01节点: yarn.resourcemanager.addresscentos01:8032 若不添加上述内容,ResourceManager将默认在执行YARN启动命令(start-yarn.sh)的节点上启动。

6.复制Hadoop安装文件到其他主机在centos01节点上,将配置好的整个Hadoop安装目录复制到其他节点(centos02和centos03),命令如下: $scp-rhadoop-2.8.2/hadoop@centos02:/opt/modules/$scp-rhadoop-2.8.2/hadoop@centos03:/opt/modules/
7.格式化NameNode启动Hadoop之前,需要先格式化NameNode。
格式化NameNode可以初始化HDFS文件系统的一些目录和文件,在centos01节点上执行以下命令,进行格式化操作: $hadoopnamenode-format若能输出以下信息,说明格式化成功:Storagedirectory/opt/modules/hadoop-2.8.2/tmp/dfs/namehasbeenessfullyformatted.格式化成功后,会在当前节点的Hadoop安装目录中生成tmp/dfs/name/current目录,该目录中则生成了用于存储HDFS文件系统元数据信息的文件fsimage(关于元数据文件将在下一章进行详细讲解),如图3-8所示。
图3-8格式化NameNode后生成的相关文件需要注意的是,必须在NameNode所在节点上进行格式化操作。

8.启动Hadoop在centos01节点上执行以下命令,启动Hadoop集群: $start-all.sh也可以执行start-dfs.sh和start-yarn.sh分别启动HDFS集群和YARN集群。
第3章Hadoop|45 Hadoop安装目录下的sbin目录中存放了很多启动脚本,若由于内存等原因使集群中的某个守护进程宕掉了,可以执行该目录中的脚本对相应的守护进程进行启动。
常用的启动和停止脚本及说明如表3-2所示。
表3-2Hadoop启动和停止脚本及说明 脚本start-all.sh-all.shstart-dfs.sh-dfs.shstart-yarn.sh-yarn.shhadoop-daemon.shstartnamenodehadoop-daemon.shnamenodehadoop-daemon.shstartdatanodehadoop-daemon.shdatanodehadoop-daemon.shstartsecondarynamenodehadoop-daemon.shsecondarynamenodeyarn-daemon.shstartresourcemanageryarn-daemon.shresourcemanageryarn-daemon.shstartnodemanageryarn-daemon.shnodemanager 说明启动整个Hadoop集群,包括HDFS和YARN停止整个Hadoop集群,包括HDFS和YARN启动HDFS集群停止HDFS集群启动YARN集群停止YARN集群单独启动NameNode守护进程单独停止NameNode守护进程单独启动DataNode守护进程单独停止DataNode守护进程单独启动SecondaryNameNode守护进程单独停止SecondaryNameNode守护进程单独启动ResourceManager守护进程单独停止ResourceManager守护进程单独启动NodeManager守护进程单独停止NodeManager守护进程 注意 ①若不配置SecondaryNameNode所在的节点,将默认在执行HDFS启动命令(start-dfs.sh)的节点上启动;②若不配置ResourceManager所在的节点,将默认在执行YARN启动命令(start-yarn.sh)的节点上启动;若配置了ResourceManager所在的节点,则必须在所配置的节点启动YARN,否则在其他节点启动时将抛出异常;③NodeManager无须配置,会与DataNode在同一个节点上,以获取任务执行时的数据本地性优势,即有DataNode的节点就会有NodeManager。

9.查看各节点启动进程 集群启动成功后,分别在各个节点上执行jps命令,查看启动的Java进程。
可以看到,各节点的Java进程如下。
centos01节点的进程: $jps135241381313351132081368814091 SecondaryNameNodeNodeManagerDataNodeNameNodeResourceManagerJps 46|Hadoop大数据技术开发实战centos02节点的进程:$jps7585NodeManager7477DataNode7789Jpscentos03节点的进程:$jps8308Jps8104NodeManager7996DataNode10.测试HDFS在centos01节点中执行以下命令,在HDFS根目录创建文件夹input,并将Hadoop安装目录 下的文件README.txt上传到新建的input文件夹中:$hdfsdfs-mkdir/input$hdfsdfs-put/opt/modules/hadoop-2.8.2/README.txt/input浏览器访问网址http://centos01:50070(需要在本地配置好域名IP映射,域名为NameNode所 在节点的主机名,关于NameNode将在第4章进行详细讲解)可以查看HDFS的NameNode信息并浏览HDFS系统中的文件,如图3-9所示。
图3-9HDFSWeb主界面 11.测试MapReduce在centos01节点中执行以下命令,运行Hadoop自带的MapReduce单词计数程序,统计/input文件夹中的所有文件的单词数量: $hadoopjarshare/hadoop/mapreduce/hadoop-mapreduce-examples-2.8.2.jar/input/output 统计完成后,执行以下命令,查看MapReduce执行结果:$hdfsdfs-cat/output/* 如果以上测试没有问题,则Hadoop集群搭建成功。
本书第4、5章将对HDFS和MapReduce做出详细讲解。
第3章Hadoop|47 第4章 HDFS 本章内容 本章首先讲解HDFS的体系结构、存储架构等理论知识,然后通过具体操作讲解HDFS的命令行和JavaAPI等实操知识。
本章目标 了解HDFS的体系结构。
掌握HDFS的存储架构。
掌握HDFS的命令行操作。
掌握HDFS的Web界面操作。
掌握HDFS的JavaAPI操作。
4.1HDFS简介 HDFS(HadoopDistributedFileSystem)是Hadoop项目的核心子项目,在大数据开发中通过分布式计算对海量数据进行存储与管理。
它基于流数据模式访问和处理超大文件的需求而开发,可以运行在廉价的商用服务器上,为海量数据提供了不怕故障的存储方法,进而为超大数据集的应用处理带来了很多便利。
下面是HDFS的一些显著特征:HDFS非常适合使用商用硬件进行分布式存储和分布式处理。
它具有容错性、可扩展性,并且扩展极其简单。
第4章HDFS|49 HDFS具有高度可配置性。
大多数情况下,需要仅针对非常大的集群调整默认配置。
HDFS是Hadoop的核心框架,而Hadoop是用Java编写的,因此可以运行于所有主流平台上。
支持类似Shell的命令直接与HDFS交互。
HDFS内置了Web服务器,可以轻松检查集群的当前状态。
4.1.1设计目标 HDFS的主要设计目标如下。

1.硬件故障硬件故障是常态,而非例外。
HDFS集群可能由数百或数千台服务器组成,每台服务器都存储文件系统数据的一部分,且每台服务器都有很大的故障概率。
因此,故障检测和快速、自动地从故障中恢复是HDFS的核心架构目标。

2.流式数据访问在HDFS上运行的应用程序需要对其数据集进行流式访问,这与运行在一般文件系统上的应用不同。
HDFS更适合批量处理,而不是用户的交互使用,它更加强调数据访问的高吞吐量,而不是数据访问的低延迟。

3.大型数据集HDFS是一个支持大型数据集的文件系统,一个典型的HDFS数据文件可以从千兆字节到兆兆字节不等,可以为具有数百个节点的集群提供高聚合的数据带宽和规模,同时承载千万个文件。

4.简单一致性模型HDFS遵循简单一致性模型,一次写入,多次读取。
即文件一旦被建立、写入、关闭,就不能被改变,更不能从文件任意位置进行修改,以此来保证数据的一致性。
Hadoop2.x以后,支持在文件末尾追加内容。

5.移动计算比移动数据容易HDFS被设计为能更好地将计算迁移到更接近数据的位置,而不是将数据移动到应用程序运行的位置,这样应用程序的计算效率会更高。
HDFS为应用程序提供接口,使其更接近数据所在的位置。

6.平台的可移植性HDFS被设计为可以从一个平台轻松地移植到另一个平台,从而使HDFS能够作为大型应用程序的首选平台。
4.1.2总体架构 HDFS是使用Java语言构建的系统,任何支持Java的计算机都可以运行HDFS,HDFS集群的总体架构如图4-1所示。
50|Hadoop大数据技术开发实战 Client NameNode SecondaryNameNode 心跳、负载均衡等 DataNode DataNode DataNode 本地磁盘 本地磁盘 本地磁盘 图4-1HDFS集群的总体架构 HDFS是一个典型的主/从(Master/Slave)架构的分布式系统。
一个HDFS集群由一个元数据节点(称为NameNode)和一些数据节点(称为DataNode)组成。
NameNode是HDFS的主节点,是一个用来管理文件元数据(文件名称、大小、存储位置等)和处理来自客户端的文件访问请求的主服务器;DataNode是HDFS的从节点,用来管理对应节点的数据存储,即实际文件数据存储于DataNode上,而DataNode中的数据则保存在本地磁盘。
当HDFS系统启动后,NameNode上会启动一个名称为“NameNode”的进程,DataNode上会启动一个名称为“DataNode”的进程。
典型的HDFS集群部署是有一台专用的计算机只运行NameNode进程,集群中的其他计算机都运行DataNode进程。
HDFS架构并不排除在同一台计算机上运行多个DataNode进程,但在实际部署中很少出现这种情况。
HDFS集群中单个NameNode的存在极大地简化了系统的体系结构。
NameNode是HDFS元数据的仲裁者和存储库。
该系统的设计方式是,用户数据永远不会流经NameNode。
此外,还有一个重要组件称为SecondaryNameNode,4.1.3节将对HDFS各组件进行详细讲解。
4.1.3主要组件 HDFS系统的主要构成组件如下。

1.数据块(Block)HDFS中的文件是以数据块(Block)的形式存储的,默认最基本的存储单位是128MB(Hadoop1.x为64MB)的数据块。
也就是说,存储在HDFS中的文件都会被分割成128MB一块的数据块进行存储,如果文件本身小于一个数据块的大小,则按实际大小存储,并不占用整个数据块空间。
HDFS的数据块之所以会设置这么大,其目的是减少寻址开销。
数据块数量越多,寻址数据块所耗的时间就越多。
当然也不会设置过大,MapReduce中的Map任务通常一次只处理一个块中的数据,如果任务数太少,作业的运行速度就会比较慢(MapReduce将在第5章讲解)。
HDFS的每一个数据块默认都有三个副本,分别存储在不同的DataNode上,以实现容错功能。
第4章HDFS|51因此,若数据块的某个副本丢失并不会影响对数据块的访问。
数据块大小和副本数量可在配置文件中更改。
HDFS数据块的存储结构如图4-2所示。
图4-2HDFS数据块的存储结构
2.NameNodeNameNode是HDFS中存储元数据(文件名称、大小和位置等信息)的地方,它将所有文件和文件夹的元数据保存在一个文件系统目录树中,任何元数据信息的改变,NameNode都会记录。
HDFS中的每个文件都被拆分为多个数据块存放,这种文件与数据块的对应关系也存储在文件系统目录树中,由NameNode维护。
NameNode还存储数据块到DataNode的映射信息,这种映射信息包括:数据块存放在哪些DataNode上、每个DataNode上保存了哪些数据块。
NameNode也会周期性地接收来自集群中DataNode的“心跳”和“块报告”。
通过“心跳”与DataNode保持通信,监控DataNode的状态(活着还是宕机),若长时间接收不到“心跳”信息,NameNode会认为DataNode已经宕机,从而做出相应的调整策略。
“块报告”包含了DataNode上所有数据块的列表信息。

3.DataNodeDataNode是HDFS中真正存储数据的地方。
客户端可以向DataNode请求写入或读取数据块,DataNode还在来自NameNode的指令下执行块的创建、删除和复制,并且周期性地向NameNode汇报数据块信息。

4.SecondaryNameNodeSecondaryNameNode用于帮助NameNode管理元数据,从而使NameNode能够快速、高效地工作。
它并不是第二个NameNode,仅是NameNode的一个辅助工具。
HDFS的元数据信息主要存储于两个文件中:fsimage和edits。
fsimage是文件系统映射文件,主要存储文件元数据信息,其中包含文件系统所有目录、文件信息以及数据块的索引;edits是HDFS 52|Hadoop大数据技术开发实战操作日志文件,HDFS对文件系统的修改日志会存储到该文件中。
当NameNode启动时,会从文件fsimage中读取HDFS的状态,也会对文件fsimage和edits进行合并,得到完整的元数据信息,随后会将新HDFS状态写入fsimage。
但是在繁忙的集群中,edits文件会随着时间的推移变得非常大,这就导致NameNode下一次启动的时间会非常长。
为了解决这个问题,则产生了SecondaryNameNode,SecondaryNameNode会定期协助NameNode合并fsimage和edits文件,并使edits文件的大小保持在一定的限制内。
SecondaryNameNode通常与NameNode在不同的计算机上运行,因为它的内存需求与NameNode相同,这样可以减轻NameNode所在计算机的压力。
SecondaryNameNode的工作流程如图4-3所示。
图4-3SecondaryNameNode的工作流程首先,当SecondaryNameNode准备从NameNode上获取元数据时,会通知NameNode暂停对文件edits的写入。
NameNode收到通知后,会停止写入edits文件,而是将新的操作日志信息写入到一个新的文件edits.new中。
然后,SecondaryNameNode通过httpget方式将NameNode的元数据文件edits和fsimage获取到本地,并将其合并为一个新的文件fsimage.ckpt。
最后,SecondaryNameNode把新的文件fsimage.ckpt通过httppost方式发回NameNode。
NameNode收到SecondaryNameNode发回的新文件fsimage.ckpt后,用该文件覆盖掉原来的fsimage文件,并删除原有的edits文件,同时将文件edits.new重命名为edits,将文件fsimage.ckpt重命名为fsimage。
上述操作避免了NameNode日志的无限增长,从而加速了NameNode的启动过程。
第4章HDFS|53 4.1.4文件读写 如图4-4所示,当客户端需要读取文件时,首先向NameNode发起读请求,NameNode收到请求后,会将请求文件的数据块在DataNode中的具体位置(元数据信息)返回给客户端,客户端根据文件数据块的位置,直接找到相应的DataNode发起读请求。
Client
1.读请求
2.返回元数据 NameNode
3.读取数据 DataNode DataNode DataNode 图4-4HDFS读数据流程 如图4-5所示,当客户端需要写文件时,首先向NameNode发起写请求,将需要写入的文件名、文件大小等信息告诉NameNode。
NameNode会将文件信息记录到本地,同时会验证客户端的写入权限,若验证通过,会向客户端返回文件数据块能够存放在DataNode上的存储位置信息,然后客户端直接向DataNode的相应位置写入数据块。
被写入数据块的DataNode也会将数据块备份到其他DataNode上。
Client
1.写请求
2.返回元数据 NameNode
3.写入数据 DataNode4.复制DataNode4.复制DataNode 图4-5HDFS写数据流程 举个例子,我们可以把NameNode想象成是一个仓库管理员,管理仓库中的商品;DataNode想象成是一个仓库,用于存储商品,而商品就是我们所说的数据。
仓库管理员只有一个,而仓库可以有多个。
当需要从仓库中获取商品时,需要先询问仓库管理员,获得仓库管理员的同意,并且得到商品所在仓库的具体位置(例如,在1号仓库的1号货架上),然后根据位置信息直接去对应的仓库中的相应货架上取得商品。
当需要向仓库中存入商品时,同样需要先询问仓库管理员,获得仓库管理员的同意,并且得到仓库管理员提供的商品能够存放的具体位置,然后根据位置信息直接去对应的仓库中的相应货架上存入商品。
54|Hadoop大数据技术开发实战 此外,用户可以使用多种客户端接口对HDFS发起读/写操作,包括命令行接口、代码API接口和浏览器接口,使用非常方便,而不需要考虑HDFS的内部实现。
本章后续将详细讲解HDFS各种接口的使用。
4.2HDFS命令行操作 HDFS的命令行接口类似传统的Shell命令,可以通过命令行接口与HDFS系统进行交互,从而对系统中的文件进行读取、移动、创建等操作。
命令行接口的格式如下:$bin/hadoopfs-命令文件路径 或者$bin/hdfsdfs-命令文件路径 上述格式中的hadoopfs和hdfsdfs为命令前缀,二者使用任何一个都可。
执行hadoopfs或hdfsdfs命令可以列出所有HDFS支持的命令列表,如下: $hadoopfsUsage:hadoopfs[genericoptions] [-appendToFile...][-cat[-ignoreCrc]...][-checksum...][-chgrp[-R]GROUPPATH...][-chmod[-R]PATH...][-chown[-R][OWNER][:[GROUP]]PATH...][-copyFromLocal[-f][-p][-l][-d]...][-copyToLocal[-f][-p][-ignoreCrc][-crc]...][-count[-q][-h][-v][-t[]][-u][-x]...][-cp[-f][-p|ax]][-d]...][-createSnapshot[]][-deleteSnapshot][-df[-h][...]][-du[-s][-h][-x]...][-expunge][-find......][-get[-f][-p][-ignoreCrc][-crc]...][-getfacl[-R]][-getfattr[-R]{-nname|-d}[-een]][-getmerge[-nl][-skip-empty-file]][-help[cmd...]][-ls[-C][-d][-h][-q][-R][-t][-S][-r][-u][...]][-mkdir[-p]...][-moveFromLocal...][-moveToLocal][-mv...] 第4章HDFS|55 [-put[-f][-p][-l][-d]...][-renameSnapshot][-rm[-f][-r|-R][-skipTrash][-safely]...][-rmdir[--ignore-fail-on-non-empty]...][-setfacl[-R][{-b|-k}{-m|-x}]|[--set]][-setfattr{-nname[-vvalue]|-xname}][-setrep[-R][-w]...][-stat[format]...][-tail[-f]][-test-[defsz]][-text[-ignoreCrc]...][-touchz...][-truncate[-w]...][-usage[cmd...]] 执行以下命令可以列出所有HDFS支持的命令及解析: $bin/hdfsdfs-help 也可以使用以下格式查看具体某一个命令的详细解析:$bin/hdfsdfs-help命令名称 下面就介绍一些HDFS系统的常用操作命令,若没有配置Hadoop的系统PATH变量,则需要进入到$HADOOP_HOME/bin目录中执行。
1.ls使用ls命令可以查看HDFS系统中的目录和文件。
例如,查看HDFS文件系统根目录下的目录和文件,命令如下: $hadoopfs–ls/ 递归列出HDFS文件系统根目录下的所有目录和文件,命令如下: $hadoopfs–ls-R/ 上述命令中的hadoopfs为操作HDFS系统的命令前缀,不可省略。
该前缀也可以使用hdfsdfs代替。
2.put使用put命令可以将本地文件上传到HDFS系统中。
例如,将本地当前目录文件a.txt上传到HDFS文件系统根目录的input文件夹中,命令如下: $hadoopfs–puta.txt/input/ 3.moveFromLocal 使用moveFromLocal命令可以将本地文件移动到HDFS文件系统中,可以一次移动多个文件。
/与put命令类似,不同的是,该命令执行后源文件将被删除。
例如,将本地文件a.txt移动到HDFS根目录的input文件夹中,命令如下: $hadoopfs–moveFromLocala.txt/input/ 56|Hadoop大数据技术开发实战 4.get使用get命令可以将HDFS文件系统中的文件下载到本地,注意下载时的文件名不能与本地文件相同,否则会提示文件已经存在。
下载多个文件或目录到本地时,要将本地路径设置为文件夹。
例如,将HDFS根目录的input文件夹中的文件a.txt下载到本地当前目录,命令如下: $hadoopfs–get/input/a.txta.txt 将HDFS根目录的input文件夹下载到本地当前目录,命令如下:$hadoopfs–get/input/./ 需要注意的是,需要确保用户对当前目录有可写权限。
5.rm使用rm命令可以删除HDFS系统中的文件或文件夹,每次可以删除多个文件或目录。
例如,删除HDFS根目录的input文件夹中的文件a.txt,命令如下:$hadoopfs–rm/input/a.txt 递归删除HDFS根目录的output文件夹及该文件夹下的所有内容,命令如下:$hadoopfs-rm-r/output6.mkdir使用mkdir命令可以在HDFS系统中创建文件或目录。
例如,在HDFS根目录下创建文件夹input,命令如下:$hadoopfs–mkdir/input/ 也可使用-p参数创建多级目录,如果父目录不存在,则会自动创建父目录。
命令如下:$hadoopfs–mkdir–p/input/file7.cp使用cp命令可以复制HDFS中的文件到另一个文件,相当于给文件重命名并保存,但源文件仍然存在。
例如,将/input/a.txt复制到/input/b.txt,并保留a.txt,命令如下:$hadoopfs–cp/input/a.txt/input/b.txt8.mv使用mv命令可以移动HDFS文件到另一个文件,相当于给文件重命名并保存,源文件已不存在。
例如,将/input/a.txt移动到/input/b.txt,命令如下:$hadoopfs–mv/input/a.txt/input/b.txt9.appendToFile使用appendToFile命令可以将单个或多个文件的内容从本地系统追加到HDFS系统的文件中。
例如,将本地当前目录的文件a.txt的内容追加到HDFS系统的/input/b.txt文件中,命令如下:$hadoopfs-appendToFilea.txt/input/b.txt 第4章HDFS|57若需要一次追加多个本地系统文件的内容,则多个文件用“空格”隔开。
例如,将本地文件a.txt和b.txt的内容追加到HDFS系统的/input/c.txt文件中,命令如下:$hadoopfs-appendToFilea.txtb.txt/input/c.txt10.cat使用cat命令可以查看并输出HDFS系统中某个文件的所有内容。
例如,查看HDFS系统中的文件/input/a.txt的所有内容,命令如下:$hadoopfs-cat/input/a.txt也可以同时查看并输出HDFS中的多个文件内容,结果会将多个文件的内容按照顺序合并输出。
例如,查看HDFS中的文件/input/a.txt和文件/input/b.txt的所有内容,命令如下:$hadoopfs-cat/input/a.txt/input/b.txt 注意在使用HDFS命令操作文件时,HDFS中的文件或目录的路径必须写绝对路径,而本地系统的文件或目录可以写相对路径。
4.3HDFSWeb界面操作 Hadoop集群启动后,可以通过浏览器Web界面查看HDFS集群的状态信息,访问IP为NameNode所在服务器的IP地址,访问端口默认为50070。
例如,本书中NameNode部署在节点centos01上,IP地址为192.168.170.133,则HDFSWeb界面访问地址为http://192.168.170.133:50070。
若本地Windows系统的hosts文件中配置了域名IP映射,且域名为centos01,则可以访问http://centos01:50070,如图4-6所示。
图4-6HDFSWeb主界面 58|Hadoop大数据技术开发实战从图4-6中可以看出,HDFS的Web界面首页中包含了很多文件系统基本信息,例如系统启 动时间、Hadoop的版本号、Hadoop的源码编译时间、集群ID等,在【Summary】一栏中还包括了HDFS磁盘存储空间、已使用空间、剩余空间等信息。
HDFSWeb界面还提供了浏览文件系统的功能,单击导航栏的按钮【Utilities】,在下拉菜单中选择【Browsethefilesystem】,即可看到HDFS系统的文件目录结构,默认显示根目录下的所有目录和文件,并且能够显示目录和文件的权限、拥有者、文件大小、最近更新时间、副本数等信息。
如果需要查看其他目录,可以在上方的文本框中输入需要查看的目录路径,按回车键即可进行查询,如图4-7所示。
图4-7HDFSWeb界面文件浏览此外,还可以从HDFSWeb界面中直接下载文件。
单击文件列表中需要下载的文件名超链接,在弹出的窗口中单击【Download】超链接,即可将文件下载到本地,如图4-8所示。
图4-8HDFSWeb界面文件下载 第4章HDFS|59 4.4HDFSJavaAPI操作 使用HDFSJavaAPI可以远程对HDFS系统中的文件进行新建、删除、读取等操作。
本节主要介绍如何在Eclipse中使用HDFSJavaAPI与HDFS文件系统进行交互。
在使用JavaAPI之前,首先需要新建一个Hadoop项目。
Hadoop项目的结构与普通的Java项目一样,只是所需依赖包不同。
在Eclipse中新建一个Maven项目“hdfs_demo”(Maven项目的搭建此处不做过多讲解),然后在该项目的pom.xml文件中添加以下代码,以引入Hadoop的JavaAPI依赖包: <.apache.hadoophadoop-client2.8.2 配置好pom.xml后,即可使用HDFSJavaAPI进行程序的编写。
4.4.1读取数据 FileSystem是HDFSJavaAPI的核心工具类,该类是一个抽象类,其中封装了很多操作文件的方法,使用这些方法可以很轻松地操作HDFS中的文件。
例如,在HDFS文件系统的根目录下有一个文件file.txt,可以直接使用FileSystemAPI读取该文件内容,具体操作步骤如下。

1.编写程序 在新建的hdfs_demo项目中新建Java类FileSystemCat.java,写入查询显示HDFS中的/file.txt文件内容的代码,代码编写步骤如下: 创建Configuration对象。
得到FileSystem对象。
进行文件操作。
完整代码如下所示: importimportimportimportimport java.io.InputStream;.apache.hadoop.conf.Configuration;.apache.hadoop.fs.FileSystem;.apache.hadoop.fs.Path;.apache.hadoop.io.IOUtils; /***查询HDFS文件内容并输出*/publicclassFileSystemCat{ 60|Hadoop大数据技术开发实战 publicstaticvoidmain(String[]args)throwsException{Configurationconf=newConfiguration();//设置HDFS访问地址conf.set("fs.default.name","hdfs://192.168.170.133:9000");//取得FileSystem文件系统实例FileSystemfs=FileSystem.get(conf);//打开文件输入流InputStreamin=fs.open(newPath("hdfs:/file.txt"));//输出文件内容IOUtils.copyBytes(in,System.out,4096,false);//关闭输入流IOUtils.closeStream(in); }}代码分析: 在运行HDFS程序之前,需要先初始化Configuration对象,该对象的主要作用是读取HDFS的系统配置信息,也就是安装Hadoop时候的配置文件,例如core-site.xml、hdfs-site.xml、mapred-site.xml等文件。
FileSystem是一个普通的文件系统API,可以使用静态工厂方法取得FileSystem实例,并传入Configuration对象参数。
FileSystem类的继承结构如图4-9所示。
图4-9FileSystem类的继承结构通过调用FileSystem对象的open()方法,取得文件的输入流。
该方法实际上返回的是一个FSDataInputStream对象,而不是标准的java.io类对象。
FSDataInputStream类是继承了java.io.DataInputStream类的一个特殊类,支持随机访问,因此可以从流的任意位置读取数据。
FSDataInputStream类的主要作用是使用DataInputStream包装一个输入流,并且使用BufferedInputStream实现对输入的缓冲。
FSDataInputStream类的部分定义源码如下:publicclassFSDataInputStreamextendsDataInputStream{}FSDataInputStream类的继承结构如图4-10所示。
图4-10FSDataInputStream类的继承结构 第4章HDFS|61
2.运行程序 直接在Eclipse中右键单击代码空白处,选择【RunAs】/【JavaApplication】运行该程序即可,若控制台中能正确输出文件file.txt的内容,说明代码编写正确。
当然,也可以将项目导出为jar包,然后上传jar包到Hadoop集群的任意一个节点上,执行以下命令运行该程序: $hadoopjarhdfs_demo.jarhdfs.demo.FileSystemCat 上述命令需要到$HADOOP_HOME/bin目录中执行,若配置了该目录的系统PATH变量,则可以在任意目录执行。
其中的hdfs_demo.jar为项目导出的jar包名称,此处为相对路径,hdfs.demo为类FileSystemCat所在的包名。
4.4.2创建目录 使用FileSystem的创建目录方法mkdirs(),可以创建未存在的父目录,就像java.io.File的mkdirs()方法一样。
如果目录创建成功,它会返回true。
下面这个例子是在HDFS文件系统根目录下创建一个名为mydir的文件夹。

1.编写程序 在新建的hdfs_demo项目中新建Java类CreateDir.java,该类的完整代码如下所示: importjava.io.IOException;.apache.hadoop.conf.Configuration;.apache.hadoop.fs.FileSystem;.apache.hadoop.fs.Path;/***创建HDFS目录mydir*/publicclassCreateDir{ publicstaticvoidmain(String[]args)throwsIOException{Configurationconf=newConfiguration(); conf.set("fs.default.name","hdfs://192.168.170.133:9000");FileSystemhdfs=FileSystem.get(conf);//创建目录booleanisok=hdfs.mkdirs(newPath("hdfs:/mydir"));if(isok){ System.out.println("创建目录成功!
");}else{ System.out.println("创建目录失败!");}hdfs.close();}}
2.运行程序 代码的运行参考4.4.1节,若控制台中能正确输出“创建目录成功!
”,说明代码编写正确。
62|Hadoop大数据技术开发实战 4.4.3创建文件 使用FileSystem的创建文件方法create(),可以在HDFS文件系统的指定路径创建一个文件,并向其写入内容。
例如,在HDFS系统根目录创建一个文件newfile2.txt,并写入内容“我是文件内容”,代码如下: /***定义创建文件方法*/publicstaticvoidcreateFile()throwsException{ Configurationconf=newConfiguration();conf.set("fs.default.name","hdfs://192.168.170.133:9000");FileSystemfs=FileSystem.get(conf);//打开一个输出流FSDataOutputStreamoutputStream=fs.create(new Path("hdfs:/newfile2.txt"));//写入文件内容outputStream.write("我是文件内容".getBytes());outputStream.close();fs.close();System.out.println("文件创建成功!");} 代码分析: FileSystem实例的create()方法返回一个文件输出流对象FSDataOutputStream,该类继承了java.io.DataOutputStream类。
与FSDataInputStream类不同的是,FSDataOutputStream类不支持随机访问,因此不能从文件的任意位置写入数据,只能从文件末尾追加数据。
create()方法有多个重载方法,允许指定是否强制覆盖已有文件(默认覆盖)、文件副本数量、写入文件的缓冲大小、文件块大小、文件权限许可等。
create()方法的其中几个重载方法的定义源码如下: publicFSDataOutputStreamcreate(Pathf)throwsIOException{}publicFSDataOutputStreamcreate(Pathf,booleanoverwrite) throwsIOException{}publicFSDataOutputStreamcreate(Pathf,shortreplication) throwsIOException{}publicFSDataOutputStreamcreate(Pathf,booleanoverwrite,intbufferSize) throwsIOException{}publicFSDataOutputStreamcreate(Pathf,booleanoverwrite,intbufferSize, shortreplication,longblockSize)throwsIOException{}publicFSDataOutputStreamcreate(Pathf,booleanoverwrite,intbufferSize, shortreplication,longblockSize,Progressableprogress) 第4章HDFS|63 throwsIOException{} 在调用create()方法时,还可以传入一个Progressable对象,该Progressable是一个接口,其中定义了一个progress()回调方法,使用该方法可以得知数据被写入数据节点的进度。
Progressable接口的源码如下: publicinterfaceProgressable{voidprogress(); } 例如,上传文件D:/soft/test.zip到HDFS根目录,并通过在控制台打印“.”显示上传进度,代码如下: publicstaticvoidmain(String[]args)throwsIOException{Configurationconf=newConfiguration();conf.set("fs.default.name","hdfs://192.168.170.133:9000");InputStreamin=newBufferedInputStream(newFileInputStream("D:/soft/test.zip"));FileSystemfs=FileSystem.get(conf);//上传文件并监控上传进度FSDataOutputStreamoutputStream=fs.create(newPath("hdfs:/test.zip"),newProgressable(){@Overridepublicvoidprogress(){//回调方法显示进度System.out.println(".");}});IOUtils.copyBytes(in,outputStream,4096,false); }} 运行上述代码,当每次上传64KB数据包到Hadoop数据节点时将调用一次progress()方法。
此外,还可以使用FileSystem的append()方法在文件末尾追加数据。
这对于日志文件需要持续写入数据非常有用。
append()方法的调用源码如下: FSDataOutputStreamoutputStream=fs.append(newPath("hdfs:/newfile2.txt")); 4.4.4删除文件 使用FileSystem的deleteOnExit()方法,可以对HDFS文件系统中已经存在的文件进行删除。
例如,删除HDFS系统根目录下的文件newfile.txt,代码如下: /***定义删除文件方法*/publicstaticvoiddeleteFile()throwsException{ Configurationconf=newConfiguration();conf.set("fs.default.name","hdfs://192.168.170.133:9000");FileSystemfs=FileSystem.get(conf); 64|Hadoop大数据技术开发实战 Pathpath=newPath("hdfs:/newfile.txt");//删除文件booleanisok=fs.deleteOnExit(path);if(isok){ System.out.println("删除成功!
");}else{ System.out.println("删除失败!");}fs.close();} 4.4.5遍历文件和目录 使用FileSystem的listStatus()方法,可以对HDFS文件系统中指定路径下的所有目录和文件进行遍历。
例如,递归遍历HDFS系统根目录下的所有文件和目录并输出路径信息,代码如下: /***递归遍历目录和文件*/publicclassListStatus{ privatestaticFileSystemhdfs;publicstaticvoidmain(String[]args)throwsException{ Configurationconf=newConfiguration();conf.set("fs.default.name","hdfs://192.168.170.133:9000");hdfs=FileSystem.get(conf);//遍历HDFS上的文件和目录FileStatus[]fs=hdfs.listStatus(newPath("hdfs:/"));if(fs.length>0){ for(FileStatusf:fs){showDir(f); }}}privatestaticvoidshowDir(FileStatusfs)throwsException{Pathpath=fs.getPath();//输出文件或目录的路径System.out.println(path);//如果是目录,则递归遍历该目录下的所有子目录或文件if(fs.isDirectory()){ FileStatus[]f=hdfs.listStatus(path);if(f.length>0){ for(FileStatusfile:f){showDir(file); }}}}} 第4章HDFS|65 上述代码通过调用FileSystem的listStatus()方法获得指定路径下的一级子目录及文件,并将结果存储于FileStatus类型的数组中;然后循环遍历该数组,当遇到目录时,再次调用listStatus()方法取得该目录下的所有子目录及文件,从而能够递归取得指定路径下的所有目录及文件。
假设HDFS文件系统的根目录有文件夹input、文件newfile.txt,文件夹input中有文件test.txt,则上述代码的输出结果为: hdfs://192.168.170.133:9000/inputhdfs://192.168.170.133:9000/input/test.txthdfs://192.168.170.133:9000/newfile.txt 4.4.6获取文件或目录的元数据 使用FileSystem的getFileStatus()方法,可以获得HDFS文件系统中的文件或目录的元数据信息,包括文件路径、文件修改日期、文件上次访问日期、文件长度、文件备份数、文件大小等。
getFileStatus()方法返回一个FileStatus对象,元数据信息则封装在了该对象中。
获取文件或目录元数据的代码如下: importimportimportimportimport java.sql.Timestamp;.apache.hadoop.conf.Configuration;.apache.hadoop.fs.FileStatus;.apache.hadoop.fs.FileSystem;.apache.hadoop.fs.Path; /***获取文件或目录的元数据信息*/ publicclassFileStatusCat{ publicstaticvoidmain(String[]args)throwsException{//创建Configuration对象Configurationconf=newConfiguration();//设置HDFS访问地址conf.set("fs.default.name","hdfs://192.168.170.133:9000");//取得FileSystem文件系统实例FileSystemfs=FileSystem.get(conf); FileStatusfileStatus=fs.getFileStatus(newPath("hdfs:/file.txt"));//判断是文件夹还是文件if(fileStatus.isDirectory()){ System.out.println("这是一个文件夹");}else{ System.out.println("这是一个文件");}//输出元数据信息System.out.println("文件路径:"+fileStatus.getPath());System.out.println("文件修改日期:" +newTimestamp(fileStatus.getModificationTime()).toString());System.out.println("文件上次访问日期:" +newTimestamp(essTime()).toString());System.out.println("文件长度:"+fileStatus.getLen()); 66|Hadoop大数据技术开发实战 System.out.println("文件备份数:"+fileStatus.getReplication());System.out.println("文件块大小:"+fileStatus.getBlockSize());System.out.println("文件所有者:"+fileStatus.getOwner());System.out.println("文件所在分组:"+fileStatus.getGroup());System.out.println("文件的权限:"+fileStatus.getPermission().toString());}} 上述代码的输出结果如下: 这是一个文件文件路径:hdfs://192.168.170.133:9000/file.txt文件修改日期:2018-07-1915:40:13.533文件上次访问日期:2018-07-1915:40:13.016文件长度:40文件备份数:2文件块大小:134217728文件所有者:hadoop文件所在分组:supergroup文件的权限:rw-r--r-- 4.4.7上传本地文件 使用FileSystem的copyFromLocalFile()方法,可以将操作系统本地的文件上传到HDFS文件系统中,该方法需要传入两个Path类型的参数,分别代表本地目录/文件和HDFS目录/文件。
例如,将Windows系统中D盘的copy_test.txt文件上传到HDFS文件系统的根目录,代码如下: /***定义方法,上传本地文件到HDFS*/publicstaticvoiduploadFileToHDFS()throwsException{//1.创建配置器Configurationconf=newConfiguration();conf.set("fs.default.name","hdfs://192.168.170.133:9000");//2.取得FileSystem文件系统实例FileSystemfs=FileSystem.get(conf);//3.创建可供hadoop使用的文件系统路径Pathsrc=newPath("D:/copy_test.txt");//本地目录/文件Pathdst=newPath("hdfs:/");//HDFS目录/文件//4.复制上传本地文件至HDFS文件系统中fs.copyFromLocalFile(src,dst);System.out.println("文件上传成功!
");} 4.4.8下载文件到本地 使用FileSystem的copyToLocalFile()方法,可以将HDFS文件系统中的文件下载到操作系统本 第4章HDFS|67 地,该方法需要传入两个Path类型的参数,分别代表HDFS目录/文件和本地目录/文件。
例如,将HDFS文件系统根目录的文件newfile2.txt下载到Windows系统中D盘根目录,并重命名为new.txt,代码如下: /***定义方法,下载文件到本地*/publicstaticvoiddownloadFileToLocal()throwsException{//1.创建配置器Configurationconf=newConfiguration();conf.set("fs.default.name","hdfs://192.168.170.133:9000");//2.取得FileSystem文件系统实例FileSystemfs=FileSystem.get(conf);//3.创建可供hadoop使用的文件系统路径Pathsrc=newPath("hdfs:/newfile2.txt");//HDFS目录/文件Pathdst=newPath("D:/new.txt");//本地目录/文件//4.从HDFS文件系统中复制下载文件至本地fs.copyToLocalFile(false,src,dst,true);System.out.println("文件下载成功!
");}

标签: #驾驶证 #certainly怎么读 #文件 #clothes #crayon #满了 #文件 #满了