zoukankan      html  css  js  c++  java
  • Hadoop源代码点滴-文件系统HDFS

    1. HDFS是Hadoop集群的文件系统,这是一种分布(distributed)、容错(fault tolerant)的文件系统
    2. 所谓分布,是说整个文件系统的内容并非集中存储在一台或几台“文件服务器上”,而是分散在集群的不同节点上
    3. 对于大数据文件系统,文件之所以应该是分布式的,不再仅仅是容量和容错的问题,还有计算的问题。
    4. 大数据处理有个原则,就是数据在哪里,计算就在哪里。
    5. 分布的计算必然要求分布的数据存储,最好就是每个机诶但都存储数据,每个节点也都承担计算。
    6. 按什么方式把整个文件系统的内容分布存储在集群中呢
      1. 远程挂在(mount):这只是目录(文件子系统)层面的分布
      2. 粒度更细化一点,改成文件层面的分布:也就是说不是以目录为单位,而是以文件为单位的分布,并建立重要文件查名服务器
      3. 粒度更细化,改成文件块层面的分布:在存储的时候把文件拆散,HDFS的分布,是“块”这个层次的分布.
    7. HDFS文件块是虚拟的,默认64MB,128MB也是很常用的
    8. 集中的目录和查明服务,则不是告诉你这些文件在哪里,而是告诉你具体的块在哪里,然后你自己去访问
    9. HDFS的查明服务都集中在一个节点上,成为nameNode;担负文件内容存储的节点则成为DataNode。
    10. 在DataNode上,不管是1MB、64MB、一个(HDFS的)块对于宿主主机而言就是一个文件,其块号就编码在文件名中。从一个DataNode中读出一个块,实际上是读出一个文件。而在NameNode中,则存储的是HDFS“文件系统”,实际上存储整个目录树,或称“namespace”的映像。可想而知,这个映像也是作为宿主系统的文件而存储的。
    11. 解决了怎么分布的问题,随之而来的是容错的问题。HDFS采用了“狡兔三窟”的策略,每个块都是一式几份。响应地,查明服务要提供的就不只是一个块在什么地方,而是这个块的几个副本分别在什么地方。这样,你就可以自己决定从哪个节点上读取这个块的副本,万一失败就换一个节点再去读取另一个副本。
    12. 为NameNode提供热备的节点,则称为“Standby NameNode“。ActiveNN和StandbyNN之间的有同步才能保持一致。然而如果每一次有一点改变时就得同步一次,系统的开销太大,所以HDFS采用一个变通的方法。(类似Oracle的archive log、ADG)
    13. 这个EditLog可以(但不是必须)既不是在NameNode节点上,也不是在Secondary NameNode节点上,而是在某个双方都能访问的第三方那里,而且一般要求这第三方具有更高的可靠性。比方说,如果集群中机器是普通的PC机,则EditLog就应该放在具有更可高、质量更好的服务器上。这样如果ActiveNN出了问题,StandbyNN出来接管,这是它手头的文件系统映像很可能是老的,已经远远落后于形势。而手头有着文件系统最新映像的原NameNode,则此时已经访问不到了。这时原StandbyNN就把EditLog中记录逐条”重演“一遍。
    14. 可想而知,这种同步也不一定非要到NameNode出问题时候才做,StandbyNN完全可以没过一段时间就做一下。
    15. EditLog信息的接收者可以不止一家。
    16. 在Hadoop中,NameNode表现为一个独立的JVM进程。同样,SNN、DataNode也是这样的JVM。
    17. NameNode    
      1. JvmPauseMonitor,看起其类名可知是用来监视JVM运行是否停滞。其实原理挺简单,这是一个线程,这个线程基本上老是睡眠,只是周期性的醒来一下,一醒来就从系统获取当时的实际时间,开刚才实际睡眠时间是否比自己指定要睡眠的时间长出很多,如果是,就说明本线程被调度运行的机会大大减少,系统已经太忙,因而就在运行日志中发出一条警告信息。
      2. Format:就只是HDFS文件系统的格式化,实际上就是其目录系统的格式化,那就是在宿主文件系统中创建一套目录,用来存放HDFS的元数据文件。而且,一旦完成格式化,程序就terminate(),这个命令的意图其实并非启动NameNode,而仅仅是格式化。当然在完成格式化之前,NameNode是无法正常运行的。
      3. 为什么格式化要和NameNode放在一起呢,这是因为HDFS的格式化只需在NameNode上进行,也只应在NameNode上进行。
      4. NameNode实际上并不需要知道具体的块在哪个数据节点的什么位置上,而只要知道哪些节点存储着哪些块,以及节点上还有多少容量可供使用。进一步,什么块在什么节点上这个信息其实不必固定记载在NameNode的文件系统映像中,而是可以在运行的时候让数据节点自行报告。在集群环境中,NameNode对于数据节点的控制不想单机对于磁盘那样严密,加之每个块都有多个副本保存在不同节点上,这样比把这些信息固定记载在NameNode上更合适,因为保不住哪个节点突然就离线了,过一会又回来了,甚至保不住哪个节点上的磁盘被拆装到了另一个节点上。
      5. NameNode的作用,简单地说:是给定一个文件路名名,就告诉你这个文件有哪些块,以及每个块都有几个副本、分别存储在什么节点上。
      6. 这里有两个环节。1、从一个文件的路径名到它的块表;2、再从具体块号到其副本所在的数据节点。这两个环节性质是有区别的。
      7. 其中的第一个环节,说明每个具体的文件名包含了哪些块,即从文件名到块表的映射,就是HDFS的目录系统,也跟单机的目录系统相似,是必须持久存储的,要不然断电之后就什么也没有了。集群中只有NameNode才有这方面的信息,DataNode根本就不知道还有HDFS这一层目录和文件。
      8. 但是第二个环节,即从块号到存储地点的映射,就不一定了。当然也可以把这个映射持久存储在NameNode上,但是这样也是有问题的,因为NameNode对于数据节点其实没有很强的控制,比如说,可能NameNode记载表明某个数据节点上有某个块号的一个副本,但是那个副本实际上却因为某种原因而不存在了,例如因本地的某种不当操作被删掉了,于是两边就不一致了。在比方说,NameNode可能记载着某个副本所在节点的节点名和IP地址,但实际使用中个别节点的名称和IP地址却可能变了。所以把第二层映射持久存储下来可能是靠不住的。那么怎么办呢?HDFS采用的办法就是干脆就不持久存储,而让各数据节点定期向NameNode报告:我这里有你的这么一些块,你可以让大家需要的时候上我这来读取;而NameNode则在运行时动态汇集和维持第二层映射所需的信息。集群中数据节点定时向NameNode发送心跳(Heartbeat)报告,上面就打搭载着这样的信息。
      9. 所以,NameNode至少要经历一轮Heartbeat之后才能真正完成其初始化。
  • 相关阅读:
    线段树 BZOJ1858 [Scoi2010]序列操作
    dfs序+线段树 BZOJ3252 攻略
    线段树 BZOJ3888 [Usaco2015 Jan]Stampede
    线段树 BZOJ1798 [Ahoi2009]Seq 维护序列seq
    大坑【持续更新……】
    LCA树剖法模板
    Tarjan-LCA HDU2586 How far away ?
    动态规划 洛谷P2401 不等数列
    搜索 洛谷P2530 [SHOI2001]化工厂装箱员
    动态规划 洛谷P1077 摆花
  • 原文地址:https://www.cnblogs.com/jiangtao1218/p/9129362.html
Copyright © 2011-2022 走看看