写在前面
写个啥呢,算了,不写了。
Hadoop
产生
- 个人数据的快速产生,保存个人成长过程的数据成为主流
- 物联网所产生出的数据
问题
- 磁盘IO
- 硬件故障
- 并行读/写数据
面对此系列问题,Hadoop为我们提供了一个可靠的且可扩展的存储和分析平台,运行于商用硬件且开源。其中,Hadoop默认使用MapReduce编程模型,实现了在合理的时间内处理针对数据集的动态查询。
与传统关系型数据库的比较
- 寻址时间
- 数据的更新
HDFS
作为Hadoop自带的分布式文件系统,也是Hadoop的旗舰级文件系统。它的设计主要:
- 超大文件
- 流式数据访问
- 商用硬件
- 低时延数据访问
- 多用户的写入
其数据块的大小默认128MB 磁盘读写的最小单位,其目的是最小化寻址开销,MR中的Map任务通常每次处理一个块大小的数据,若任务数太小,作业运行速率变慢。
好处
- 一个文件的大小可以大于网络中任意一个磁盘的容量
- 使用抽象块而非整个文件作为存储单元,大大简化了存储系统的设计,简化存储管理。
节点:
HDFS集群有两类节点:namenode和datanode,分别代表着管理节点和工作节点。它们以管理节点-工作节点模式运行,即一个管理节点对应多个工作节点。
-
namenode
- 功能
- 管理文件系统的命名空间
- 维护着文件系统树,以及整棵树的文件和目录
- 处理客户端请求
- 配置副本策略
- 保存本地磁盘上的文件:命名空间、镜像文件、编辑日志
- 容错机制
- 备份组成文件系统的元数据持久化状态的文件
- 运行SNN,帮助NN合并日志文件,避免文件过大
- 功能
-
datanode
- 功能
- 文件系统的工作节点
- 依需检索存储数据块(受客户端或者namenode的调度)
- 定期向namenode发送其所存储的块信息(心跳机制)
- 容错机制
- 副本策略
- 功能
-
secondlyNameNode
- namenode的冷备份
- 保存namenode的部分信息
- 帮助namenode合并镜像文件和编辑日志
冷备份以及热备份的区别?
- 所谓的冷备份在主服务器丢失的情况下才会使用的服务器,其同步了主服务器的数据信息,但并未安装或未配置成与主服务器相同或相似的运行环境
- 热备能在主服务器丢失的第一时间替代主服务器,成为新的主服务器。这就要求热备服务器与主服务器之间不仅得保持数据同步,也得保证其运行环境相同或相似,且时刻与主服务器为联机状态,故此带来的要求更高了。
数据流
读取
流程:
- 客户端打开dfs,获取dfs实例
- dfs远程调用NN,获取相应的块位置信息
- dsf返回一个FSDataInputStream对象给客户端,其中fsdis对象封装了DFSInputStream对象,管理着DN和NN的IO
- client 对fsdis调用read方法。fsdis连接相应的块,反复调用read方法对数据块进行读取。
- 到达块末端的时候便关闭dfsis与当前DN的连接,继续连接下一最佳DN
- 所有数据读取完后,dfsis调用close方法,关闭数据流。读取完成。
客户端读取HDFS数据图示:
当数据读取的时候,dfsis在与DN通信时遇到错误,会尝试连接当前块副本的下一个最邻近的节点,并记住当前节点,保证不会读取该节点后续的块。当然,当dfsis读取块数据后也会通过校验和来确认此块信息是否完整,如果发现由损坏的块,则会去从其他的DN读取该块副本数据,同时也会将损坏的块通知NN。
网络拓扑 与Hadoop
在海量数据的处理中,其主要限制因素是节点之间的数据传输速率——带宽,故此我们根据两个节点间的带宽作为其距离的衡量标准。
Hadoop采用一种简单的方式来衡量两个节点间的带宽:把网络看成一棵树,两个节点间的距离是它们到最近共同祖先的距离总和,该树中的层次没有预先设定,但是对于数据中心、机架和正在运行的节点,通常可以设定等级,其想法为针对以下场景,可用带宽依次递减:
- 同一结点的进程
- 同一机架上的不同节点
- 同一数据中心不同机架上的节点
- 不同数据中心的节点
写入
流程:
- 客户端通过对dfs对象调用create()方法来创建新的文件
- dfs对NN创建一个RPC,在文件系统的命名空间创建一个新的文件。
- NN执行各种检查条件确保该文件不存在此文件系统中且客户端具有相应的权限,通过后,NN会为此纪录创建一条记录。否则抛出异常。
- dfs向客户端返回一个fsdos对象,由此客户端便可以开始写入数据。
- 数据写入。数据写入时,dfsos会将数据分成一个个数据包,并写入内部队列,称为数据队列。DataStreamer处理数据队列,它的责任是挑选出适合存储数据副本的一组DN,并据此要求DN分配新的数据块,这一组DN构成一个管线,其中管线的节点数由副本数决定,DataStreamer将数据包流式传送到管线中的第一个DN,再由它传给管线中下一个DN,以此传送。
- dfsos也维护着一个内部数据包队列来等待DN的收到确认回执,称为确认队列。当收到管道内的所有DN确认信息后,该数据包才会从确认队列中删除。
- 客户端完成所有的数据写入后,对数据流执行close()方法。该操作会将剩余的数据全部写入到DN管线中。
最小副本原则
NN在选择在那个DN上存放数据副本时候,需要对可靠性、写入带宽和读取带宽进行权衡。例如,当NN将所有的副本写入一个节点中,此时写入带宽最小,但是其并不可靠,当该节点宕机后,此块的信息将会完全丢失。同时,同一机架上的服务器的读取带宽是相当高的。对另一极端而言,将副本放在不同数据中心可以最大的保证其可靠性,但是其带宽消耗也是不容小觑的。
Hadoop的默认布局策略是在客户端运行的节点放置第一个副本(如果客户端运行在集群之外,则会随机选择一个节点,不过系统会避免放在存储太满或者太忙的节点),第二个副本放在与第一个不同且随机另外选择的机架中的节点上,第三个副本放在与第二个副本同一机架不同节点上。其他副本放在集群随机节点上,同时系统会避免同一机架上的不同副本的数量过多。
高可用
由于NN是唯一存储元数据与文件到数据块映射信息的地方,当NN失效,Hadoop无法为文件系统提供系统服务,直到有新的NN上线。对于一个大型并拥有大量文件的集群,NN的冷启动时间长达30分钟甚至更久。其高可用性就是为了避免此类的单点故障。
新的NN必须满足以下条件,Hadoop才能正常运行:
- 将命名空间导入镜像文件
- 重演编辑日志
- 获取足够多的来自于DN的块报告信息
- 推出安全模式
Hadoop 2.0 增加了对高可用(HA)的支持,配置一对活动-备用NN,当活动的NN失效后,备用NN能够立即接管它的任务,并服务来自于客户端的请求,且这一状态的转变对于客户端来说是透明的,即客户端不会有任何中断。
修改
-
保证客户端的操作请求能够被两个NN同时接受
通过高可用共享存储实现编辑日志的共享,即对于每次的操作,首先将其写入编辑日志中,再执行操作。当备用NN接管后,其必须通读整个共享编辑日志,实现状态的同步,并继续由活动NN写入新的条目。
-
DN需要同时向两个NN汇报节点块信息
数据块的映射信息保存在内存当中,而非磁盘。
-
SNM角色被备用NN包含。
-
NN的接管过程对客户端时透明的。
实现:NFS过滤器和QJM
- NFS过滤器
- QJM
- 专用的HDFS实现。对提供一个高可用的编辑日志而实现的,被推荐用于大量的HDFS部署中。
- QJM以一组日志节点(journal node)的行式运行,每一次编辑需写入大多数的日志节点中,其安排与zk类似,但其实现并没有使用zookeeper。但是在HA选取活动NN的时候使用了zk。
- 比较
- 当使用NFS过滤器实现共享编辑日志的时候,由于不可能同一时间只允许一个NN写入数据
故障切换与规避
每个NN运行着一个轻量级的故障转移控制器,其工作室通过心跳机制监视宿主NN是否失效,并在失效时进行故障的切换,以保证先前活动的NN不会危害系统,导致系统崩溃的操作。其常用的规避操作:
- 撤销原NN访问问存储目录的权限
- 通过远程命令屏蔽相应的网络端口
检查点的创建:
- SNN请求NN停止正在使用的edits文件,并将新的编辑操作写入新的文件中,主NN还会更新所有存储目录中的seen_txid文件
- SNN从主节点获取最新的fsimage和edits(采用get方式)
- SNN将fsimage载入内存,逐一执行edits文件中的事务,创建新的fsimage文件
- SNN将新的fsimage文件发送到主NN(使用put),主NN将其保存为临时的 .ckpt 文件
- 主NN重命名临时的fsimage文件,便于日后使用。
参数:
dfs.namenode.checkpoint.period 默认一小时,即默认每一小时创建一个检查点
dfs.namenode.checkpoint.txns 默认一百万,即默认每一百万条事务就创建一个检查点(每一分钟检查一次)
流程图
安全模式
NN启动时,首先将镜像文件载入内存之中,并执行编辑日志中的各项编辑操作。一旦在内存中创建文件系统元数据的映像,则会创建一个新的镜像文件和新的编辑日志文件(此操作不借助SNN)。在此过程中,NN运行在安全模式下,意味着NN的文件系统对于客户端来说,是只可读的。
严格来说,在安全模式下,对于文件系统的元数据的访问读取操作是一定能成功的,例如显示文件列表信息等。因为对于读操作来说,只要该文件系统的DN的数据块可用的时候才能正常工作,但写操作一定失败。
在安全模式下,各个DN都会向NN汇报最新的块列表信息,只有当NN收到足够多的块列表信息后,HDFS才可正常运行。
当NN收到的块列表信息过少,此时就会启动块复制进程,将数据块信息复制到新的DN节点,以达到最小副本。而实际上,在安全模式下,NN不会向DN发送任何块复制或者块删除命令。
最小副本条件:整个文件系统中有99.9%的块满足最小副本级别。
MapReduce
MR是Hadoop的最重要的计算引擎,不仅支持交互式应用、基于程序的应用,还是Hive等组件的基础。
MR采用分治法的思想,MR框架负责处理并行编程中的分布式存储、工作调度、负载均衡、容错及网络通信等复杂工作,把处理过程高度抽象为两个函数map和reduce,map负责将作业切分为多个任务,reduce负责将切分后的任务处理结果汇总。
在MR1.x版本,其节点只有JobTracker和TaskTracker
节点
- ResourceManage:拥有为系统中所有应用分配资源的决定权。为节点分配资源
- AppMaster:负责与RM协商资源,并与NM协同工作来执行和监控。
- NodeManage:向RM申请节点运行所需资源
yarn流程
- 在客户端提交作业。
- RM负责协调集群上计算资源的分配。
- NM负责启动和监视集群上的计算容器。
- AM负责协调运行MR作业的任务,它和MR任务在容器内运行,这些容器有RM分配对NM进行管理。
- HDFS用来与其他实体间共享作业文件。
Map和Reduce阶段
- map阶段
- Read。Map Task通过用户编写的RecorderReader,从输入inputsplit中解析出(k/v)。
- Map。将解析出来的k/v交互给用户编写的map函数进行处理,并产生一组新的k/v。
- Collect。在用户编写的map函数中,数据处理完成后,一般会调用OutputCollector.collect()来进行收集结果。在该函数内部,它会生成k/v分片,通过Partitioner并行写入一个圆形缓冲区中。
- Spill。当圆形缓冲区填满后,MR会将数据写入到本地磁盘上,并生成一个临时文件。
- Sort。在写入本地磁盘之前,先要对数据进行一次本地排序,并在需要时进行合并、压缩等操作。
- Combine。当所有的数据处理完后,MapTask会对所有的临时文件进行合并,以确保最终只会生成一个数据文件。
- reduce阶段
- Copy。Reduce Task从各个Map Task上远程复制数据,并针对某一片数据进行判断,如果大小超过阈值,则将其溢写到磁盘上,否则直接放在内存中。
- Merge。在远程复制的同时,Reduce Task启动了两个后台线程,对内存和磁盘上的文件进行合并,以防止内存使用过多或者磁盘上文件过多。
- Sort。Reduce 输入数据是按照key进行聚集的一组数据,为了将key相同的数据聚在一起,Hadoop采用基于排序的策略,由于Map Task已经实现了对自己处理结果的一个基本局部排序,因此 Reduce Task只需对所有的数据进行一次归并排序即可。
- Reduce。ReduceTask将每组数据一次交给用户编写的reduce函数进行处理。
- Write。reduce函数将结果持久化在HDFS上。