Hadoop
common
- 为Hadoop其他组件提供公共库
HDFS(Hadoop Distributed File System)
Mapreduce
HDFS简介
- hdfs:hadoop分布式文件系统,hadoop的两大核心组件之一,主要解决分布式存储问题。
- 计算机集群基本架构
- 机架:1个机架有30-40台机器,机架与机架之间用带宽更高的几个光纤交换机来完成彼此之间的交互和连接
- 节点:机架上的每个机器称作一个节点,机架内部之间是通过光纤高速交换机进行连接
- 一个作为主节点,其余的作为从节点,主节点承担数据目录(元数据)服务,从节点完成相关的存储任务
- HDFS要实现的目标(优点)
- 兼容廉价的硬件设备。以前需要非常高端的机器,比如小型机,动辄几十万,现在普通的PC机即可构建一个集群
- 实现流数据读写,为了满足大规模数据的批量处理需求而设计的
- 支持大数据集,能以TB为单位存储
- 支持简单的文件模型,只允许追加,不允许修改
- 强大的跨平台兼容性
- HDFS的缺点
- 不适合低延迟的数据访问,实时性不高,(HBase可以满足该需求)
- 无法高效存储大量小文件
- 不支持多用户写入及任意修改文件
HDFS相关概念
-
块:整个HDFS当中的最核心的概念
- 为了分摊磁盘读写开销也就是在大量数据间分摊磁盘寻址开销
- 一个块要比普通的文件系统的块大很多,默认是64MB,可以修改为128MB
- 设计理念
- 支持面向大规模数据存储
- 降低分布式节点的寻址开销(块越大寻址开销越小,但是会影响MapReduce的计算效率)
- 简化系统设计
- 适合数据备份
-
HDFS两大组件
- 名称节点(NameNode)
- 整个HDFS集群的管家(数据目录)
- FsImage:文件系统树(规模很大)
- 文件的复制等级
- 修改和访问时间
- 访问权限
- 块大小以及组成文件的块(注意:块存储在哪个节点的信息不是由FsImage来保存,而是单独在内存一个区域中维护的,通过名称节点和数据节点实实时沟通来维护这些信息)
- EditLog:记录对数据进行的诸如创建、删除、重命名等操作(规模很小,操作速度非常快)
- 系统启动首先从底层把FsInage读出来,再把EditLog读出来,它们在内存中进行合并操作,得到一个新的FsImage,把旧的FsImage删掉,再生成一个新的空EditLog文件,以后每次的操作都保存到EditLog中
- 映射信息(保存到名臣节点内存中)
- 一个大的文件到底包含了哪些块
- 一个块到底放到哪个数据节点
- 第二名称节点(Secondary NameNode,2.0版本已经不存在了)
-
对名称节点的冷备份
- 定期的和名称节点进行通信
- 名称节点停止使用EditLog文件
- NameNode会立即生成一个新的edit.new,把新的操作写到Edit.new里面,同时并把EditLog和FsImage通过Http的get方式下载到第二名称节点,第二名称节点和EditLog做合并操作得到新的FsImage,合并完了以后又发给NameNode,NameNode把Edit.new改成EditLog
-
对EditLog的处理
-
- 数据节点(DataNode)
- 存储实际数据
- 名称节点(NameNode)
-
元数据
- 文件是什么
- 文件被分成多少块
- 每个块和文件是怎么映射的
- 每个块被存储在哪个服务器上面
-
HDFS的局限性
- 命名空间限制:名称节点是保存在内存中的,因此名称节点能够监控的对象的个数会受到空间大小限制
- 性能的瓶颈:整个分布式文件的吞吐量,受限于单个名称节点的吞吐量
- 隔离问题:由于集群中只有一个名称节点,只有一个命名空间,因此无法对不同应用程序进行隔离
- 集群的可用性:一旦这个唯一的名称节点发生故障,会导致整个集群变得不可用。(单点故障)2.0版本中设置两个名称节点进行分区管理,并设置热备
-
写流程
- 客户端向NameNode发出写文件请求。
- 检查是否已存在文件、检查权限。若通过检查,直接先将操作写入EditLog,并返回输出流对象。
(注:WAL,write ahead log,先写Log,再写内存,因为EditLog记录的是最新的HDFS客户端执行所有的写操作。如果后续真实写操作失败了,由于在真实写操作之前,操作就被写入EditLog中了,故EditLog中仍会有记录,我们不用担心后续client读不到相应的数据块,因为在第5步中DataNode收到块后会有一返回确认信息,若没写成功,发送端没收到确认信息,会一直重试,直到成功) - client端按128MB的块切分文件。
- client将NameNode返回的分配的可写的DataNode列表和Data数据一同发送给最近的第一个DataNode节点,此后client端和NameNode分配的多个DataNode构成pipeline管道,client端向输出流对象中写数据。client每向第一个DataNode写入一个packet,这个packet便会直接在pipeline里传给第二个、第三个…DataNode。
(注:并不是写好一个块或一整个文件后才向后分发) - 每个DataNode写完一个块后,会返回确认信息。
(注:并不是每写完一个packet后就返回确认信息,个人觉得因为packet中的每个chunk都携带校验信息,没必要每写一个就汇报一下,这样效率太慢。正确的做法是写完一个block块后,对校验信息进行汇总分析,就能得出是否有块写错的情况发生) - 写完数据,关闭输输出流。
- 发送完成信号给NameNode。
(注:发送完成信号的时机取决于集群是强一致性还是最终一致性,强一致性则需要所有DataNode写完后才向NameNode汇报。最终一致性则其中任意一个DataNode写完后就能单独向NameNode汇报,HDFS一般情况下都是强调强一致性)
-
读流程
- client访问NameNode,查询元数据信息,获得这个文件的数据块位置列表,返回输入流对象。
- 就近挑选一台datanode服务器,请求建立输入流 。
- DataNode向输入流中中写数据,以packet为单位来校验。
- 关闭输入流
-
HDFS的存储原理
-
冗余数据保存的问题
- 默认冗余保存为3,伪分布式必须为1
- 能加快数据的传输速率
- 很容易检查数据错误
- 保证数据的可靠性
-
数据保存的策略问题
- 第一副本的存储策略:对于集群内部数据节点发起的请求,第一副本一般放在发起请求的数据节点上(不用通过网络再次传输,提高存储效率)。对于集群外部发起的请求,它会随机的挑选一台磁盘不太满,CPU又不太忙的节点放第一副本
- 第二副本:放在与第一副本不同机架的节点上
- 第三副本:把它放在第一副本相同机架的其他节点上
- 如果还有其他副本,也放在第一副本相同的机架上
-
数据读取
- 就行读取策略
- HDFS提供了一个API可以确定一个数据节点所属的机架ID,客户端也可以调用API获取自己所属的机架ID
-
数据恢复的问题
- 名称节点出错
- 在1.0版本中,namenode出错先暂停服务一段时间,从第二名称节点上把数据恢复回来,恢复以后再提供对外服务
- 在2.0通过热备即可
- 数据节点出错
- 数据节点在整个运行过程中都会定期的通过远程过程调用向名称节点发送心跳信息,告诉自己还活着,一旦一段时间内名称节点收不到数据节点的心跳信息,名称节点会在它的状态列表里面把它标记为不可用状态,把凡是存储在故障机上的数据重新复制分发到其他正常可用的机器上
- 不仅在出错的情况下会实现迁移备份,当出现负载不均衡的时候,也会把负载较重的机器上的数据块迁移到另外的机器上,达到负载均衡的效果
- 数据出错
- 校验码校验
- 校验码在文件被创建的时候生成,客户端每往里面写一个文件的时候,都会为这个数据块生成一个校验码,把它保存在同一个文件目录下面,下次读的时候把数据块和校验码一起读出来,然后把读出的校验码进行校验码计算,再和上次生成的校验码进行比较,如果校验码不一致,说明在存储过程中发生了错误,此时就会进行冗余备份
- 名称节点出错
MapReduce
Shuffle过程原理
- Map端的Shffle过程
- 输入数据和执行Map任务
- 写入缓存(默认100M,溢写比是0.8)
- 溢写(分区、排序、合并)
- 文件归并
Yarn
- Yarn的基本思想是将JobTracker的两个主要功能(资源管理和作业调度/监控)分离。
四大组件
- ResourceManager(RM) 单独对应一个节点,负责资源管理
- ApplicationsManager 应用程序管理器
- ResourceScheduler 资源调度器
- NodeManager(NM), 负责计算,执行MapReduce程序。
- ApplicationMaster(AM),并不是节点,而是一个单独的进程,可以设在任意节点上,包括RM节点,负责任务调度
- Container
执行流程
- 用户编写客户端应用程序,向Yarn提交应用程序,提交的内容包括ApplicationMaster程序,启动ApplicationMaster的命令、用户程序等。
- Yarn中的ResourceManager负责接收和处理来自客户端的请求,接收到客户端应用程序请求后,ResourceMananger里面的调度器(Scheduler)会为应用程序分配一个容器。同时,ResourceManager的应用程序管理器(Applications Manager)会与该容器所在的NodeManager通信,为该应用程序在该容器中启动一个ApplicationMaster(MR App Mstr).
- ApplicationMaster被创建后会首先向ResourceManager注册,从而使得用户可以通过ResourceManger来直接查看应用程序的运行状态。接下来的步骤4-7是具体的应用程序执行步骤。
- ApplicationMaster采用轮询的方式通过RPC协议想ResourceManager申请资源。
- ResourceManager以容器(Container)的形式向提出申请的ApplicationMaster分配资源,一旦ApplicationMaster申请到资源后,就会与该容器所在的NodeManager进行通信,要求它启动任务。
- 当ApplicationMaster要求容器启动任务时,它会为任务设置好运行环境(包括环境变量、JAR包、二进制程序等),然后将任务启动命令写到一个脚本中,最后通过在容器中运行该脚本来启动任务。
- 各个任务通过某个RPC协议向ApplicationMaster汇报自己的状态和进度,让ApplicationMaster可以随时掌握各个任务的运行状态,从而可以在任务失败时重新启动任务。
- 应用程序运行完成后,ApplicationMaster向ResourceManager的应用程序管理器注销并关闭自己。若ApplicationMaster因故失败,ResourceManger中的应用程序管理器会检测到失败的情形,然后将其重新启动,直到所有的任务执行完毕。