HDFS集群的基础知识总结

简介
HDFS是一个分布式文件系统,通过统一的命名空间——目录树来定位文件,由很多的服务器联合起来实现分布式的功能,主要来解决海量数据的存储问题。在大数据系统结构中就是为分布式运算框架提供数据存储服务的。
主要设计思想:“分而治之,冗余备份”。将大文件被切割成小文件,使用分而治之的思想让很多服务器对同一个文件进行联合管理;再者,将每一个小文件做冗余备份并且分散存储到不同的服务器中,做到高可靠不丢失。这样就可以实现使用很多低廉的服务器来存储海量的数据。

架构和各个节点的职责
主从架构:一主多从
主节点(Namenode):集群的老大,掌管文件系统目录树,处理客户端读写请求。
职责:
1. 负责客户端请求(读写数据请求)的响应;
2. 维护目录树结构(元数据存储和管理:查询和修改),元数据的管理是通过WAL(预写日志系统)将所有的修改在提交之前先写入log文件中。
3. 配置和应用副本存放策略;
4. 管理集群数据块负载均衡的问题。
注意:Namennode对元数据的管理采用了两种存储形式:内存和磁盘。Namenode的内存元数据中,包括文件路径,副本数,blockid,每一个block所在Datanode的信息。但在磁盘中的fsimage(元数据镜像)文件中,并不包含每个block所在Datanode的位置。这也是在冷启动集群的时候,集群会进入安全模式一段时间的原因(详情请见四个核心设计中的安全模式章节)。
从节点(Datanode):存储整个集群所有的数据块,真正地处理数据的读写。
职责:
1. 存储管理用户的文件块数据;
2. 定期向Namenode汇报自身所持有的block信息和状态信息(通过心跳和Namenode通讯)。
SecondaryNamenode:严格说并不是Namenode备份节点,主要是为Namenode分担压力,是Namenode的冷备份,辅助保存HDFS元数据的快照(只有在普通的伪分布式集群和分布式集群中才会有SecondaryNamenode这个角色。在HA或者联邦集群中是没有该角色的,因为在HA和联邦集群中会有Standby Namnode来作为Active Namenode的热备份)。
注释:冷备份就是假设a是b的冷备份,在b挂掉的时候,a并不能代替b的工作。而热备份就是假设a是b的热备份,在b挂掉的时候,a可以马上替代b的工作。
Namenode和Datanode都是HDFS上层抽象的文件系统,实际上存的还是在Linux文件系统之上,只不过由Datande一一对应。

特性
1. HDFS中的文件在物理上是分块存储的,块的大小是通过参数(dfs.blocksize)来规定的,默认大小在Hadoop2.x版本之后是128M,老版本中是64M。
2. HDFS文件系统会给客户端提供一个统一的抽象目录树,客户端通过路径来访问文件,形如:hdfs://namenode:port/dir-a/dir-b/file.data(在这里,默认的端口为9000)。
3. 目录结构及文件分块位置信息(元数据)的管理由Namenode节点承担。文件各个block的存储是由Datanode节点承担,每一个block都可以在多个Datanode上存储多个副本(副本数量是通过参数(dfs.replication)来规定的,默认副本数为3)
4. HDFS是设计成“一次写入,多次读取”的场景,且不支持文件的修改,允许追加。(所以,HDFS适合数据分析,不适合网盘等应用,因为不便修改,延迟大,网络开销大,成本太高)

优缺点
优点:
1. 可构建在廉价的机器上;
2. 高容错性(副本存放策略);
3. 适合批处理(移动计算而非移动数据,数据的位置暴露给计算框架);
4. 适合大数据处理;
5. 流式文件访问(一次写入,多次读取,保证了数据的一致性)。
缺点:
1. 低延迟的数据访问(毫秒级的数据访问不支持)4
2. 小文件的存取(会占Namenode的大量内存,每条元数据的大小约为150b,同时也会导致寻道时间超过读取时间影响文件的读取速度。会给hadoop的扩展性和性能带来严重的问题。)
Hadoop自带的几种解决方案:
- - Hadoop Archive(HAR):是一个高效地将小文件放入HDFS块中的文件存档工具,它能够将多个小文件打包成一个HAR文件,这样在减少Namenode内存的同时,还保证了文件进行透明的访问;
hadoop archive -archiveName 存档名 -p 存放小文件的目录
hadoop dfs -ls har:///hostname:port/archivepath/fileinarchive
- - Sequence File:是由一系列的二进制key/value组成,使key为小文件名,value为文件内容,则可以将大批小文件合并成一个大文件。(在Hadoop-0.21.0之后提供了该功能,需要编写Writer,Reader和SequenceFileSorter类进行写,读和排序操作。)
- - CombineFileInputFormat:是一种新的inputformat,用于将多个文件合并成一个单独的split,另外,它会考虑数据的存储位置。
3. 并发写入,文件随机修改(一个文件只能有一个写入者,仅支持追加。不然会影响带宽)
在这里我们可以做一个测试:就是修改block的数据,会发现在block的数据结尾添加数据,数据块还可以正常读取,但是,如果在其他地方添加数据,读取数据块的时候就会失败。

四个核心设计
HDFS的四个核心设计分别为:心跳机制,安全模式,副本存放策略,负载均衡。
详解请见:HDFS四个核心设计详解

Namenode的工作机制
根据上面的描述,我们知道了Namenode的职责主要是对元数据的管理。
Namenode对元数据的管理采用了两种存储形式:内存和磁盘。
内存中的元数据是一份完整的元数据,包括文件路径,副本数,blockid,每一个block所在Datanode的信息。而内存中的元数据,其实是元数据镜像文件,并不包括每一个block所在的Datanode的信息。
对元数据的管理是通过WAL预写日志系统实现的。
在WAL预写日志文件系统中,所有的修改在提交之前都要先写入log(日志)文件中。
在磁盘中的元数据镜像文件存储的位置为:/hadoopdata/name/current
磁盘中的元数据镜像文件
图中,
fsimage_0000000000000000016:元数据镜像文件(数字越大说明数据越新)
edits_0000000000000000001-0000000000000000016:数据历史操作日志文件
edits_inprogress_0000000000000000017:数据预写操作日志文件
默认情况下,每隔一个小时生成一个数据历史操作文件,在这一个小时中,一直由数据预写操作日志文件更新元数据信息。
在这里有两个计算元数据的公式:
最新的元数据(metadata) = 最新的fsimage + 数据预写操作日志文件;
最新的元数据(metadata) = 所有的数据历史操作日志文件 + 数据预写操作日志文件。
查看fsimage镜像文件和edits文件的方式:
这两个文件不能直接查看,需要先转换一下格式:hdfs oev -i 文件名 -o 转换后的文件名.xml
再查看:cat 转换后的文件名.xml
Namenode元数据的存储机制:在内存中存着一份完整的元数据,在磁盘中有一个“准完整”的元数据镜像文件,该存储机制就是用来衔接内存元数据和磁盘元数据镜像文件之间操作日志文件。当客户端对HDFS中的文件进行新增或者修改操作时,操作记录首先被记入edits日志文件中,当客户端操作成功之后,相应的元数据会更新到内存元数据中。
元数据的存储机制(元数据的checkpoint)详情请看最后的SecondaryNamenode的工作机制。

Datanode的工作机制
通过上述文章的描述,我们知道DataNode的工作职责主要是对用户文件的存储和定期通过心跳机制向Namenode汇报自身所持有的block信息和自身的状态信息。
Datanode和Namenode之间通过心跳机制一直保持着通讯,Namenode也是通过心跳机制向Datanode发送命令的。在默认情况下,在超过10分钟30秒后,Datanode没有通过心跳机制向Namenode进行通讯,则认为该Datanode节点已经挂掉。
详细请看四个核心设计中的心跳机制。

SecondaryNamenode的工作机制
SecondaryNamenode的作用就是分担Namenode的合并元数据的压力。所以再配置SecondaryNamenode节点的时候,一定不要和Namenode在同一个节点。但事实上,只有在普通的伪分布式集群和分布式集群中才会有SecondaryNamenode这个角色。在HA或者联邦集群中是没有该角色的,因为在HA和联邦集群中会有Standby Namnode来作为Active Namenode的热备份。
也可以说SecondaryNamenode的工作机制就是CheckPoint机制。
元数据的CheckPoint机制
在写数据的时候,预写日志到edits progress,写成功之后,将内容加载到内存更新元数据,每隔一段时间,会有SecondaryNamenode将Namenode上所积累的所有edits和一个最新的fsimage下载到本地,并加载到内存进行merge,这个过程技术称之为元数据的CheckPoint。
CheckPoint的过程:
1. Namenode将元数据放在内存中可以让读取速度更快,但是进程一旦被杀掉或者节点宕机就会导致内存中的元数据全部丢失,所以,Namenode同时也会将元数据序列化到磁盘上。但是,如果在Namenode上一直进行序列化操作,就会影响Namenode的性能,所以,Namenode采取了只在启动时序列化一次的机制,之后的操作只存入日志。然后将原镜像文件和日志文件合并的工作交给SecondaryNamenode完成,这样就可减小Namenode的压力;
2. Namenode的内存中存储着的元数据信息由磁盘中的元数据镜像文件和所有的日志文件组成。在SecondaryNamenode需要合并元数据的时候,就向Namenode发送CheckPoint请求。在请求成功后,将Namenode磁盘中的序列化后的元数据镜像文件和所有的日志文件(包括数据历史操作日志文件和数据预写操作日志文件)发送给SecondaryNamenode(该操作只在第一次请求时,在之后的请求中,只需要发送最新的历史日志文件和预写日志文件即可,因为SecondaryNamenode在第一次以合并元数据之后会会在自己保存一份最新的元数据镜像文件);
3. SecondaryNamenode在接收到序列化镜像文件和日志文件之后,对序列化镜像文件进行反序列化后,结合日志文件合并出最新的元数据信息,自己保存一份元数据信息。
4. 将合并出的最新的元数据信息序列化得到新的序列化镜像文件后,发送给Namenode。所以,在Namenode中具有两个镜像和一堆日志文件。
CheckPoint的几个默认配置:
1. 检查触发条件是否满足的频率:60秒
2. 最大的重试次数:3次
3. 两次CheckPoint之间的时间间隔:3600秒
4. 两次CheckPoint之间最大的操作记录:1000000
(3和4条也是1中的两个触发条件)
CheckPoint的一个附带作用:
Namenode和SecondaryNamenode的工作目录存储结构完全相同,所以,当Namenode故障退出需要重新恢复的时候,可以从SecondaryNamenode的工作目录中将fsimage拷贝到Namenode的工作目录,以恢复Namenode的元数据。

猜你喜欢

转载自blog.csdn.net/weixin_44319333/article/details/88979363