在hadoop 整体分析中,说过nameNode主要是实现一个 blockID 到对应 dataNode的对应关系映射。 现在分析一下腰实现这个映射,nameNode还需要哪些模块。
1 为了方便用户查找,实现一个目录树是必须的 (因为要完成 目录到文件的映射,称之为一级关系)。 在linux中是用C 和汇编语言来实现这个的,想要看懂代码感觉不容易,现在有一个JAVA版本的实现,让人兴奋。
2 核心问题实现 blockID 与dataNode的映射。(称之为二级关系)
3 还有一个重要问题 是 nameNode要实现某个block要放置在哪个dataNode上的算法。这个算法要保证效率,保证集群中节点的负载均 衡。
3 提供IPC服务 等等其他的辅助性工作。
同dataNode的实现分析一样,这里也是采取由上及下,从nameNode的启动开始分析它的各个模块的实现。
启动的时候最重要的是先把前面说的 一二级关系建立起来。
第一级关系的建立。
1). 从fsimage中读取该HDFS中保存的每一个目录和每一个文件
2). 初始化每个目录和文件的元数据信息
3). 根据目录和文件的路径,构造出整个namespace在内存中的镜像
4). 如果是文件,则读取出该文件包含的所有blockid,并插入到BlocksMap中。
整个加载流程如下图所示:
第二级关系的建立
建立第二级关系之前,先看一下 第二级关系在数据结构
这个数据结构的建立过程
如图所示,在naneNode启动的过程中 先是处于安全模式,数据节点向nanode节点主动汇报自己存储的block信息。
对于第三个问题 在hadoop 中节点选择的原则 是这样 如果写入数据源来源于一个数据节点 那么 选择原则如下
在当前数据节点下作为一个副本 然后随机选择一个机架存储其他副本 。
这个算法由于机架式用简单的随机算法选定的,所以会出现负载不均衡问题,hadoop 中为解决这个问题,采取了启动专门的负载均衡线程来完成。 而没有使用分布式hash表。