HDFS
HDFS是一个具有高度容错性的分布式文件系统,适合部署在廉价的机器上,它具有以下几个特点:
1)适合存储非常大的文件
2)适合流式数据读取,即适合“只写一次,读多次”的数据处理模式
3)适合部署在廉价的机器上
但HDFS不适合以下场景(任何东西都要分两面看,只有适合自己业务的技术才是真正的好技术):
1)不适合存储大量的小文件,因为受Namenode内存大小限制
2)不适合实时数据读取,高吞吐量和实时性是相悖的,HDFS选择前者
3)不适合需要经常修改数据的场景
HDFS的架构如上图所示,总体上采用了Master/Slave的架构,主要有以下4个部分组成:
1、Client
2、NameNode
整个HDFS集群只有一个NameNode,它存储整个集群文件分别的元数据信息。这些信息以fsimage和editlog两个文件存储在本地磁盘,Client通过这些元数据信息可以找到相应的文件。此外,NameNode还负责监控DataNode的健康情况,一旦发现DataNode异常,就将其踢出,并拷贝其上数据至其它DataNode。
3、Secondary NameNode
Secondary NameNode负责定期合并NameNode的fsimage和editlog。这里特别注意,它不是NameNode的热备,所以NameNode依然是Single Point of Failure。它存在的主要目的是为了分担一部分NameNode的工作(特别是消耗内存的工作,因为内存资源对NameNode来说非常珍贵)。
4、DataNode
DataNode负责数据的实际存储。当一个文件上传至HDFS集群时,它以Block为基本单位分布在各个DataNode中,同时,为了保证数据的可靠性,每个Block会同时写入多个DataNode中(默认为3)
MapReduce
和HDFS一样,MapReduce也是采用Master/Slave的架构,其架构图如下:
它主要有以下4个部分组成:
1)Client
2)JobTracker
JobTracke负责资源监控和作业调度。JobTracker 监控所有TaskTracker 与job的健康状况,一旦发现失败,就将相应的任务转移到其他节点;同时,JobTracker 会跟踪任务的执行进度、资源使用量等信息,并将这些信息告诉任务调度器,而调度器会在资源出现空闲时,选择合适的任务使用这些资源。在Hadoop 中,任务调度器是一个可插拔的模块,用户可以根据自己的需要设计相应的调度器。
3)TaskTracker
TaskTracker 会周期性地通过Heartbeat 将本节点上资源的使用情况和任务的运行进度汇报给JobTracker,同时接收JobTracker 发送过来的命令并执行相应的操作(如启动新任务、杀死任务等)。TaskTracker 使用“slot”等量划分本节点上的资源量。“slot”代表计算资源(CPU、内存等)。一个Task 获取到一个slot 后才有机会运行,而Hadoop 调度器的作用就是将各个TaskTracker 上的空闲slot 分配给Task 使用。slot 分为Map slot 和Reduce slot 两种,分别供MapTask 和Reduce Task 使用。TaskTracker 通过slot 数目(可配置参数)限定Task 的并发度。
4)Task
Task 分为Map Task 和Reduce Task 两种,均由TaskTracker 启动。HDFS 以固定大小的block 为基本单位存储数据,而对于MapReduce 而言,其处理单位是split。split 是一个逻辑概念,它只包含一些元数据信息,比如数据起始位置、数据长度、数据所在节点等。它的划分方法完全由用户自己决定。但需要注意的是,split 的多少决定了Map Task 的数目,因为每个split 只会交给一个Map Task 处理。Split 和 Block的关系如下图所示:
Map Task 执行过程如下图 所示。由该图可知,Map Task 先将对应的split 迭代解析成一个个key/value 对,依次调用用户自定义的map() 函数进行处理,最终将临时结果存放到本地磁盘上,其中临时数据被分成若干个partition,每个partition 将被一个Reduce Task 处理。
Reduce Task 执行过程下图所示。该过程分为三个阶段:
①从远程节点上读取MapTask 中间结果(称为“Shuffle 阶段”);
②按照key 对key/value 对进行排序(称为“Sort 阶段”);
③依次读取<key, value list>,调用用户自定义的reduce() 函数处理,并将最终结果存到HDFS 上(称为“Reduce 阶段”)。