网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
Secondary NameNode负责:
- 合并fsimage和edits文件来更新NameNode的metedata
存储模型
以后我们看到块要立即反应到偏移量、位置信息
NameNode(NN)
基于内存存储 :不会和磁盘发生交换
1.简介
- namenode 是整个文件系统的管理节点。他维护着整个文件系统的文件目录树,文件/目录的元信息和每个文件对应的数据块列表。接收用户的操作请求。
文件包括:
- fsimage:元数据镜像文件。存储某一时段NameNode内存元数据信息。
- edits:操作日志文件。
- fstime:保存最近一次checkpoint的时间。
2.NameNode的工作特点
- NameNode始终在内存中保存metedata,用于处理“读请求”,到有“写请求”到来时,NameNode首先会写editlog到磁盘,即向edits文件中写日志,成功返回后,才会修改内存,并且向客户端返回。
- Hadoop会维护一个人fsimage文件,也就是NameNode中metedata的镜像,但是fsimage不会随时与NameNode内存中的metedata保持一致,而是每隔一段时间通过合并edits文件来更新内容。Secondary NameNode就是用来合并fsimage和edits文件来更新NameNode的metedata的。
3.NameNode主要功能
- 接受客户端的读写服务
- 收集DataNode汇报的Block列表信息
4.NameNode保存metadata信息包括
- 文件owership和permissions文件大小
- 时间(Block列表:Block偏移量),位置信息,Block每副本位置(由DataNode上报)
5.NameNode持久化
- NameNode的metadate信息在启动后会加载到内存
- metadata存储到磁盘文件名为” fsimage ”
- Block的位置信息不会保存到fsimage
- edits记录对metadata的操作日志
6.DataNode(DN)
本地磁盘目录存储数据(Block),文件形式 . 同时存储Block的元数据信息文件
启动DN时会向NN汇报block信息, 通过向NN发送心跳保持与其联系(3秒一次),
如果NN 10分钟没有收到DN的心跳,则认为其已经lost,并copy其上的block到其它DN
SecondaryNameNode(SNN)
它不是NN的备份(但可以做备份),它的主要工作是帮助NN合并edits log,减少NN启动时间。
1.SNN执行合并时机
根据配置文件设置的时间间隔fs.checkpoint.period 默认3600秒
根据配置文件设置edits log大小 fs.checkpoint.size 规定edits文件的最大值默认是64MB,一旦超过这个值则强制checkpoint,不管是否到达最大时间间隔。
2.SNN执行流程图
- fsimage文件 : 其实是Hadoop文件系统元数据的一个永久性的检查点,
其中包含Hadoop文件系统中的所有目录和文件idnode的序列化信息; - edits文件 : 存放的是Hadoop文件系统的所有更新操作的路径,
文件系统客户端执行的写操作首先会被记录到edits文件中。
3.过程介绍
- 在 PNN(Primary NameNode) 合并之前,会将 edits 和 fsimage 文件发送给 SNN,然后 PNN 创建一个新的 edits.new 文件继续记录 PNN 的操作。
- PNN 将之前的 edits 和 fsimage 发送给 SNN 后,SNN 会将 fsimage 加载到内存,edits 也加载到内存
根据 edits 中操作记录执行相应的指令,当 edits 的所有操作记录对应的指令执行完毕,会生成一个新的 fsimage.ckpt 快照。 - 将新生成的 fsimage.ckpt 再发送给 PNN ,这时 PNN 就拥有 edits.new 创建之前的快照记录
若 PNN 发生了宕机,可以根据 fsimage 和 edits.new 恢复到宕机前的状态
Block的副本放置策略
Rack :服务器机架
这样选择很好地平衡了可靠性、读写性能
- 可靠性:Block分布在两个机架上
- 写带宽:写入管道的过程只需要跨越一个交换机
- 读带宽:可以从两个机架中任选一个读取
五、HDFS的读写流程(重点)
HDFS写流程
- 客户端通过调用 DistributedFileSystem 的create方法,创建一个新的文件。
- DistributedFileSystem 通过 RPC(远程过程调用)调用 NameNode,去创建一个没有blocks关联的新文件。创建前,NameNode 会做各种校验,比如文件是否存在,客户端有无权限去创建等。如果校验通过,NameNode 就会记录下新文件,否则就会抛出IO异常。
- 前两步结束后会返回 FSDataOutputStream 的对象,和读文件的时候相似,FSDataOutputStream 被封装成 DFSOutputStream,DFSOutputStream 负责处理namenode和datanode之间的通信。客户端开始写数据到DFSOutputStream,DFSOutputStream会把数据切成一个个小packet(64k),然后排成队列 data queue。 使用管道 与 切割成packet的理由:并行存储,增加效率。
- DataStreamer 会去处理接受 data queue,它先问询 NameNode 这个新的 block 最适合存储的在哪几个DataNode里,比如重复数是3,那么就找到3个最适合的 DataNode,把它们排成一个 pipeline。DataStreamer 把 packet 按队列输出到管道的第一个 DataNode 中,第一个 DataNode又把 packet 输出到第二个 DataNode 中,以此类推。
- DFSOutputStream 还有一个队列叫 ack queue,也是由 packet 组成,等待DataNode的收到响应,当pipeline中的所有DataNode都表示已经收到的时候,这时akc queue才会把对应的packet包移除掉。
- 客户端完成写数据后,调用close方法关闭写入流。
- DataStreamer 把剩余的包都刷到 pipeline 里,然后等待 ack 信息,收到最后一个 ack 后,通知 DataNode 把文件标示为已完成。
注意:如果数据节点(datanode)在写入的过程中失败,关闭管线(pipeline),确认队列中的任何包都会被添加回数据队列的前面,当前的数据块在已经写入的数据节点中被元数据节点赋予新的标示,则错误节点重启后能够察觉其数据块是过时的,会被删除。失败的数据节点从管线(pipeline)中移除,另外的数据块则写入pipeline中的另外两个数据节点。元数据节点则被通知此数据块是复制块数不足,将来会再创建第三份备份。
总结:这一方法不仅提供了很好的稳定性(数据块存储在两个机架中)并实现很好的负载均衡,包括写入带宽(写入操作只需要遍历一个交换机)、读取性能(可以从两个机架中选择读取)和集群中块的均匀分布(客户端只在本地机架上写入一个块)。
HDFS读流程
HDFS采用的是“一次写入多次读取”的文件访问模型。一个文件经过创建、写入和关闭之后就不需要改变。这一假设简化了数据一致性问题,并且使高吞吐量的数据访问成为可能。
- 首先客户端调用FileSystem对象的open方法在HDFS中打开要读取的文件,其实获取的是一个DistributedFileSystem的实例。
- DistributedFileSystem通过RPC(远程过程调用)来调用namenode,确定文件起始块的位置,即获得文件的第一批block的locations,同一block按照重复数会返回多个locations,这些locations按照hadoop拓扑结构排序,距离客户端近的排在前面。
- 前两步会返回一个支持文件定位的输入流 FSDataInputStream对象,该对象会被封装成 DFSInputStream对象(存储着文件起始几个块的datanode地址),DFSInputStream可以方便的管理datanode和namenode数据流。客户端调用read方法,DFSInputStream就会找出离客户端最近的datanode并连接datanode。
- 数据从datanode源源不断的流向客户端。
- 如果第一个block块的数据读完了,就会关闭指向第一个block块的datanode连接,接着读取下一个block块。这些操作对客户端来说是透明的,从客户端的角度来看只是读一个持续不断的流。
- 如果第一批block都读完了,DFSInputStream就会去namenode拿下一批blocks的location,然后继续读,如果所有的block块都读完,这时就会关闭掉所有的流。
注意:在读取的时候,如果client与datanode通信时遇到一个错误,那么它就会去尝试对这个块来说下一个最近的块。它也会记住那个故障节点的datanode,以保证不会再对之后的块进行徒劳无益的尝试。client也会确认datanode发来的数据的校验和。如果发现一个损坏的块,它就会在client试图从别的datanode中读取一个块的副本之前报告给namenode。
总结:这个设计的一个重点是,client直接联系datanode去检索数据,并被namenode指引到块中最好的datanode。因为数据流在此集群中是在所有datanode分散进行的。所以这种设计能使HDFS可扩展到最大的并发client数量。同时,namenode只不过提供块的位置请求(存储在内存中,十分高效),不是提供数据。否则如果客户端数量增长,namenode就会快速成为一个“瓶颈”。
六、hadoop2.x新特性
- 引入了NameNode Federation,解决了横向内存扩展
- 引入了Namenode HA,解决了namenode单点故障(SPOF: Single Point Of Failure)
- 引入了YARN,负责资源管理和调度
- 增加了ResourceManager HA解决了ResourceManager单点故障
七、NameNode和SecondaryNameNode(详解)
思考:NameNode中的元数据是存储在哪里的?
首先,我们做个假设,如果存储在NameNode节点的磁盘中,因为经常需要进行随机访问,还有响应客户请求,必然是效率过低。因此,元数据需要存放在内存中。但如果只存在内存中,一旦断电,元数据丢失,整个集群就无法工作了。因此产生在磁盘中备份元数据的FsImage。
这样又会带来新的问题,当在内存中的元数据更新时,如果同时更新FsImage,就会导致效率过低,但如果不更新,就会发生一致性问题,一旦NameNode节点断电,就会产生数据丢失。因此,引入Edits文件(只进行追加操作,效率很高)。每当元数据有更新或者添加元数据时,修改内存中的元数据并追加到Edits中。这样,一旦NameNode节点断电,可以通过FsImage和Edits的合并,合成元数据。
但是,如果长时间添加数据到Edits中,会导致该文件数据过大,效率降低,而且一旦断电,恢复元数据需要的时间过长。因此,需要定期进行FsImage和Edits的合并,如果这个操作由NameNode节点完成,又会效率过低。因此,引入一个新的节点SecondaryNamenode,专门用于FsImage和Edits的合并。
- 第一阶段:NameNode启动
(1)第一次启动NameNode格式化后,创建Fsimage和Edits文件。如果不是第一次启动,直接加载编辑日志和镜像文件到内存。
(2)客户端对元数据进行增删改的请求。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
-19mNL9dE-1715697970680)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新