第 4 章 Hadoop 基础

4.1 Hadoop历史、生态系统

4.1.1 Hadoop 简介

在这个大数据爆发的时代,人们在利用手机和电脑进行社交、购物、网络游戏等活动时会产生大量的 数据,公司的交易、财务记录,保险公司的保险记录等等每天都会留下大量的信息,现在很多公司每天 产生的信息量已经从 TB级上升到PB 级,面对如此浩瀚的数据,如何对其进行更有效的存储 并从中探索出数据的规律,成为了数据工程师们面对的难题。

传统的数据仓库和OLAP(Online Analytical Processing)的分析模式在海量数据前显得苍白无力, 基于分布式思维构建的Hadoop则给出了一个很好的解决方案。Hadoop是Apache软件基金下的一个开 源的分布式计算平台。它可以运行在成千上万个普通机器的节点组成的集群上,并通过分布式的计算模型 和存储模型来处理大数据集。Hadoop分布式文件系统(Hadoop Distributed File System)和 MapReduce(Google MapReduce 的开源实现)为用户提供了底层的分布式基础架构和分布式并行处理 的程序支持。Hadoop具有高扩展性、高效性、高容错性和低成本等优点,现在已经有越来越多的 公司选择Hadoop作为自己的大数据处理分析工具。

4.1.2 Hadoop 的历史

Hadoop 起源于2002年的Apache Nutch项目,是Apache Lucene创始人Doug Cutting创建 的,他对Hadoop这一名称的来历这样解释:“这个名字是我的孩子给一头吃饱了的棕黄色大象起的。我的 命名标准是简短,容易发音和拼写,没有太多的含义,并且不会被用于别处。”因此,我们现在看 到Hadoop 的图标都是大象了。除此之外,Hadoop的其他子项目也秉承了这一传统,如“Pig”就是动物的名 字。

在Nutch项目中,开发者发现他们的网页爬取工具和搜索引擎不能解决数十亿网页的搜索问题。2003年 谷歌发表的一篇论文(即为谷歌的分布式文件系统GFS)为他们提供了很多思路,2004年他们开发了自己 的分布式文件系统(NDFS)。2004年谷歌又发表论文介绍他们自己的 MapReduce 系统。2005年,Nutch 的开发人员在Nutch 上实现了一个MapReduce 系统。 在2006年2月,开发人员 将NFDS 和MapReduce 移出Nutch 形成 Lucene 的一个子项目,成为Hadoop并且最终成为了Apache基 金会的顶级项目。截止到2018年10月份,Hadoop 的版本已经更新到3.1.1。

Hadoop 2.0版本指的是Apache Hadoop 0.23.x、2.x 或者CDH4 系列的Hadoop,相比Hadoop 1.0 ,Hadoop 2.0 在HDFS的架构与MapReduce上都有较大的变化,且速度上和可用性上都有了很大的提 高。主要有两方面的改进:第一,HDFS的NameNodes可以以集群的方式布署,增强了NameNodes的水平扩 展能力和可用性;第二,MapReduce将JobTracker中的资源管理及任务生命周期管理(包括定时触发及 监控),拆分成两个独立的组件,并更名为YARN(Yet Another Resource Negotiator)。其中,YARN 是一个资源管理系统,它主要负责集群资源管理和调度,而Mapreduce 则是运行在YARN 上的离线处理框 架,它与Hadoop 1.0 中的Mapreduce 在编程模型(新旧API)和数据处理引擎 (MapTask 和 ReduceTask )两方面是相同的。Hadoop 2.0(YARN)允许每个节点(NodeManager)配置 可用的CPU和内存资源总量,而中央调度器则会根据这些资源总量分配给应用程序。为了更好地分配与利 用资源,YARN允许管理员根据实际需要和CPU性能将每个物理CPU划分成若干个虚拟CPU,同时也可以单独 配置每个节点需要的虚拟CPU个数,还有一种方法是在用户提交应用程序时,也可指定每个任务需要的虚 拟CPU个数。同时,Hadoop 2.0还引入了基于Cgroups的轻量级资源隔离方案,这大大降低了同节点上任 务间的相互干扰,而Hadoop 1.0仅采用了基于JVM的资源隔离,粒度非常粗糙。

4.1.3 Hadoop与传统集群的比较

Hadoop的本质是一种专门为存储和分析海量非结构化数据而设计的特定类型的计算集群,相较于以往的传统集群而言,Hadoop在很多方面都存在优势,这也是目前Hadoop被广泛应用的重要原因之一。具体体现在以下几个方面:

一、适合处理海量大数据。Hadoop的工作原理在于将数据拆分成片,然后将每个“分片”分配到特定的集群节点上进行分析。其对数据的均匀分布没有要求,因为每个“分片”都是在独立的集群节点上被单独处理的。Hadoop对于海量大数据的适用性体现容量规模和数据多样性两个方面:传统集群在容量规模方面一般是实现由GB到TB的转变,Hadoop集群则实现了由GB到TB再到PB及以上的转变;此外,传统集群大多仅适用于结构化数据,而Hadoop集群可以适用于结构化数据、半结构化数据和非结构化数据。

二、灵活的可拓展性。大数据分析中面临的一个重要问题是数据量的不断增加,很多应用场景下需要对其进行实时或接近实时地分析处理。虽然并行处理可以极大提高分析速度,但是随着数据量的增加,处理速度仍然可能受到影响。然而,Hadoop集群通过添加集群节点可以有效地拓展集群,这也使得Hadoop具有灵活的可拓展性。

三、高容错能力。在Hadoop中,当一个分片数据被发送到某个集群节点时,会自动拷贝一份数据副本存放到集群的其它节点上。通过这种方式,即使一个节点发生了故障,该节点存放的数据仍可以在其它节点上获取得到,不会影响到对该数据的分析处理。相对而言,传统集群的容错能力完全取决于关键节点,对大量数据的备份和恢复均较为困难。

四、低成本。一方面,Hadoop集群所需的软件是开源的,可以自由下载Apache Hadoop发行版,而传统集群的软件采购成本及后续服务费很高;另一方面,Hadoop集群支持商用硬件,不需要购买服务器级硬件,而传统集群对服务器配置的要求很高。

五、应用价值高。传统集群侧重的是数据的操作性,同时兼顾统计报表;Hadoop集群更关注数据的业务决策价值,强调数据挖掘与综合分析。

4.1.4 Hadoop 的生态系统

Hadoop 的两大核心是HDFS 和MapReduce。整个的Hadoop 的体系结构主要通过HDFS 实现分布式存储的底 层支持,通过MapReduce 实现分布式并行处理的程序支持。但是在Hadoop 上还有Hive 、Hbase 、Pig 、Zookeeper 、 Chukwa 、Avro 等项目:其中Hive 是建立在Hadoop 上的数据仓库,它提供了类SQL语句来实现对Hadoop 文件中的 数据进行整理、特殊查询和分析存储,避免了用户进行大量的编码工作;Hbase 是一个分布式的面向列的开源数据 库,主要用于需要随机访问、实时读写的大数据;Pig 是一个对大型数据集进行分析、评估的平台,它最突出 的优势是它的结构能够经受住高度并行化的检验,这一功能使得它能处理大型的数据集;ZooKeeper是 一个分布式的,开放源码的分布式应用程序协调服务,是Hadoop和Hbase的重要组件,它是一个为分 布式应用提供一致性服务的软件,提供的功能包括:配置维护、名字服务、分布式同步、组服务等; Chuwa 是开源的数据收集系统,用于监控和分析大型分布式系统的数据;Avro是新的数据序列 化格式与传输工具,将逐步取代Hadoop原有的IPC机制。

4.1.5 Hadoop 的组成模块

Hadoop的组成模块主要有NameNode、DataNode、Secondary NameNode、JobTracker、 TaskTracker五部分,其中NameNode、DataNode、Secondary NameNode是HDFS内的组件,JobTracker、 TaskTracker是MapReduce内的组件。

NameNode是HDFS的主节点,维护着文件系统树以及文件树中所有的文件和文件夹的元数据以及每个文件对应的数据块列表,并进行文件的拆分调度,跟踪文件如何分解为文件块,哪些节点存储这些文件块以及分布式文件系统的总体运行状况,一个HDFS集群内仅有一个NameNode。Namenode记录着每个文件中各个块所在的数据节点的位置信息,但是他并不持久化存储这些信息,因为这些信息会在系统启动时从数据节点重建。 NameNode进行信息管理的文件有两个,分别是分别是Namespace镜像文件(fsimage)和操作日志文件(edit logs)。fsimage储存元数据信息,是在NameNode启动时对整个文件系统的快照;edit logs是对文件的操作日志。只有在NameNode重启时,edit logs才会合并到fsimage文件中,从而得到一个文件系统的最新快照。但是在产品集群中NameNode很少重启,这也意味着当NameNode运行了很长时间后,edit logs文件会变得很大,从而产生edit logs文件过大不易管理和NameNode重启时合并文件耗时过长的问题,如果NameNode发生损坏,edit logs中未被合并到fsimage文件中的操作就会丢失。 NameNode是Hadoop集群的单点故障,如果NameNode损坏,其对分布式系统的掌控就会缺失,分布式系统停止运行,系统中的文件将会完全丢失。因此,namenode的容错机制非常重要,Hadoop提供了两种机制。 第一种方式是将持久化存储在本地硬盘的文件系统元数据备份。Hadoop可以通过配置来让Namenode将他的持久化状态文件写到不同的文件系统中。这种写操作是同步并且是原子化的。第二种方式是运行一个辅助的Namenode(Secondary Namenode)。

DataNode是文件系统的工作节点,集群中的每台工作计算机将托管一个DataNode程序。DataNode根据NameNode的指令调度存储和检索数据,读取HDFS块并将其写入本地文件系统上的实际文件。DataNode不断向NameNode报告,以使NameNode能够实时掌握DataNode所在的worker节点上数据的情况,并接收NameNode发布的有关从本地磁盘创建,移动或删除块的指令。 如果某一节点上DataNode发生损坏,NameNode会调取其他节点上的相应数据继续进行工作,当该DataNode进行修复后,NameNode可根据原指令恢复该DataNode内的数据。

Secondary NameNode是集群内NameNode的辅助守护程序,每个群集都有一个Secondary NameNode。 Secondary Namenode并不能被用作Namenode但可以用来恢复NameNode,有助于最大程度地减少由于NameNode故障而导致的停机时间和数据丢失。 Secondary NameNode定时到NameNode去获取edit logs,并更新到Secondary NameNode的fsimage上。当Secondary NameNode拥有新的fsimage文件,它会将其拷贝回NameNode中。NameNode在正常重启或故障排除后重启时会使用这个新的fsimage文件,从而减少重启的时间和防止数据丢失。 通常,Secondary Namenode运行在一个单独的物理机上,因为合并操作需要占用大量的CPU时间以及和Namenode相当的内存。

JobTracker是整个MapReduce计算框架中的主服务,通常在服务器上作为群集的主节点运行,一个MapReduce集群中仅有一个JobTracker。JobTracker通过确定要处理的文件来确定执行计划,将不同的任务分配到不同节点运行,并通过检测TaskTracker的周期性心跳来监视所有正在运行的任务以及节点的健康状况。若发现异常情况可以向TaskTracker发送ReinitTrackerAction(重新初始化)、LauchTaskAction(运行新任务)、KillTaskAction(杀死任务)、KillJobAction(杀死作业)和CommitTaskAction(提交任务)等命令进行处理。 在MapReduce中,若因JobTracker存在单点故障问题导致异常退出后重启,那么所有正在运行的作业运行时信息将丢失。如果不采用适当的作业恢复机制对作业信息进行恢复,则所有作业需重新提交,且已经计算完成的任务需重新计算。这势必造成资源浪费。 为了解决JobTracker面临的单点故障问题,Hadoop设计了作业恢复机制,过程如下:作业从提交到运行结束的整个过程中,JobTracker会为一些关键事件记录日志(由JobHistory类完成)。对于作业而言,包括作业提交、作业创建、作业开始运行、作业运行完成、作业运行失败、作业被杀死等关键事件;对于任务而言,包括任务创建、任务开始运行、任务运行结束、任务运行失败、任务被杀死等关键事件。当JobTracker因故障重启后(重启过程中,所有TaskTracker仍然活着),如果管理员启用了作业恢复功能,则JobTracker会检查是否存在需要恢复运行状态的作业,如果有,则通过日志恢复这些作业的运行状态,并重新调度那些未运行完成的任务(包括产生部分结果的任务)。 对于小型系统来说,jobtracker一般情况下都不做具体数据处理计算,运行在master节点上即可;对于大型系统来说可能需要独立的jobtracker处理器。

TaskTracker是JobTracker和Task之间的桥梁,一个MapReduce集群中的每一个worker节点上都有一个TaskTracker。TaskTracker从JobTracker接收并执行各种命令,包括运行任务、提交任务、杀死任务等;以此同时,TaskTracker将本地节点上的各种信息通过心跳周期性汇报给JobTracker,汇报的信息包括任务执行方面信息如任务执行进度、运行状态等;以及机器健康状况信息如节点健康状况、资源使用情况等。TaskTracker与JobTracker和Task之间采用了RPC协议进行通信。

4.2 分布式文件系统(HDFS)

4.2.1 HDFS 简介

Hadoop 的分布式文件系统HDFS(Hadoop Distributed File System)是Hadoop 的主要的存储系 统。Hadoop 是一个综合性的文件系统抽象,它提供了文件系统实现的各种接口。而我们本节要讲 的HDFS只是其中的一个实现。HDFS 不仅可用来创建、删除、移动、重命名文件,还有很多不同之处包括 读/写数据流等。

从物理存储中读取数据的速度受限于磁盘I/O的上限,同时大量数据的网络传输也会消耗大量时间,因此 想要实现高效的大数据存储和读取,需要将数据可能地存储在多个节点中,并且我们希望每个节点 的数据处理都可以在节点上完成。这样可以尽量减少数据的传输量,提高处理效率。HDFS基于一次写入、多 次读取的思路构建,这样可以保证高效的访问,同时HDFS以流式数据访问模式来存储超大文件,这里的 超大文件指具有几百MB 、几百GB 甚至几百TB 大小的文件,流式数据访问是指我们每次分析数据都将 涉及到数据集的大部分甚至全部,因此读取整个数据集的时间延迟比读取第一条记录的时间延迟更 重要。Hadoop 不需要运行在价格昂贵可靠的机器上,它可以运行在普通的商用硬件集群上。这样 做的好处是花费较少,但是故障率较高。但是HDFS 遇到上述故障时,被设计成能够持续运行且不让 用户察觉到明显的中断。这也是Hadoop 的优势之一。

HDFS可用来处理PB 级的数据,它的组成包括NameNode和DataNode,这是HDFS的核心。其中NameNode 只有一个,主要用于管理存储数据的元数据,而DataNode 可以有多个,主要是用来直接存储数据。 在DataNode 存储数据块时,会默认根据一定的规则在机器的不同DataNode 中存储3份,以防止数据发生 损坏而造成不可挽回的损失。

HDFS 有很多优良的特性,比如它是一个高容错的系统,可以部署在一般的普通机器上,它的高容错率防 止数据出问题,即使一个普通节点上的数据出现问题,它也能很好地处理。Hadoop 的文件模型是一次写 入,多次读取,一旦HDFS 上的文件被创建并写入了内容,关闭后不需要再对它进行更改(但支持文件追 加),此方法也大大提高了HDFS处理文件的吞吐量。

对于一些应用尽管数据量大,但是并不适合运行在HDFS 上,包括要求低时间延迟的数据访问,对于这样 的数据要求在几十毫秒内访问数据,HDFS 还没达到这一要求。其次是HDFS不适合处理大量的小文件,引 文NameNode 将文件系统的元数据存储在内存中,因此该文件系统所能存储的文件总数受制于 NameNode 的内存容量。最后,HDFS不适合处理多用户写入,任意修改的文件。HDFS 中的文件可能只有一个写入 者 ,而且写操作总是将数据添加在稳健的末尾。因此它不支持具有多个写入者的操作,也不支持在文件 的任意位置进行修改。

4.2.2 HDFS 的体系结构

大家都知道我们的计算机磁盘都有容量,这里面也会分出很多的数据块(DATA BLOCK),每个数据块有默 认的大小,数据块是磁盘进行读/写的最小单位,多个数据块组成文件系统块。文件系统块一般为几千 字节,而磁盘块一般512字节。但是系统自身也提供了一些工具(如 df 和 fsck )来维护文件系统,它 们直接对文件中的块进行操作。

在HDFS文件系统中,每个数据文件也被分成多个数据块(Chunk),来作为独立的存储单元。 HDFS默认的数据块大小是64MB,也可以设置成32MB或128MB。一个大的文件会被分为多个数据块来存储,而对于小于块大小 的文件则不会占据整个块的空间。为什么HDFS上的块设置的这么大,可以参见(Hadoop 权威指南 第二版 p43)。

对于分布式文件系统中块进行抽象能带来很多好处。比如,一个文件的大小可以大于网络中任意一个磁 盘的容量。这样对于一些较大的文件,就不必存储一个磁盘上,可以充分利用集群上的磁盘空间。同时 可以仅存储一个文件,该文件的块占满集群中所有的磁盘。其次是,使用块而非整个文件作为存储单元, 大大简化了存储子系统的设计。这样可以简化存储管理同时消除了对元数据的顾虑。块还非常适合适用 于数据备份进而提供数据容 错能力和可用性。HDFS 默认将块复制到3 个不同的机器上,这样保证了当其 中一个发生错误或故障时,其他的相同的数据仍可运行。

对于文件系统的管理,HDFS采用master/slave 架构。HDFS 的体系结构有两类节点,一类 是NameNode(master),一类是DataNode(slave)。NameNode 只有一个,主要承担管理者的角色,它负 责管理文件系统的命名空间(Namespace)以及客户端对文件的访问。NameNode 执行文件系统的名字空 间的操作如打开、关闭、重命名文件或目录。它也负责确定数据块到具体DataNode 节点的映射,记录着 每个文件中各个块所在数据节点的信息,类似于一个目录的作用,但是它不能永久保存块的信息,因为这些信息会在系统重建时 由数据节点重建。

DataNode 有多个,它是文件系统的工作节点,它在HDFS中真正存储了数据。HDFS 展示了文件系统的命名空间,用户能够以文件的形式 在上面存储数据。在系统内部,一个文件被分成一个或多个数据块,这些数据块存在一 组DataNode 上。NameNode 和DataNode 的交互是通过客户端(client)的用户来访问整个文件系统。客 户端提供了一种类似于POSIX(可移植操作系统界面)的文件系统接口,以便用户在不清 楚NameNode 和DataNode 运行机制的情况下也能实现他们的功能。DataNode根据需要存储并检索数据块 (受客户端或NameNode调度),并且定期向NameNode 发送它们所存储的块的列表。也即是说,没 有NameNode ,文件系统将无法使用。因为一旦运NameNode 服务的机器毁坏,文件系统上的所有文件将会 丢失,因为我们不知道如何根据DataNode 的块来重建文件。

Hadoop 提供了两种对NameNode 的容错机制。第一种是备份那些组成文件系统元数据持久状态的文 件。Hadoop 通过配置使NameNode 在多个文件系统上保存元数据的持久状态。这些写操作时实时同步的。 第二种配置是运行一个辅助的NameNode ,但它不能被用作NameNode。它的作用是定期通过编辑日志合并 命名空间镜像,以防止编辑日志过大。

4.2.3 HDFS 基本文件系统操作

首先,我们先来了解下HDFS的命令行接口。附录上我们介绍了伪分布式下Hadoop 的说明和集群的说明, 此外读者也可参考(???)(???)(???) 等。

在我们设置伪分布式时,有两个属性需要解释。第一项是fs.default.name 设置 为:hdfs://localhost/ ,主要用于设置Hadoop 的默认文件系统。文件系统是由 URI指定的, 这里我们使用了HDFS URI 来配置HDFS 为Hadoop 的默认文件系统。HDFS 的守护程序将通过该属性项来 确定HDFS的NameNode 的主机及接口。默认情况下是在localhost 默认端口8020 下运行NameNode。第二 个属性是dfs.replication , HDFS 默认设置将文件系统块复本设为3,如果我们改为1,在单 独一个DataNode运行时,HDFS将无法将块复制到其他DataNode 上,因此它会持续给出块副本不足的警 告。

HDFS 的文件系统操作包括:读取文件、创建目录、移动文件、删除数据、列出目录等。可以输 入:

    $ hadoop fs –help

命令获取所有命令的详细帮助文件。

如果将本地文件test.txt(在 /home/dmc/input/ 路径下)上传 到HDFS的/user/dmc/路径下,相应的命令行是:

    $ hadoop fs –copyFromLocal /home/dmc/input/test.txt \
       hdfs://localhost/user/dmc/test.txt

因为在我们的core-site.xml 中已经设置了URI的默认设置 (hdfs://localhost/),因此上述命令可以简写为:

    $ hadoop fs –copyFromLocal /home/dmc/input/test.txt \
       /user/dmc/test.txt

我们也可以使用相对路径,并将文件复制到HDFS 的home 目录中,本例为:

    $ hadoop fs –copyFromLocal /home/dmc/input/test.txt test.txt

我们可以把文件复制回本地,并检查两个文件是否还一致:

    $ hadoop fs –copyToLocal test.txt test.copy.txt

这样HDFS 上的test.txt 文件就被复制到本地当前路径下命名为:test.copy.txt 检验和当前路径下的是否一致:

    $ md5sum test.txt test.copy.txt

出现如下结果:

    d41d8cd98f00b204e9800998ecf8427e  test.txt
    d41d8cd98f00b204e9800998ecf8427e  test.copy.txt

这里MD5键值相同,表明这个文件在HDFS 中保存完整。

下面我们在HDFS 中创建目录并在列表中进行显示:

    $ hadoop fs –mkdir test
    $ hadoop fs –ls

    Found 4 items
    drwxr-xr-x   - dmc supergroup          0 2015-07-30 23:50 input
    drwxr-xr-x   - dmc supergroup          0 2015-07-30 23:53 output
    drwxr-xr-x   - dmc supergroup          0 2015-08-30 09:54 test
    -rw-r--r--   1 dmc supergroup          0 2015-08-30 09:42 test.txt

从这里可以看出返回的信息和我们在Linux 系统中看到的有些类似,仅有细微的差别就是在第二列 中test.txt 文件中的数字 1,这里的意思是在HDFS 文件系统中 test.txt 的副本只有一份。而在我们 新建的目录 test 中,由于我们还没有在里面存放东西,所以看到的只有空值,只是将目录作为元数据 放在了NameNode中,而非DataNode 中。

4.2.4 接口

Hadoop 是用Java 写的,通过Java API 可以调用所有Hadoop 文件系统的交互操作。

让我们先来了解一下Hadoop 的文件系统(见表\[tab:hadoop-fs\]),正如前面所说Hadoop 是一个综 合性抽象的文件系统概念。Java 抽象类 org.apache.hadoop.fs.FileSystem定义 了Hadoop 的一个文件系统接口,并且该抽象类有几个具体实现。

Hadoop
文件系统 URI 方案 Java 实现(org.apache.org) 定义
Local File fs.LocalFileSystem 支持客户端校验和本地的文件系统
HDFS hdfs hdfs.DistributedFileSystem Hadoop 的分布式文件系统
HFTP hftp hdfs.HftpFileSystem 支持HTTP方式以只读的方式访问HDFS,通常与 distcp 结合使用
HSFTP hsftp hdfs.hsftpFileSystem 在HTTPS 上提供对HDFS 只读访问的文件系统
HAR har fs.HarFileSystem 一个构建在其他系统之上的用于文件存档的文件 系统
KFS kfs fs.kfs.kosmosFileSystem Cloudstore 文件系统是类似于HDFS 和谷歌GFS 文件系统
FTP ftp fs.ftp.FTPFileSystem 由FTP 服务器支持的文件系统
S3(原生) s3n fs.s3native.NativeS3FileSystem 由 Amazon S3 支持的文件系统
S3(基于块) s3 fs.s3.NativeS3FileSystem 基于Amazon S3 的文件系统

如果想查看Hadoop 的文件系统可以使用命令:

    $ hadoop fs –ls file://

HDFS 的接口主要有Thrift 、C语言、FUSE WebDAV、HTTP、FTP 和Java 接口。

4.2.5 Hadoop 存档

前面已经介绍过,Hadoop 存储文档的块默认为64 MB ,如果文档没有这么大,如只有10MB ,也会耗费 一个块。Hadoop 存档工具或HAR 文件,是一个高效的文件存档工具,它将文件存到HDFS块,在减 少NameNode 使用的同时,还能允许对文件进行透明的访问。也就是说,Hadoop的存档文件可以作 为MapReduce 的输入。

Hadoop 存档是通过 archive 工具根据一组文件创建而来。该存档工具运行一个MapReduce 作业来并行 处理所有的输入文件,因此需要一个MapReduce 集群来运行和使用它。我们使用HDFS 中的一些文档进行 存档:

    $ hadoop fs –lsr ./myfiles/a
    drwxr-xr-x  - dmc supergroup      0 2015-08-30 12:09 myfiles/a/aa
    drwxr-xr-x  - dmc supergroup      0 2015-08-30 12:09 myfiles/a/bb
    drwxr-xr-x  - dmc supergroup      0 2015-08-30 12:09 myfiles/a/cc

运行archive 命令:

    $ hadoop archive –archiveName myfiles.har ./myfiles/a  \
       /myfiles

删除文件:

    $ hadoop fs - rmr  /myfiles/files.har

不足之处就是创建一个har文件就会在原始文件的基础上,创建一个原始文件的副本,要消耗至少和文件 容量大小的磁盘空间。虽然存档文件中源文件能被压缩,但是不支持压缩文件压缩。并且一旦创建, 文件不能被修改,若想修改文件必须重新创立文档文件。

4.2.6 访问HDFS

HDFS通过URI(Uniform Resource Identifier, URI)对数据资源进行标识。URI的标准格式为格式为Scheme://Authority/Path。 其中Scheme即为HDFS,Authority为HDFS中NameNode的主机名,Path则是文件或目录的路径。在标准伪分布式的HDFS下, 想要通过绝对路径访问HDFS,需要配置core-site.xml的如下:

<property> <name>fs.defaultFS</name> <value>hdfs://localhost:9000</value> </property>

此外,也可以通过"hdfs://localhost:9000/user/hadoop的方式访问hdfs,其中$USER是用户的登录名, 此时,需要配置hdfs-site.xml如下:

<property> <name>dfs.namenode.rpc-address</name> <value>hdfs://localhost:9000</value> </property>

进一步,也可以通过设定"dfs.namenode.rpc-bind-host"来使得外网可以访问HDFS,hdfs-site.xml配置 如下:

<property> <name>dfs.namenode.rpc-bind-host</name> <value>0.0.0.0</value> </property>

其中的<value>会替换上面的"dfs.namenode.rpc-address"的取值,使得HDFS在外网可见。

4.2.7 其他命令

HDFS 还提供了一些常见的命令供我们处理文件:

  • NameNode -format : 格式化DFS 文件系统

  • dfsadmin :运行DFS 的管理客户端

  • NameNode :运行DFS 的NameNode 进程

  • DataNode :运行DFS 的DataNode 进程

  • secondNameNode :运行DFS的 secondNameNode 进程

  • fsck :运行HDFS 的检测进程

  • balancer :运行一个文件系统平衡进 程

  • jobtracker :运行一个JobTracker 进程

  • pipes:运行一个Pipes 任务

  • tasktracker :运行一 个TaskTracker任务

  • queue :获得运行中的MapReduce 队列的信息

这些命令的统一的格式是:

    $ hadoop command [generations] [commandOperations]

4.2.8 小型Hadoop项目实操

使用命令

      hadoop

即可查看hadoop相关命令信息,x想要获知hadoop版本信息,可使用命令

      hadoop version

想要查看hadoop内环境变量配置,可使用echo命令,Linux里的环境变量以$符号唤起,如查看JAVA_HOME的环境变量配置可使用命令

      echo $JAVA_HOME

对分布式文件系统的操作要通过hadoop fs命令来提交。 使用命令

      hadoop fs -ls /

可查看分布式文件系统的根目录,使用命令

      hadoop fs -ls /user

可查看分布式文件系统内用户文件夹下内容,使用命令

      hadoop fs -ls 

可查看当前登录用户文件夹下内容,若当前登录用户为student,则上述命令与命令

      hadoop fs -ls /user/student

效果相同。 hadoop内所有的操作都是bach的操作,是非交互的操作,操作过程中必须指定路径,没有切换到其他文件夹下的交互功能。 hadoop fs内嵌了包括cat函数在内的操作函数,部分函数在Linux Basics章节内有所介绍。 如想要打印/user/student/example.txt文件内容,可使用命令

      hadoop fs -cat /user/student/example.txt

若想要保存HDFS内的文件到本地可以使用get命令,如保存/user/student/example.txt文件到本地可使用命令

      hadoop fs -get /user/student/example.txt .

上述命令中’.’指当前位置,需要注意的是文件储存在HDFS中时,是拆成小份分别存放在不同worker节点上面的,在操作get命令时,NameNode找到每一块文件所在的DataNode,命令DataNode将其所在的worker节点内储存的文件块发回到master,master整合后再将其存放到本地硬盘内。

若想要上传本地文件至HDFS内,可以使用put命令,如将本地的/opt/apps/ecm/service/hive/2.3.3-1.0.2/package/apache-hive-2.3.3-1.0.2-bin/binary-package-licenses/asm-LICENSE文件上传至HDFS当前用户文件夹下可使用命令

      hadoop fs -put /opt/apps/ecm/service/hive/2.3.3-1.0.2/package/apache-hive-2.3.3-1.0.2-bin/binary-package-licenses/asm-LICENSE .

若想在分布式文件系统内创建文件夹,可使用命令mkdir,如在当前用户下创建’exam’文件夹

      hadoop fs -mkdir /user/student/exam

若想在分布式文件系统内删除文件夹,可使用命令rm,如删除当前用户下的’exam’文件夹

      hadoop fs -rm -r /user/student/exam

HDFS内进行的删除工作并不是真正的删除,而是在HDFS内开辟出一块回收站,删除的文件存放在回收站内。

下面将尝试使用hadoop的hadoop-streaming模块进行/user/student/example.txt文件的字符数统计工作。 首先查看需要使用的命令在Hadoop内的存储地址,本例中需要查看cat命令与wc命令地址,具体命令如下

      which cat 

      which wc 

删除放置目标输出文件夹内的原有输出文件

      hadoop fs -rm -r /user/student/output 

执行相应程序使用命令

      hadoop jar $HADOOP_HOME/share/hadoop/tools/lib/hadoop-streaming-2.7.2.jar -input /user/student/example.txt  -output /user/student/output -mapper "/bin/cat" -reducer "/bin/wc" 

其中,jar是执行相应程序所需配置内容,-input部分是所需处理的文件,-output部分是输出内容的存放位置,-mapper-reducer是map过程和reduce过程所需命令的所在位置,每个worker节点的相应位置都必须要有相应命令此程序才能正常运行。 若想要设置reduce过程的个数,如将reduce过程设置为1个可使用命令

      hadoop jar $HADOOP_HOME/share/hadoop/tools/lib/hadoop-streaming-2.7.2.jar -input /user/student/example.txt  -output /user/student/output -mapper "/bin/cat" -reducer "/bin/wc" -numReduceTasks 1

程序运行后,可使用-ls命令查看结果文件

      hadoop fs -ls /user/student/output

或使用-cat命令查看结果文件内的具体内容

      hadoop fs -cat /user/student/output/*

4.2.9 Hadoop过时了吗?

不,Hadoop并没有过时, Hadoop生态系统仍然无法替代。 HDFS仍然是世界上最可靠的存储系统,并且全球超过50%的数据已移至Hadoop。 我们要知道的是,尽管有很多其他的工具可以用来解决非常特殊的大数据问题,但是Hadoop已经发展成为一个完整的生态系统,它可以提供相关大数据问题的所有解决方案。因此,虽然现在Hadoop的某些组件已被新组件取代,而且很少有公司再去使用那些旧的组件,但是Hadoop仍然没有过时。例如,Hadoop Mapreduce正逐渐被Apache Spark取代,但Spark仍使用Hadoop HDFS和Yarn进行存储和资源管理,而且许多公司仍在使用MapReduce。 简而言之,无论有什么新技术出现,我们还是应该学习Hadoop,Hadoop将会成为新技术的基础,学习Hadoop对我们没有坏处。