hdfs的四大机制和两大核心


四大机制:

(1)心跳机制:

  介绍: hdfs是主从架构,所有为了实时的得知dataNode是否存活,必须建立心跳机制,在整个hdfs运行过程中,dataNode会定时的向nameNode发送心跳报告已告知nameNode自己的状态。
   心跳内容
     – 报告自己的存活状态,每次汇报之后都会更新维护的计数信息
     – 向nameNode汇报自己的存储的block列表信息
   心跳报告周期

<property>
              <name>dfs.heartbeat.interval</name>
              <value>3</value> //单位秒
</property>

   nameNode判断一个dataNode宕机的基准:连续10次接收不到dataNode的心跳信息,和2次的检查时间。
  检查时间:表示在nameNode在接收不到dataNode的心跳时,此时会向dataNode主动发送检查

<property>
                  <name>dfs.namenode.heartbeat.recheck-interval</name>
                  <value>300000</value> //单位毫秒
</property>

  计算公式:2dfs.namenode.heartbeat.recheck-interval+10dfs.heartbeat.interval=310+3002=630s=10.5min

(2)安全机制:

   介绍:hdfs在启动的时候,首先会进入的安全模式中,当达到规定的要求时,会退出安全模式。在安全模式中,不能执行任何修改元数据信息的操作。
   hdfs的元数据的介绍(三个部分):
    - 抽象目录树
    - 数据与块的对应关系(文件被切分成多少个块)
    - block块存放的位置信息
   hdfs元数据的存储位置
    - 内存:内存中存储了一份完整的元数据信息(抽象目录树、数据与块的对应关系、block块存放的位置信息)
    - 硬盘:抽象目录树、数据与块的对应关系
    注意:其中内存中的元数据的block块存放的位置信息,是通过dataNode向nameNode汇报心跳时获取的,硬盘中的元数据,是因为内存中的元数据在机器宕机时就自动消失,所以需要将内存中的元数据持久化到硬盘
而硬盘中的元数据只有抽象目录树、数据与块的对应关系,没有block块存放的位置信息
   nameNode在启动的所作的操作
集群的启动顺序:nameNode—》dataNode—》secondaryNameNode
   将硬盘中的元数据信息加载内存,如果是第一次启动集群,此时会在本地生成一个fsimage镜像文件,接收dataNode汇报的心跳,将汇报中的block的位置信息,加载到内存。当然就在此时hdfs会进入安全模式。
  退出安全模式的条件
    – 如果在集群启动时dfs.namenode.safemode.min.datanodes(启动的dataNode个数)为0时,并且,数据块的最小副本数dfs.namenode.replication.min为1时,此时会退出安全模式,也就是说,集群达到了最小副本数,并且能运行的datanode节点也达到了要求,此时退出安全模式
    – 启动的dataNode个数为0时,并且所有的数据块的存货率达到0.999f时,集群退出安全模式(副本数达到要求)

<property>
     <name>dfs.namenode.safemode.threshold-pct</name>
     <value>0.999f</value>
</property>

   手动退出或者进入安全模式

      hdfs dfsadmin -safemode enter 进入
        hdfs dfsadmin -safemode leave 退出
        hdfs dfsadmin -safemode get 查看

(3)机架策略(副本存放策略):

hdfs的四大机制和两大核心
  第一个副本,放置在离客户端最近的那个机架的任意节点,如果客户端是本机,那就存放在本机(保证有一个副本数),第二个副本,放置在跟第一个副本不同机架的任意节点上,第三个副本,放置在跟第二个副本相同机架的不同节点上。
   修改副本的方法
     1. 修改配置文件:

<property>
 <name>dfs.replication</name>
 <value>1</value>
</property>

     2. 命令设置: hadoop fs -setrep 2 -R dir

(4)负载均衡:

  hdfs的负载均衡:表示每一个dataNode存储的数据与其硬件相匹配,即占用率相当
  ,如何手动调整负载均衡:
    – 集群自动调整负载均衡的带宽:(默认为1M)

<property>
        <name>dfs.datanode.balance.bandwidthPerSec</name>
        <value>1048576</value> //1M
</property>

    – 告诉集群进行负载均衡:start-balancer.sh -t 10% 表示节点最大占用率与节点的最小的占用率之间的差值当超过10%时,此时集群不会立刻进行负载均衡,会在集群不忙的时候进行。

两大核心:

(1)文件上传:

hdfs的四大机制和两大核心

  • 使用hdfs提供的客户端client,向远程的namenode发起RPC请求。
  • namenode会检查要创建的文件是否已经存在、创建者是否有权限,成功则会为文件创建一个记录,否则向客户端抛出异常。
  • 当客户端开始写入文件的时候,客户端会将文件切分成多个packets,并在内部以数据队列“data queue(数据队列)”的形式管理这些packet,并向namenode申请blocks,获取用来存储replicas的合适的datanode列表,列表的大小根据namenode中的replication个数来设定。
  • client获取block列表之后,开始以pipeline(管道)的形式,将packet写入所有的replicas中,客户端把packet以流的形式写入到第一个datanode中,该datanode把packet存储之后,在将其传递到此pipeline中的下一个datanode,直到最后一个 datanode。
  • 最后一个 datanode 成功存储之后会返回一个 ack packet(确认队列),在 pipeline 里传递至客户端,在客户端的开发库内部维护着"ack queue",成功收到 datanode 返回的 ackpacket 后会从"data queue"移除相应的 packet。
  • 如果传输过程中,有某个datanode出现了故障,那么当前pipeline会被关闭,出现故障的节点,会被剔除此pipeline,剩余的block会继续剩下的的 datanode 中继续以 pipeline 的形式传输,同时 namenode 会分配一个新的 datanode,保持 replicas 设定的数量。
  • 客户端完成数据的写入后,会对数据流调用close方法,关闭数据流
  • 只要写入了 dfs.replication.min(最小写入成功的副本数)的复本数(默认为 1),写操作就会成功,并且这个块可以在集群中异步复制,直到达到其目标复本数(dfs.replication的默认值为 3),因为namenode已经知道文件由哪些块组成,所以他在返回成功前只需要等待数据块进行最小量的复制。
  • 最后当这个文件上传成功后,此时namenode会将预写如日志的操作,同步到内存中

    (2)文件下载:

    hdfs的四大机制和两大核心

  • 客户端对nameNode发送下载的指令,hadoop fs -get /a.txt
  • nameNode做一系列的校验(是否权限、文件是否存在..)
  • nameNode向client发送block的位置信息,根据情况发送一部分或者全部
  • client计算出最进行DN,然后建立连接,进行文件下载
  • client每下载一个块就会做CRC校验,如果下载失败,client会向nameNode汇报,然后从其他的DD相应的块的副本,此时nameNode会记录这个可能故障的DN,在下次上传或者下载的时候,尽量不使用它。
  • 当所有的块下载成功的时候,client向nameNode汇报成功信息

    补充元数据的合并:

    这是在分布式的基础上,secondaryNamenode对元数据的合并:
    hdfs的四大机制和两大核心
    合并时机:
    A:间隔多长时间合并一次

            <property>
              <name>dfs.namenode.checkpoint.period</name>
              <value>3600</value> //单位秒
            </property>

    B:操作日志记录超过多少条合并一次

    <property>
              <name>dfs.namenode.checkpoint.txns</name>
              <value>1000000</value>
     </property>
  • 集群启动时,加载fsimage镜像文件到内存,如果是第一启动集群或者集群正常关闭之后重启此时nameNode会在硬盘中合并一个fsimage镜像
  • seconddaryNameNode定时(1分钟)发送检验给nameNode,查看是否需要进行合并
  • 得知nameNode需要进行元数据合并
  • seconddaryNameNode向nameNode发送合并请求
  • nameNode将edits_inprogress_000095 根据seen_txid进行回滚,并且生成一个新的空的edits_inprogress_000096,继续记录操作日志
  • secondaryNameNode将回滚的edits和最新的fsiamge进行本地拉去
  • secondaryNameNode将edits和最新的fsiamge进行合并,在内存中根据edits修改fsiamge
  • secondaryNameNode将合并后的fsiamge推送回namenode。并在本地保存一份。