HDFS学习笔记

前言

本文是基于石杉码农公众号关于HDFS的4篇文章作得总结梳理,因为微信公众好跳转连接会过时,就不放上来了,有兴趣的能够直接前往公众号查看《2018年原创汇总》文章查找。微信

HDFS的架构原理

角色

  • NameNode-文件结构树保存节点

Active NameNode-主节点:对外提供服务接收请求。网络

Standby NameNode-备节点:一是接收和同步主节点的edits log以及执行按期checkpoint,二是在Active NameNode的时候进行主备切换。架构

  • JournalNode-日志节点

存放NameNode元数据写入的editLogs,供Standby NameNode拉取,主要意义是保持Active NameNode和Standby NameNode的同步,但必须高可用,因此是集群部署。并发

  • DataNode-数据节点

存放真实数据的节点异步

  • Block

一份数据会分为多个block存放在各个DataNode上,一个block会创建副本,放入其余的DataNode,保证一个block有三个副本在不一样的DataNode上.优化

上传一个文件的流程

  • 客户端上传文件,请求NameNode
  • Active NameNode-主节点在内存中修改文件目录树,同时写入本地的editLog以及向JournalNode集群发送editLog,而后返回给客户端,客户端接收响应后才把文件上传到dataNode集群。
  • Standby NameNode-备节点从JournalNode集群拉取editLog,修改本身的文件目录树
  • Standby NameNode 定时在磁盘生成fsimage镜像文件,并合并本身的editLog文件(这个称为checkpoint检查点操做),而后上传到Active NameNode,Active NameNode收到后清空老的editLog文件以及fsimage文件。
  • 若Active NameNode故障,Standby NameNode将从JournalNode读取所有的editLog,而后切换为Active NameNode(能够保证故障转移时,目录树是彻底和原来的ActiveNode同步的),若原来的Active NameNode重启了,将根据JournalNode同步editLog到最新,恢复时直接根据fsimage文件以及本地editLog文件重放命令,进行数据恢复
  • 为何须要这套机制:为了加快NameNode重启后恢复数据的效率(镜像恢复速度快,不须要重放全部editLog)。

几个重要的优化

获取transactionId以及本地磁盘写+网络磁盘写JournalNode的优化

为何须要引入transactionId

由于在Active NameNode向JournalNode发送editLog的时候,必须保证顺序。因此须要获取transacationId来维护这个顺序,这也意味着transacationId的获取不能并发。线程

原理与流程解析

主要是运用了double-buffer双缓冲机制,什么是双缓冲勒。要发送的editLog数据是先放在缓冲区里面,而后再由某个线程统一发送到JournalNode,提升网络写的效率。但这里有个问题得解决,如何让在网络写的过程当中不影响数据写入缓冲区勒?只能引入双缓冲机制,即将缓冲区域分为两份,一份用于存放即时写入的数据,另外一份用于存放将要被网络写的数据,当须要网络写的时候将两个区域切换,这样两个操做才能互相不影响。日志

上图第一次获取锁是为了生成transacationId,第二次获取锁的操做就是优化网络写,保证每一个请求nameNode的线程不作无效的写入请求。这里保留一个疑问。第二次获取锁应该是非公平锁把,理论上最后一个transacationId的线程获取到锁效率会更高一些,HDFS没有对这里作优化吗?文章里没有提到这里更细的解释,这里暂时存疑。blog

大文件上传优化

HDFS上传文件的流程

  • 好比有人上传一个1TB的大文件到网盘,或者是上传个1TB的大日志文件。
  • HDFS客户端把一个一个的block上传到对应的第一个DataNode
  • 第一个DataNode会把这个block复制一份,作一个副本发送给第二个DataNode。
  • 第二个DataNode发送一个block副本到第三个DataNode。

为何须要优化

若是使用传统的IO传输,将会产生频繁的网络传输,效率很低。队列

优化机制

Chunk缓冲机制

加快磁盘写入内存效率,默认是512Byte。

Packet数据包机制

进一步缓冲要发送网络的数据,默认64M。

内存队列异步发送机制
  • 当一个Packet被塞满了chunk以后,就会将这个Packet放入一个内存队列来进行排队。
  • 而后有一个DataStreamer线程会不断的获取队列中的Packet数据包,经过网络传输直接写一个Packet数据包给DataNode。

注:这里是异步的,意思是往OutPutStream写入数据的同时,也在DataStreamer线程也在发送数据包。

文件契约机制

为何要有文件契约

为了保证同一时间只能有一个客户端获取NameNode上面一个文件的契约,而后才能够写入数据。在写文件的过程期间,客户端须要开启一个线程,不停的发送请求给NameNode进行文件续约。

优化机制

NameNode若是每次都遍历NameNode去淘汰过时的契约,效率是很是低下的,这里的优化就是对每一个契约按最近一次续约时间进行排,序每次都把续约时间最老的契约排在最前头。当每次检查是否过时时,从头开始遍历,只要遍历到没有过时的就不遍历了,由于后面的一定没有过时。相似的,运用这种方式优化的案例还有eureka维护服务实例心跳续约使用的机制。

相关文章
相关标签/搜索