一、HDFS架构图和读写流程【十分熟悉】
1.HDFS系统架构
NameNode(nn):Hdfs集群的管理者,Master
- 维护管理Hdfs的名称空间(NameSpace)
- 维护副本策略
- 记录文件块(Block)的映射信息
- 负责处理客户端读写请求
DataNode:NameNode下达命令,DataNode执行实际操作,Slave。
- 保存实际的数据块
- 负责数据块的读写
Client:客户端
- 上传文件到HDFS的时候,Client负责将文件切分成Block,然后进行上传
- 与NameNode交互,获取文件的位置信息
- 与DataNode交互,读取或写入文件
- Client可以使用一些命令来管理HDFS或者访问HDFS
2.HDFS读写数据流程
读数据流程
请求—查询—选择—传输—接收
- 客户端通过Distributed FileSystem向NameNode请求下载文件,NameNode通过查询元数据,找到文件块所在的DataNode地址。
- 挑选一台DataNode(就近原则,然后随机)服务器,请求读取数据
- DataNode开始传输数据给客户端(从磁盘里面读取数据输入流,以Packet为单位来做校验)
- 客户端以Packet为单位接收,先在本地缓存,然后写入目标文件
写数据流程
【客户端—NameNode交互】
- 请求是否可以上传
- 请求datanode信息
- 客户端通过Distributed FileSystem模块向NameNode请求上传文件,NameNode检查目标文件是否已存在,父目录是否存在
- NameNode响应是否可以上传
- 客户端请求上传第一个 Block块,需要得到DataNode信息
- NameNode返回3个DataNode节点信息,分别为dn1、dn2、dn3
【客户端—DateNode交互】
- 客户端通过FSDataOutputStream模块请求dn1上传数据,dn1收到请求会继续调用dn2,然后dn2调用dn3,将这个通信管道建立完成
- dn1、dn2、dn3逐级应答客户端
- 客户端开始往dn1上传第一个Block(先从磁盘读取数据放到一个本地内存缓存),以Packet为单位,dn1收到一个Packet就会传给dn2,dn2传给dn3;dn1每传一个packet会放入一个确认队列等待确认
- 当一个Block传输完成之后,客户端再次请求NameNode上传第二个Block的服务器。(重复执行3-7步)
读写数据流程总结
读数据
- 请求NN,得到数据所在地址
- 就近访问DN,请求读取
-
写数据
请求NN批准,想要上传文件(我可以上传吗?)
- 请求存储位置(我该存哪?),NN返回DN相应信息
- 建立逐级通信管道dn1->dn2->dn3,DN逐级响应
- 逐级在管道内传输数据包
二、NN与2NN
1.元数据管理
流程:
- 第一阶段:NameNode启动
- 第一次启动NameNode格式化后,创建Fsimage和Edits文件。如果不是第一次启动,直接加载编辑日志和镜像文件到内存 。
- 客户端对元数据进行增删改的请求
- NameNode记录操作日志,更新滚动日志 (edits文件?)
- NameNode在内存中对数据进行增删改
- 第二阶段:Secondary NameNode工作
- Secondary NameNode询问NameNode是否需要CheckPoint,直接带回NameNode是否执行检查点操作结果。
- Secondary NameNode请求执行CheckPoint
- NameNode滚动正在写的edits日志
- 将滚动前的编辑日志和镜像文件拷贝到Secondary NameNode
- Secondary NameNode加载编辑日志和镜像文件到内存,并合并
- 生成新的镜像文件fsimage.checkpoint
- 拷贝fsimage.checkpoint 到NameNode
- NameNode将fsimage.chkpoint重新命名成fsimage
- Edits文件 :存储了客户端对HDFS文件系统所有的更新操作记录,Client对HDFS文件系统所有的更新操作都会被记录到Edits文件中(不包括查询操作)
- Fsimage文件:是namenode中关于元数据的镜像,一般称为检查点,这里包含了HDFS文件系统所有目录以及文件相关信息(Block数量,副本数量,权限等信息)
注意:fsimage后面的数组表示当前合并的edits文件的最大下标。
问题:
- NameNode如何管理和存储元数据?
内存+磁盘;NameNode内存+FsImage的文件(磁盘)
- nn启动时需要加载fsimage文件以及那些没有被2nn进行合并的edits文件,nn如何判断哪些edits已经
被合并了呢?
可以通过fsimage文件自身的编号来确定哪些已经被合并。 - checkpoint周期
定时/ edits文件满
2.NN故障处理
如果元数据出现丢失损坏如何恢复呢?
1. 将2NN的元数据拷贝到NN的节点下
此种方式会存在元数据的丢失。
2. 搭建HDFS的HA(高可用)集群,解决NN的单点故障问题!!
借助Zookeeper实现HA,一个Active的NameNode,一个是Standby的NameNode
三、HDFS安全模式
- 安全模式是HDFS所处的一种特殊状态,在这种状态下,文件系统只接受读数据请求,而不接受删除、修改等变更请求。
- 在NameNode主节点启动时,HDFS首先进入安全模式,DataNode在启动的时候会向NameNode汇报可用的block等状态,当整个系统达到安全标准时,HDFS自动离开安全模式。
如果HDFS出于安全模式下,则文件block不能进行任何的副本复制操作,因此达到最小的副本数量要求是基于DataNode启动时的状态来判定的,启动时不会再做任何复制(从而达到最小副本数量要求),HDFS集群刚启动的时候,默认30S钟的时间是出于安全期的,只有过了30S之后,集群脱离了安全期,然后才可以对集群进行操作。
总结
安全模式,只读
- NN启动时,首先进入安全模式
- 30s安全期
四、Hadoop归档技术
主要解决HDFS集群存在大量小文件的问题!!
- Hadoop存档文件HAR文件,是一个更高效的文件存档工具,HAR文件是由一组文件通过archive工具创建而来,在减少了NameNode的内存使用的同时,可以对文件进行透明的访问,通俗来说就是HAR文件对NameNode来说是一个文件减少了内存的浪费,对于实际操作处理文件依然是一个一个独立的文件 。
五、Hadoop优化(高频面试题库)
- 输入小文件过多处理
- 合并小文件:对小文件进行归档(Har)、自定义 Inputformat 将小文件存储成 SequenceFile 文件
- 采用 ConbinFileInputFormat 来作为输入,解决输入端大量小文件场景。
- Map 阶段
- 增大环形缓冲区大小。由 100m 扩大到 200m
- 增大环形缓冲区溢写的比例。由 80%扩大到 90%
- 减少对溢写文件的 merge 次数。(10 个文件,一次 20 个 merge)
- 不影响实际业务的前提下,采用 Combiner 提前合并,减少 I/O。
- Reduce 阶段
- 合理设置 Map 和 Reduce 数量:两个都不能设置太少,也不能设置太多。
- 太少,会导致 Task 等待,延长处理时间;
- 太多,会导致 Map、Reduce 任务间竞争资源,造成处理超时等错误。
- 设置 Map、Reduce 共存
- 调整 slowstart.completedmaps 参数,使 Map 运行到一定 程度后,Reduce 也开始运行,减少 Reduce 的等待时间。
- 规避使用 Reduce,因为 Reduce 在用于连接数据集的时候将会产生大量的网络消 耗。
- 增加每个 Reduce 去 Map 中拿数据的并行数
- 集群性能可以的前提下,增大 Reduce 端存储数据内存的大小。
- 合理设置 Map 和 Reduce 数量:两个都不能设置太少,也不能设置太多。
- IO 传输
- 采用数据压缩的方式,减少网络 IO 的的时间。安装 Snappy 和 LZOP 压缩编码器。
- 使用 SequenceFile 二进制文件
- 切片机制
- 简单地按照文件的内容长度进行切片
- 切片大小,默认等于 Block 大小(128m)
- 切片时不考虑数据集整体,而是逐个针对每一个文件单独切片
- 压缩方式
六、Hadoop 解决数据倾斜方法
- 提前在 map 进行 combine,减少传输的数据量(应对一个mapper的通用处理)
在 Mapper 加上 combiner 相当于提前进行 reduce,即把一个 Mapper 中的相同 key 进行了聚合,减少 shuffle 过程中传输的数据量,以及 Reducer 端的计算量。
- 导致数据倾斜的 key 大量分布在不同的 mapper
- 局部聚合加全局聚合。
- 第一次在 map 阶段对那些导致了数据倾斜的 key 加上 1 到 n 的随机前缀,这样本来相同的 key 也会被分到多个 Reducer 中进行局部聚合,数量就会大大降低。
- 第二次 mapreduce,去掉 key 的随机前缀,进行全局聚合。
- 增加 Reducer,提升并行度
- JobConf.setNumReduceTasks(int)
- 实现自定义分区
- 根据数据分布情况,自定义散列函数(默认是哈希分区),将 key 均匀分配到不同 Reducer
- 局部聚合加全局聚合。
文件操作常用命令
Shell 命令行操作HDFS
/bin目录下,或者直接任意目录下?
hdfs dfs -操作
- 显示目录信息
hdfs dfs -ls /
- 在HDFS上创建目录
hdfs dfs -mkdir -p /lagou/bigdata
- 显示文件内容
hdfs dfs -cat
- 修改用户、用户组以及权限
hdfs dfs -chmod 修改权限
hdfs dfs -chown 修改用户组
- 从HDFS的一个路径拷贝到HDFS的另一个路径
hdfs dfs -cp
- 从HDFS下载文件到本地
-get
- 从本地上传文件到HDFS
-put
- 显示一个文件的末尾
-tail
- 删除文件或文件夹
-rm
- 删除空目录
-rmdir
- 设置HDFS中文件的副本数量
-setrep
JAVA客户端IDEA
- HDFS的API操作
- I/O流操作HDFS