一、背景
随着数据量的增大,存储技术出现以下问题,
①硬件问题:复制数据解决(RAID)
②分析需要从不同的硬盘读取数据:MapReduce
而Hadoop提供了以下功能,
①可靠的共享存储(分布式存储)
②抽象的分析接口(分布式分析)
首先简单解释一下大数据的概念,大数据实际上是不能使用一台机器进行处理的数据,大数据的核心是样本=总体。处理大数据所需要的关键技术主要包括以下要求,
①数据分布在多台机器,每个数据块都复制到多个节点,多个节点同时处理数据。
②计算随数据走,网络IO速度 << 本地磁盘IO速度,大数据系统会尽量地将任务分配到离数据最近的机器上运行(程序运行时,将程序及其依赖包都复制到数据所在的机器运行)。代码向数据迁移,避免大规模数据时,造成大量数据迁移的情况,尽量让一段数据的计算发生在同一台机器上。
③串行IO取代随机IO,传输时间 << 寻道时间,一般数据写入后不再修改。
二、Hadoop简介
Hadoop可运行于一般的商用服务器上,具有高容错、高可靠性、高扩展性等特点,特别适合写一次,读多次的场景。
Hadoop的架构如图所示,
其中,HDFS是分布式文件存储,YARN是分布式资源管理,MapReduce是分布式计算,Others是利用YARN的资源管理功能实现其他的数据处理方式。
三、Hadoop各组成部分
1:Hadoop HDFS
Hadoop HDFS的全称为:Hadoop Distributed File System,分布式文件系统。HDFS的架构如图所示,
其中,Block数据块是,
①基本存储单位,一般大小为64M,配置大的块主要是因为:1)减少搜寻时间,一般硬盘传输速率比寻道时间要快,大的块可以减少寻道时间;2)减少管理块的数据开销,每个块都需要在NameNode上有对应的记录;3)对数据块进行读写,减少建立网络的连接成本。
②一个大文件会被拆分成一个个的块,然后存储于不同的机器。如果一个文件少于Block大小,那么实际占用的空间为其文件的大小。
③基本的读写单位,类似于磁盘的页,每次都是读写一个块。
④每个块都会被复制到多台机器,默认复制3份。
NameNode是,
①存储文件的metadata,运行时所有数据都保存到内存,整个HDFS可存储的文件数受限于NameNode的内存大小。
②一个Block在NameNode中对应一条记录(一般一个block占用150字节),如果是大量的小文件,会消耗大量内存。同时map task的数量是由splits来决定的,所以用MapReduce处理大量的小文件时,就会产生过多的map task,线程管理开销将会增加作业时间。处理大量小文件的速度远远小于处理同等大小的大文件的速度。因此Hadoop建议存储大文件。
③数据会定时保存到本地磁盘,但不保存block的位置信息,而是由DataNode注册时上报和运行时维护(NameNode中与DataNode相关的信息并不保存到NameNode的文件系统中,而是NameNode每次重启后,动态重建)。
④NameNode失效则整个HDFS都失效了,所以要保证NameNode的可用性。
Secondary NameNode是,定时与NameNode进行同步(定期合并文件系统镜像和编辑日志,然后把合并后的传给NameNode,替换其镜像,并清空编辑日志,类似于CheckPoint机制),但NameNode失效后仍需要手工将其设置成主机。
DataNode是,
①保存具体的block数据。
②负责数据的读写操作和复制操作。
③DataNode启动时会向NameNode报告当前存储的数据块信息,后续也会定时报告修改信息。
④DataNode之间会进行通信,复制数据块,保证数据的冗余性。
1.1:Hadoop 写文件
HDFS 写文件的方式如图所示:
其中,
①客户端将文件写入本地磁盘的HDFS Client文件中。
②当临时文件大小达到一个block大小时,HDFS client通知NameNode,申请写入文件。
③NameNode在HDFS的文件系统中创建一个文件,并把该block id和要写入的DataNode的列表返回给客户端。
④客户端收到这些信息后,将临时文件写入DataNodes。
·4.1 客户端将文件内容写入第一个DataNode(一般以4kb为单位进行传输)。
·4.2 第一个DataNode接收后,将数据写入本地磁盘,同时也传输给第二个DataNode。
·4.3 依此类推到最后一个DataNode,数据在DataNode之间是通过pipeline的方式进行复制的。
·4.4 后面的DataNode接收完数据后,都会发送一个确认给前一个DataNode,最终第一个DataNode返回确认给客户端。
·4.5 当客户端接收到整个block的确认后,会向NameNode发送一个最终的确认信息。
·4.6 如果写入某个DataNode失败,数据会继续写入其他的DataNode。然后NameNode会找另外一个好的DataNode继续复制,以保证冗余性。
·4.7 每个block都会有一个校验码,并存放到独立的文件中,以便读的时候来验证其完整性。
⑤文件写完后(客户端关闭),NameNode提交文件(这时文件才可见,如果提交前,NameNode垮掉,那文件也就丢失了。fsync:只保证数据的信息写到NameNode上,但并不保证数据已经被写到DataNode中)。
1.2:Hadoop 读文件
HDFS 读文件的方式如图所示:
①客户端向NameNode发送读取请求。
②NameNode返回文件的所有block和这些block所在的DataNodes(包括复制节点)。
③客户端直接从DataNode中读取数据,如果该DataNode读取失败(DataNode失效或校验码不对),则从复制节点中读取(如果读取的数据就在本机,则直接读取,否则通过网络读取)。
1.3:Hadoop 可靠性
HDFS 的可靠性主要有以下几点:
①冗余副本策略,可以在 hdfs-site.xml 中设置复制因子指定副本数量,所有数据块都可副本,DataNode 启动时,遍历本地文件系统,产生一份 HDFS 数据块和本地文件的对应关系列表 (blockreport) 汇报给 Namenode。
②机架策略,HDFS 的“机架感知",通过节点之间发送一个数据包,来感应它们是否在同一个机架,一般在本机架放一个副本,在其他机架再存放一个副本,这样可以防止机架失效时丢失数据,也可以提高带宽利用率。
③心跳机制,NameNode 周期性从 DataNode 接受心跳信息和块报告,NameNode 根据块报告验证元数据,没有按时发送心跳的 DataNode 会被标记为宕机,不会再给他任何 I/O 请求,如果 DataNode 失效造成副本数量下降,并且低于预先设定的值,NameNode 会检测出这些数据库,并在合适的时机重新复制。引发重新复制的原因还包括数据副本本身损坏、磁盘错误、复制因子被增大等。
④安全模式,NameNode 启动时会先经过一个 "安全模式" 阶段,安全模式阶段不会产生数据写,在此阶段 NameNode 收集各个DataNode 的报告,当数据块达到最小副本数以上时,会被认为是"安全"的,在一定比例可设置)的数据块被确定为"安全" 后,再过若干时间,安全模式结束。当检测到副本数不足的数据块是,该块会被复制,直到达到最小副本数。
⑤效验和,在文件创立时,每个数据块都产生效验和,效验和会作为单独一个隐藏文件保存在命名空间下,客户端获取数据时可以检查效验和是否相同,从而发现数据块是否损坏,如果正在读取的数据块损坏,则可以继续读取其他副本。
⑥回收站,删除文件时,其实是放入回收站 /trash,回收站里的文件是可以快速恢复的,可以设置一个时间值,当回收站里文件的存放时间超过了这个值,就被彻底删除,并且释放占用的数据块。
⑦元数据保护,映像文件和事物日志是 NameNode 的核心数据,可以配置为拥有多个副本,副本会降低 NameNode 的处理速度,但增加安全性。NameNode 依然是单点,如果发生故障要手工切换。
1.4:Hadoop 命令工具
常用HDFS命令,
fsck:检查文件的完整性。
start-balancer.sh:重新平衡HDFS。
hdfs dfs -copyFromLocal:从本地磁盘复制文件到HDFS。
2:Hadoop YARN
首先说一下旧的MapReduce架构,如图所示,
其中,JobTracker 负责资源管理,跟踪资源消耗和可用性,作业生命周期管理(调度作业任务,跟踪进度,为任务提供容错)。TaskTracker 加载或关闭任务,定时报告任务状态。
此架构会有以下问题,
①JobTracker 是 MapReduce 的集中处理点,存在单点故障。
②JobTracker 完成了太多的任务,造成了过多的资源消耗,当 MapReduce job 非常多的时候,会造成很大的内存开销。这也是业界普遍总结出老 Hadoop 的 MapReduce 只能支持 4000 节点主机的上限。
③在 TaskTracker 端,以 map/reduce task 的数目作为资源的表示过于简单,没有考虑到 cpu/ 内存的占用情况,如果两个大内存消耗的 task 被调度到了一块,很容易出现 OOM。
④在 TaskTracker 端,把资源强制划分为 map task slot 和 reduce task slot , 如果当系统中只有 map task 或者只有 reduce task 的时候,会造成资源的浪费,也就集群资源利用的问题。
总的来说就是单点问题和资源利用率问题难以满足大数据处理的需求。
YARN的构架如图所示,
YARN就是将 JobTracker 的职责进行拆分,将资源管理和任务调度监控拆分成独立 #x7ACB 的进程,即一个全局的资源管理和一个每个作业的管理(ApplicationMaster) ResourceManager 和 NodeManager 提供了计算资源的分配和管理,而 ApplicationMaster 则完成应用程序的运行。
①ResourceManager:全局资源管理和任务调度
②NodeManager:单个节点的资源管理和监控
③ApplicationMaster:单个作业的资源管理和任务监控
④Container:资源申请的单位和任务运行的容器
YARN的基本流程如图所示,
①Job submission
从ResourceManager 中获取一个Application ID 检查作业输出配置,计算输入分片拷贝作业资源(job jar、配置文件、分片信息)到 HDFS,以便后面任务的执行。
②Job initialization
ResourceManager 将作业递交给 Scheduler(有很多调度算法,一般是根据优先级)Scheduler 为作业分配一个 Container,ResourceManager 就加载一个 application master process 并交给 NodeManager。
管理 ApplicationMaster 主要是创建一系列的监控进程来跟踪作业的进度,同时获取输入分片,为每一个分片创建一个 Map task 和相应的 reduce task Application Master 还决定如何运行作业,如果作业很小(可配置),则直接在同一个JVM 下运行。
③Task assignment
ApplicationMaster 向 Resource Manager 申请资源(一个个的Container,指定任务分配的资源要求)一般是根据data locality来分配资源。
④Task execution
ApplicationMaster 根据 ResourceManager 的分配情况,在对应的 NodeManager 中启动 Container 从HDFSN#x4E2D; 读取任务所需资源(job jar,配置文件等),然后执行该任务。
⑤Progress and status update
定时将任务的进度和状态报告给 ApplicationMaster Client 定时向 ApplicationMaster 获取整个任务的进度和状态。
⑥Job completion
Client定时检查整个作业是否完成作业完成后,会清空临时文件、目录等。
2.1:Hadoop ResourceManager
2.2:Hadoop NodeManager
2.3:Hadoop ApplicationMaster
2.4:Hadoop Container
2.5:Hadoop Failover
3:Hadoop MapReduce