Hadoop学习日记(四)HDFS的基本命令及Hadoop分布式计算框架MapReduce原理

133 阅读5分钟
  • HDFS基本命令
  1. 创建目录

hadoop fs -mkdir /filepath
hadoop fs -p -mkdir  /rootpath/filepath/..

2.查看文件列表

hadoop fs -ls /filepath

3.上传文件到HDFS

hadoop fs -put   /sourcepath  /targetpath

4.下载文件到本地

hadoop fs -get  /sourcepath  /targetpath

5.查看HDFS文件内容

hadoop fs -cat  /filepath

6.删除HDFS文件

hadoop fs -rm /filepath

低版本中有hadoop fs和hadoop dfs两种形式的hadoop命令行,但新版本建议只使用前者。

  • HDFS基本架构

HDFS主要由3个组件构成,分别是NameNode,SecondaryNameNode和DataNode。HDFS是以主从模式运行的。NameNode,SecondaryNameNode运行在master上,DataNode运行在slave上。

NameNode维护系统的命名空间,包括文件到块的映射关系,文件名目录以及它们的层级关系,文件目录的所有者及权限访问日志的等属性的存储,操作功能等所有的元数据。HDFS集群上只能有一个NameNode,它会定期通过心跳消息与DataNode进行通信,给DataNode传递消息并且收集其状态。PS:需要注意的是,NameNode并不保存块的位置信息,这些信息在集群启动的时候由DataNode重建,把块的位置信息放在内存中。

DataNode是HDFS中的woker节点,它负责存储数据块,为Client提供数据的读写,同时根据NameNode的命令来创建,删除,复制等操作。同时,DataNode之间还会相互通信,复制数据,以达到冗余。

前面我们提到,HDFS只有一个NameNode节点,这样就存在单点故障的问题。SecondaryNameNode就是为了解决此问题而设置,但SecondaryNameNode保存的信息总是滞后的,出现故障时还是会丢失一部分数据。NameNode的元信息存放在fsimage文件中,对元信息的所有操作持久化在本地的edits文件中,如果不设置SecondaryNameNode,那么集群在重启时,会消耗大量的时间更新元信息。所以SeconaryNameNode的作用就是定期合并fsimage和edits文件。具体过程如下:

  1. 通知NameNode把当前所有对元信息的操作写到新的edits文件中并将其命名为,edits.new。
  2. 从NameNode请求获得当前的fsimage和edits文件。
  3. 将fsimage和edits合并为新的fsimage文件。
  4. 同时把旧的edits文件用新的edits.new文件替换。
  5. 更新fstime文件中的检查点。
  • HDFS的容错机制

HDFS通过创建副本的方式来实现容错,数据块的大小和备份因子都是可以配置的,为了增加容错率,副本的存储最好是跨机架的,避免由于单个机架故障导致数据丢失。

同时,HDFS还设有安全模式,在NameNode启动时,会进入安全模式,DataNode上传数据块列表,让NameNode得到快的位置并且统计副本数量,当不满足最小副本个数时,安排DataNode进行复制,满足时退出安全模式(安全模式是只读模式)。可以手动退出安全模式

hadoop dfsasmin -safemode leave

  • MapReduce

MapReduce的思想就是把大任务分而治之,提高了任务处理的效率。在Hadoop平台上,MapReduce框架负责处理并行编程中的分布式存储,工作调度,负载均衡,容错,以及网络通信等复杂的任务。但我们要进行Mapreduce任务的编程只需考虑把整个处理过程高度抽象出来的两个函数map和reduce,map即是分割,把分割后的任务以map的形式建立key-value映射关系,reduce即是组合,我们把分割的小任务的处理结果合并得到最终的结果。

我们通过经典的例子WordCount来理解MapReduce任务。

Map过程可以分为下面5个步骤

  1. Map:Read  通过用户编写的RecordReader,从输入流中解析出一个个的key-value

    假设这里key是value的HashCode。

  2. Map: Map 用户编写的处理逻辑阶段,把key-value处理成新的key-value。

    3. Map: Collect 一般会调用OutputCollector.collect()收集结果,它将生成分片(通过partitioner),分区的总数和reduce任务数相同(最优reduce任务数取决于reduce任务槽slot,通常小于slot数,这样可以预留一些系统资源来处理异常,两者相同的原因是控制被分成m个区,也就是m个组的数据,能够还原到m个任务里),上一步map好的结果在分区的位置由hashcode(key)%分区总数。这里我们假设以字符串的长度来作为Hash值

    这里Hash(hello)=5,分区数量为10,Hash(hello)%10=5,分区后写入一个环形内存缓存区。

      4. Map: Spill  就是溢写,在环形缓存区存满后,会在磁盘上生成一个临时文件存储,在写入磁盘之前,会根据Hash(key)进行排序。

    5.Map:  Combine 当所有数据处理完后,会对所有临时文件进行合并。



这里World可能是(World,2)也可能是两个(World,1),如果环形缓存区没满,没有生成临时文件,那就不存在合并临时文件。

Reduce阶段分解为5个步骤

  1. Shuffle  也叫做copy阶段,就是Reduce Task从各个Map Task上远程复制一片数据,并针对某一片数据判断,如果大小超过阈值,就写入磁盘,否则放进内存。
  2. Merge  在复制的同时进行Merge,注意merge是不同于Combine的,Combine的结果把<A,1>,<A,1>处理为<A,2>,而merge是<A,list<1,1>>。每个ReduceTask里的数据个数和每个分区里面数据个数一致。

3.Sort  由于MapTask之前已经进行过局部排序了,所以只用再归并排序一遍即可。

4.Reduce   按照编写的Reduce进行合并。

5.Write   将计算结果写入HDFS。

  • 在虚拟机上安装自己习惯的IDE,就可以进行MapReduce任务编写啦!在Hadoop安装目录下的hadoop-MapReduce-examples-你的hadoop版本号-sources.jar里有WordCount.java这个文件,可以当做一个样板来学习。