关于HDFS的一些知识点(建议收藏)
大纲
HDFS 基本概念及特性
NameNode 和 DataNode
数据冗余备份
数据副本存放策略
机架感知
FsImage 和 EditLog
SecondaryNameNode
HDFS 读写步骤
安全模式
几个问答题
什么是 HDFS
The Hadoop Distributed File System (HDFS) is a distributed file system designed to run on commodity hardware.
HDFS 的使命
接受硬件故障
看到流数据访问时,卡了我很久,没明白流式数据、实时数据、流式计算、实时计算有什么区别,经过一番查阅,发现这些概念或许不应该放在一起作比较。 流式数据:理解为不是一次性加载完的数据,比如看电影,数据是一帧一帧过来的,动态的;
实时数据:实时产生的数据,和流式数据区别不大,有时候也会叫做实时流数据;
实时计算:处理实时数据,区别与离线计算(处理历史数据);
流式计算:这与实时计算不应该一起比较,实时计算强调的是数据的实时性,而流式计算强调的是计算方法,理解为 Java8 中的流式数据处理;
NameNode 和 DataNode
-
接受用户请求; -
维护文件系统的目录结构; -
管理文件与 block 之间的关系以及 block 与 DataNode 之间的关系;
-
存储文件; -
文件被分成 block 存储在磁盘上; -
为保证数据安全,文件会有多个副本,默认是 3 份;
-
目录仅仅是元信息,没有冗余备份,文件才有备份; -
一个物理节点可以作为一个 DataNode,也可以在一个节点上启动两个 DataNode,只是通常不会这么做; -
HDFS 不支持硬链接或软连接; -
HDFS 中的 block 大小以及备份的数量都是可配置的;
数据冗余备份
数据副本存放策略
-
在机架 1 上放置第一个副本; -
在另一个机架 2 上放置第二副本; -
副本三与副本二放置在同一个机架上; -
如果有更多的副本,则随机选择机架,每个机架的副本数量有个上限值,计算方式通常是:(replicas - 1) / racks + 2
-
避免一个机架出故障,导致所有数据丢失; -
同一个机架上的节点通信网络会比不同机架节点通信更好,副本二与副本三放置在同一个机架能够节省带宽;
机架感知
core-site.xml
文件中有此配置项:net.topology.script.file.name
,以下是官方文档对该配置项的描述。
net.topology.script.file.name The default implementation of the DNSToSwitchMapping. It invokes a script specified in net.topology.script.file.name to resolve node names. If the value for net.topology.script.file.name is not set, the default value of DEFAULT_RACK is returned for all node names.
/myrack/myhost
eg: /192.168.100.0/192.168.100.5
读取时如何选择副本
FsImage 和 EditLog
-
EditLog:保存元数据更改记录,一个文件只记录一段时间的信息,该文件会在某些时刻合并到 FsImage,FsImage 中的信息要比 EditLog 记录的信息慢一步。 -
FsImage:保存文件系统目录树以及文件和 block 的对应关系,理解为元数据镜像文件,某个时刻整个 HDFS 系统文件信息的快照;
SecondaryNameNode
指定时间间隔,通过 dfs.namenode.checkpoint.period 进行配置,默认是一小时;
指定 EditLog 文件大小,通过 dfs.namenode.checkpoint.txns 进行配置,默认是 1 百万条事务记录;
FsImage 和 EditLog 合并过程
-
检查是否触发 checkpoint 条件; -
触发 checkpoint,NameNode 停止向 edits 中写新的记录,另外生成一个 edits.new 文件,将新的事务记录在此文件中; -
SecondaryNameNode 通过 HTTP 请求,从 NameNode 下载 fsimage 和 edits 文件,合并生成 fsimage.chkpoint 文件; -
SecondaryNameNode 再将新生成的 fsimage.chkpoint 上传到 NameNode 并重命名为 fsimage,直接覆盖旧的 fsimage,实际上中间的过程还有一些 MD5 完整性校验,检查文件上传下载后是否完整; -
将 edits.new 文件重命名为 edits 文件,旧的 edits 文件已经合并到 fsimage;
读写详细步骤
-
Client 向 NameNode 发起读请求; -
NameNode 将请求文件的元信息返回给 Client; -
Client 根据元信息去对应的 datanode 上取 block,并以追加的方式写文件,完成 block 的拼接工作; -
最后组成完整的文件;
客户端发起写文件请求,会带上元数据信息;
NameNode 接受到请求后,会做一些校验工作,如文件是否存在、客户端是否有写权限等,并将写操作记录到 edits 文件中,如果写失败,比如断电了,edits 文件中还记录了上一次操作的信息,能够复原上一次操作;
NameNode 将返回每个 block 存放的 DataNode 列表;
客户端从 block 所属的 DataNode 列表中,假设备份 3 份,根据就近原则开始写操作,比如选择 DataNode1,在写的同时,DataNode1 会将文件信息传递给 DataNode2,DataNode2 接收到后再传递给 DataNode3,DataNode 接收到信息后,再依次返回确认信息,就像流水线一样,1 -> 2 -> 3,这个过程叫 Replication Pipelining。
DataNode 写完之后,会将结果返回给客户端,收到一个成功的结果,客户端就认为写操作已经完成了,剩余两个备份会异步进行。假设 2 -> 3 的过程中写失败了, 3 号机器宕机,2 号收不到成功确认 ack,则会告知 NameNode,NameNode 再重新指定一个 DataNode 进行写操作,1、2 随机选择一个作为写操作的发起端,保证最后是 3 份备份。
安全模式
问答形式
-
HDFS 的目标应用场景就是一次写入,多次读取 ; -
如果要支持随机写,分布式数据的一致性就会受到挑战;随机写文件会破坏原文件元数据,元数据的改动会导致校验和的改动,而 hadoop 会依赖校验和等信息进行文件拆分,以及校验文件合法性,随机写会造成效率很低。 -
如果一定要保证实时的数据一致性,性能牺牲会很大,不适合大数据量少写多读的场景。
从磁盘传输的时间明显大于寻址时间,导致程序在处理这块数据时,变得非常慢;
MapReduce 中的 map 任务通常一次只处理一个 block 的数据,如果块过大,运行速度会变慢;
存放大量小文件会占用 NameNode 中大量内存来存储元数据,而 NameNode 的内存是有限的,这样不合理;
文件块过小,大量小文件导致寻址时间增长,程序花很多时间找 block 位置;
-END-