Hadoop源码分析-NameNode 启动流程源码深度剖析

本文尝试讲解 NameNode 启动流程源码剖析,内容包含

  1. Namenode 启动流程跟踪
  2. Namenode Httpserver 启动流程跟踪
  3. Namenode 元数据加载跟踪
    阅读本文,必须了解 HDFS2 的架构以及Hadoop RPC 的使用

开始之前先简单说下阅读源码的技巧

  1. 先掌握其通信架构 - Hadoop RPC
  2. 场景驱动的方式阅读 - 弄懂核心场景
  3. 边看源码,边画图,边写自己的注释
  4. 看类本身的注释
  5. 有些代码实在没有思路,就只能猜了

一、NameNode 启动流程源码深度剖析

1. NameNode.java 类注释

image

以下是 Namenode 类的注释,以及简单的翻译(翻译并不完全是按照原文翻译的)

NameNode serves as both directory namespace manager and
"inode table" for the Hadoop DFS.  There is a single NameNode
running in any DFS deployment.  (Well, except when there
is a second backup/failover NameNode, or when using federated NameNodes.)

NameNode 即是 Hadoop DFS 的目录命名空间管理器,也“inode表”。
在 HDFS 集群中只有一个 Namenode(除了 HA和联邦外);

The NameNode controls two critical tables:
  1)  filename->blocksequence (namespace)
  2)  block->machinelist ("inodes")

Namenode 控制 2 个表:

  1. 文件名-> block 块(命名空间)
  2. blcok -> 机器列表(inodes)
 The first table is stored on disk and is very precious.
 The second table is rebuilt every time the NameNode comes up.

第一个表存储在磁盘上,原因是它很重要(还有就是 文件名与block的关系,基本不会改变)
第二个表每次 Namenode 启动的时候重新构建(block与机器的关系,可能会改变,如果增减机器等)

 NameNode refers to both this class as well as the NameNode server.
 The FSNamesystem class actually performs most of the filesystem
 management.  The majority of the NameNode class itself is concerned
 with exposing the IPC interface and the HTTP server to the outside world,
 plus some configuration management.

NameNode 既指这个类,也指NameNode server。FSNamesystem 类实际上执行了大部分文件系统管理工作。
NameNode 类 对外公开了 IPC 接口(RPC服务) 和 HTTP 服务(50070),以及一些配置管理。

2. NameNode 启动代码猜测

在我们开始 NameNode 启动代码分析之前,我们先对 NameNode 代码进行一个猜测。
我们之前说了Namenode 肯定是个RPC服务,那么它就符合 RPC的规范,那么我们就可以模拟下 NameNode的代码

//协议
public interface A{
    public long versionID=xxxxL;
    public void xxx();
}
public interface B{
    public long versionID=yyyyL;
    public void yyy();
}

//服务端
public class NameNode implements A,B{
    public void xxx(){
      ......
    }
         public void xxx(){
      ......
    }
    public static void main(String args[]){
        RPC.Server server = new RPC.Builder(new Configuration())
        .setBindAddress(xxxx)
        .setPort(xxxx)//9000/8020
        .setProtocol(A.class)
        .setInstance(new NameNode())
        .build();
        server.start();
    }
}

3. NameNode 启动代码分析

  1. 找到 Namenode 启动的入口(也就是main方法),从字面上看, NameNode namenode = createNameNode(argv, null); 应该就是创建一个 Namenode ,既然是创建 Namendoe 应该跟启动有很大的关系了,而其他的代码就看着就关系不大。
image
  1. 进入 createNameNode 的代码后,看到一个 switch,仔细查看各分支后,发现除了 default 外,其他都跟启动没有关系。而default 这里就是 new 了一个 NameNode

    namenode启动入口

  2. 跟进 new NameNode(conf); 代码后,可以看到 try 前面的代码都是给变量赋值,在 try 中 initialize(conf); 比较可疑;

    image

  3. 跟进 initialize(conf);后,发现 rpcServer = createRpcServer(conf); 代码,这个代码非常直观的说明,这里就是 RPC 服务;

    image

  4. 跟进 rpcServer = createRpcServer(conf); 后,发现就只有一行代码new NameNodeRpcServer(conf, this);,这个就是说 new一个 NameNodeRpcServer 对象,直接跟进

    image

  5. 跟进 new NameNodeRpcServer(conf, this); 后,会看到一堆 new,new完也没干什么,那么我们就把代码往下拉,看看有没有其他的不是赋值的。

    image

  6. 终于,我们看到了 RPC.Builder 代码。虽然我们找到了 RPC.Builder 代码,但是这跟我们之前的猜想有些不一样,我们之前猜想 RPC.Builder 代码 应该是在 Namenode 中,而实际上 RPC.Builder 是在 NameNodeRpcServer 中。

    image

  7. 再来看看 Namenode 实现的接口,也不像我们之前说的 RPC 的规范,最起码来 versionID 字段都没有。

    image

  8. 我们再看看 NameNodeRpcServer 实现的接口,发现 NameNodeRpcServer 实现的接口又继承了很多个接口

    image

  9. 我们随便选几个继承的接口看看


    image

    image
  10. 发现这些都有 versionID 字段,那么就可以得出结论,NameNodeRpcServer 是RPC 的服务端,而 Namenode 不是。
    但是呢,我们又在 JPS 的时候明明看到了 Namenode ,这是什么原因呢?
    我们到 Namenode 中搜索一下 NameNodeRpcServer 发现原来,NameNodeRpcServer 是Namenode的一个成员变量。

    image

  11. 并且 NameNodeRpcServer 的赋值和启动都是在 Namenode 中进行的。


    image

4. NameNode 启动代码总结

根据实际的源码分析,我们可以修改下我们之前的代码猜测

//协议
public interface A{
    public long versionID=xxxxL;
    public void xxx();
}
public interface B{
    public long versionID=yyyyL;
    public void yyy();
}

public interface C extends A,B{

}

//服务端
public class NameNodeRpcServer implements C{
    public void xxx(){
      ......
    }
         public void xxx(){
      ......
    }
            RPC.Server server = new RPC.Builder(new Configuration())
            .setBindAddress(xxxx)
            .setPort(xxxx)//9000/8020
            .setProtocol(A.class)
            .setInstance(new NameNode())
            .build();
            server.start();
}
public class NameNode {
    public static void main(String args[]){
             NameNodeRpcServer rpcServer = createRpcServer(conf);// TODO 创建 RPC 服务
             rpcServer.start()
         }
}

5. NameNode Httpserver 启动跟踪

NameNode 服务启动跟踪 的第 4 步,我们还看到 Namenode 启动了一个 HTTP 服务,我们简单来看下这个代码:

image

  1. 我们来跟进下这个HTTP服务代码,可以看到这里 new 了一个 NameNodeHttpServer,然后又调用了一个 start 方法

    image

  2. 我们看看 httpServer = new NameNodeHttpServer(conf, this, getHttpServerBindAddress(conf)); 里面做了什么。看来里面就只是赋值,并没有其他的操作。那么我们在看看 new 之后的 start 方法

    image

  3. 在 start 方法中,我们看到了,构建 HttpServer2 服务的代码,这个 HttpServer2 跟 JDK 的 HttpServer 差不多,他是 Hadoop 自己封装的,具体我们就不看了。 注意 setupServlets(httpServer, conf);,这就是 绑定 servlet

    image

  4. 我们跟进 setupServlets(httpServer, conf);看到这里的确绑定了很多 servlet

    image

6. Namenode 元数据加载源码跟踪(简述)

NameNode 服务启动跟踪 的第 4 步,我们还看到 加载元数据的代码,我们也简单的先看看

image

  1. 跟进去可以看到就一行代码,我们继续跟进


    image
  2. 再跟进去,可以看到下面代码,我们可以看到这里 new 了一个 Fsimage 对象,虽然没有使用,但是发现 namesystem.loadFSImage(startOpt); 代码的名字很像加载 Fsimage。我们继续看看
    image
  3. 跟进去后,第一句就是 获得 getFSImage(),这个返回的就是第2不里 new 的 fsimage 对象。然后就是对 fsimage 进行格式化(如果是第一次启动的话),接着后面的一句代码 fsImage.recoverTransitionRead(startOpt, this, recovery); 这个就是合并 fsimage 和 edit ,再然后就是存储到 新的 fsimage 到磁盘等,具体的我们以后再细讲
    image

7. Namenode 启动源码总结

  1. 先启动 httpserver
  2. 加载元数据
  3. 启动 RPC 服务
    NameNode 启动流程源码深度剖析

    PS:其实在启动 RPC服务之前还有检查资源和判断是否进入安全模式,这块我们以后再讲
    点击这里查看原文地址
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,125评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,293评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,054评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,077评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,096评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,062评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,988评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,817评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,266评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,486评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,646评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,375评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,974评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,621评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,642评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,538评论 2 352

推荐阅读更多精彩内容