美文网首页大数据我爱编程
Hadoop源码学习笔记(2)--Hdfs的启动流程分析

Hadoop源码学习笔记(2)--Hdfs的启动流程分析

作者: kifile | 来源:发表于2017-03-11 23:02 被阅读1151次

    Hdfs 的基础架构

    Hdfs基础架构

    如上图所示。 默认情况下,Hdfs 由一个 Namenode 和多个 DataNode 组成。

    hdfs作为一个分布式文件存储系统,他的文件路径和文件内容是相互隔离的。 文件路径信息保存在 NameNode 中,文件内容则分布式的保存在 DataNode中。

    也就是说对于一个大文件,它可能被根据其文件大小切割成多个小文件进行存储,同时这些小文件可能被分布式的存储在不同的DataNode中。

    当Client希望获取这个文件时,则需要先根据文件路径从 NameNode 中获取他对应的区块在不同的 DataNode 中的信息,然后才能够从 DataNode 中取出数据,还原成一个大文件。

    具体的代码逻辑会在之后的读写操作中介绍,这里我们先看看 hdfs 集群的启动流程。

    Hdfs 集群启动流程

    默认情况下,我们通过 ${HADOOP_HOME}/sbin/start-dfs.sh 启动整个 Hdfs 集群。

    hdfs namenode "${HADOOP_HDFS_HOME}/bin/hdfs" --workers --config "${HADOOP_CONF_DIR}" --hostnames "${NAMENODES}" --daemon start namenode ${nameStartOpt}
    
    hdfs datanode "${HADOOP_HDFS_HOME}/bin/hdfs" --workers --config "${HADOOP_CONF_DIR}" --daemon start datanode ${dataStartOpt}
    
    hdfs secondarynamenode "${HADOOP_HDFS_HOME}/bin/hdfs" --workers --config "${HADOOP_CONF_DIR}" --hostnames "${SECONDARY_NAMENODES}" --daemon start secondarynamenode
    
    hdfs journalnode "${HADOOP_HDFS_HOME}/bin/hdfs" --workers --config "${HADOOP_CONF_DIR}" --hostnames "${JOURNAL_NODES}" --daemon start journalnode
    
    hdfs zkfc "${HADOOP_HDFS_HOME}/bin/hdfs" --workers --config "${HADOOP_CONF_DIR}" --hostnames "${NAMENODES}" --daemon start zkfc
    

    start-dfs.sh 文件中,我们看到shell文件通过执行hdfs命令先后启动 NameNodeDataNodeSecondaryNameNodeJournalNode

    hdfs也是一个shell文件,通过文本应用打开后,我们看到在该文件的执行逻辑如下:

    hdfs执行逻辑

    节点类型和Java类的一一对应

    hdfs文件中可以看到,传入的第一个参数对应着需要启动节点的类型,使用 hdfscmd_case 根据节点类型可以找到对应需要执行的Java类,节点对应表如下。

    节点类型 Java类
    namenode org.apache.hadoop.hdfs.server.namenode.NameNode
    datanode org.apache.hadoop.hdfs.server.datanode.DataNode
    secondarynamenode org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode
    journalnode org.apache.hadoop.hdfs.qjournal.server.JournalNode

    Tips:类似datanode根据是否是secure mode会有多个Java类对应,但这里只列出最常用的类

    为远程机器启动hdfs

    通过解析节点类型,hdfs找到了对应的Java类。接下来就应该是启动并执行这个Java类。

    但是如果在启动命令中包含了 --worker 参数,就代表着需要链接到其他节点机器上执行命令。在处理传参的时候,发现--worker后,会将 ${HADOOP_WORKER_MODE} 设置为 true, 从而执行 hadoop_common_worker_mode_execute(对应的方法逻辑在 hadoop-functions.sh 文件中)。在 hadoop_common_worker_mode_execute 中,通过读取配置文件信息,获取到真实运行设备的hostname,通过ssh执行一个不带--worker选项的hdfs命令,使得hostname对应的节点机器能够启动hdfs节点。

    注意:如果需要通过这种方法启动远程机器,需要将启动机器的.ssh公钥加入被启动机器的信任列表中: cat target/id_rsa.pub >> ~/.ssh/authorized_keys,否则无法直接链接上对应设备

    本地启动hdfs

    我们通过ssh让远程设备启动hdfs节点时,会传递过去一个不带--worker的可执行命令。

    因此通过hdfs启动节点时,运行逻辑和之前保持一致,只是${HADOOP_WORKER_MODE}不为true。此时通过判断是否需要在后台执行命令,我们分别通过 hadoop_daemon_handler 或者 hadoop_java_exec 在前台或后台启动对应的Java任务。

    这里需要留意的是,在通过 hdfscmd_case 解析节点指令时,或默认将 ${HADOOP_DAEMON_MODE} 设置为 true,使得各个节点默认在后台运行。

    NameNode 启动逻辑

    NameNode在整个hdfs中扮演着一个很重要的角色,他负责整个文件系统的路径和数据的管理工作,比较类似 Unix 系统中的 inode table。

    Client 通过 NameNode 获取到指定路径的分布式文件的 metadata,找到存放在 DataNode 的数据位置,就像从 inode talbe中获取 inode 编号,然后才能去访问具体的分布式文件。

    从上一小节的表格中,我们看到 NameNode 对应的启动类是 org.apache.hadoop.hdfs.server.namenode.NameNode,接下来我们通过走读NameNode::main 具体查看节点的启动流程。

    由于 NameNode 的启动参数很多,类似 FORMAT,CLUSTERID,IMPORT等等启动参数并不会被用来启动 NameNode。为了简单起见,这里只针对默认启动逻辑 REGULAR进行分析,启动流程如下:

    NameNode

    如图所示,对于REGULAR模式而言,NameNode节点主要启动了下面三个组件:

    NameNode

    NameNodeHttpServer

    startHttpServer 会启动一个 NameNodeHttpServer

    NameNodeHttpServer 是一个基于 jetty 服务器的简单封装,提供给使用人员一个简单的节点状态查询页面,默认的绑定端口是 :9870,静态页面代码路径是 webapps/namenode,这一部分由于不涉及到核心逻辑,不做介绍。

    FSNamesystem

    loadNamesystem 会构建一个 FSNamesystem 对象,FSNamesystemNameNode 中最核心的一个模块,负责处理维护整个分布式文件系统。详细的处理逻辑会在后续的章节做仔细介绍。

    RPC.Server

    createRPCServer 会启动一个 RPC.Server 线程。

    RPC.Server 负责处理 hdfs 集群中的内部通信,在 RPC.Server 中绑定了一个 socket 端口,利用protobuf的序列化框架进行数据传输,关于 RPC.Server 的交互逻辑会在下一章中做详细介绍,这里可以简单理解为一个使用socket通信的rpc访问框架。

    if (serviceRpcAddr != null) {
        serviceRpcServer = new RPC.Builder(conf).build();
    }
    
    if (lifelineRpcAddr != null) {
        lifelineRpcServer = new RPC.Builder(conf).build();
    }
    
    clientRpcServer = new RPC.Builder(conf).build()
    

    NameNodeRpcServer的构造方法中可能会构造 serviceRpcServer , lifelineRpcServerclientRpcServer 三种 RPC.Server

    DataNode 启动逻辑

    DataNode 在整个hdfs框架中负责具体的文件存储。

    我们知道DataNode的启动类是org.apache.hadoop.hdfs.server.datanode.DataNode

    DataNode启动逻辑

    他的启动逻辑如上图所示。和NameNode类似,在DataNode中同样启动了一个基于 jetty Server的 HTTP 服务器,负责向使用人员展示节点状态;同样还有一个基于 RPC.Server 的 socket 链接负责 hdfs集群 的内部通信。

    DataNode

    DataXceiverServer

    initDataXceiver 会启动一个 DataXceiverServer 类。

    DataXceiverServer 负责接收通过TCP协议传输过来的文件数据,会在下一章介绍 hdfs 的文件传输的时候做介绍,这里先略过

    DatanodeHttpServer

    DatanodeHttpServerNameNodeHttpServer 一样,也是一个基于 jetty 服务器的封装,负责向使用人员提供当前Datanode的节点状态信息,默认的启动端口是 :9864,静态页面代码路径 webapps/datanode,同样这一部分不设计核心逻辑,不做介绍

    RPC.Server

    DataNode中也存在一个RPC.Server对象,负责维持节点间通信,在下一篇文章中会做详细介绍。

    BlockPoolManager

    由于在hdfs中文件路径和文件内容是相互隔离的,在DataNode负责存放分布式的文件内容,但是对于DataNode自身并不知道自己的文件名,只有一个唯一的 blockId 用以定位文件信息。

    BlockPoolManager 中,DataNode会定期上报当前节点的 blockId 列表,以便告知NameNode节点中拥有的文件内容。具体的逻辑会在 hdfs的文件传输的时候做介绍。

    总结

    在本文中,没有过多的对源码进行分析,只简单的介绍了 NameNodeDataNode 两个节点的启动逻辑。

    原因很简单,每个子组件的内容都需要结合 NameNodeDataNode 甚至还需要 Client 三者结合来讲解。而且每个子组件的逻辑也会比较复杂,已经无法放在一个小节里进行讲述。

    所以,本文中只有 start-dfs.sh 的启动逻辑和 NameNodeDataNode 的关键组件构成。

    相关文章

      网友评论

        本文标题:Hadoop源码学习笔记(2)--Hdfs的启动流程分析

        本文链接:https://www.haomeiwen.com/subject/ufjygttx.html