接上回
——》NameNode #构造函数()
——1 》NameNode # initialize
▼
rpcServer = createRpcServer(conf); //上节课部分讲完了
1、 NameNode资源检查部分 18:00
--------------- 下来是本节部分-----------------------
//TODO 启动一些公共的服务。NameNode RPC的服务就是在里面启动的
//1)进行资源检查,检查是否有磁盘足够存储元数据
//2)进入安全模式检查,检查是否可以退出安全模式。
startCommonServices(conf);
——1.1 》 NameNode # startCommonServices( )
——1.1.1》FSNamesystem# startCommonServices( )
▼
/** namenode启动的时候,存储资源检查
- namenode: core-site.xml hdfs-site.xml
- 1)fsimage -》目录 磁盘的存储够不够(100M)
- 2)editLog -》目录 磁盘的存储够不够()
默认,这两个文件存储在同一个目录。
*/
//NameNode资源检查 通过core-site.xml hdfs-site.xml两个文件,就知道了元数据存在哪儿?
//需要检查三个目录,因为这三个目录都涉及到了元数据
//(1)NameNode的两个目录:存储fsiamge的目录,存储editlog的目录。但是一般情况下,或者默认情况这两个使用的是同一个目录。
//加载了配置文件,配置文件里面有存储元数据的目录。
nnResourceChecker = new NameNodeResourceChecker(conf);
——1.1.1.1》NameNodeResourceChecker构造函数()
▼
//TODO 阈值
duReserved = conf.getLong(DFSConfigKeys.DFS_NAMENODE_DU_RESERVED_KEY,
▲ 回到——1.1.1》FSNamesystem# startCommonServices
//TODO 检查是否有足够的磁盘存储元数据
checkAvailableResources();
——1.1.1.3》FSNamesystem# checkAvailableResources
hasResourcesAvailable = nnResourceChecker.hasAvailableDiskSpace();
——1.1.1.3》 NameNodeResourceChecker.hasAvailableDiskSpace()
if (! resource.isResourceAvailable())
↓
——1.1.1.3》 NameNodeResourceChecker.isResourceAvailable()
//关键调用的是这儿的代码
return NameNodeResourcePolicy.areResourcesAvailable(volumes.values(),
——1.1.1.3》 NameNodeResourcePolicy#areResourcesAvailable()
//TODO 判断磁盘资源是否充足
if (! resource.isResourceAvailable()) {
↓
NameNodeResourceChecker#CheckedVolume#isResourceAvailable
▲ 回到——1.1.1》FSNamesystem# startCommonServices
2 HDFS 安全模式 0:20
★——1.1.1》FSNamesystem# startCommonServices
▼
//TODO HDFS的安全模式
setBlockTotal();
——1.1.1.4》FSNamesystem#setBlockTotal()
//TODO 设置安全模式
//getCompleteBlocksTotal()获取所有正常的block的个数
safeMode.setBlockTotal((int)getCompleteBlocksTotal());
——1.1.1.4》FSNamesystem#setBlockTotal()
▼
//TODO 设置安全模式
//getCompleteBlocksTotal()获取所有正常的block的个数
safeMode.setBlockTotal((int)getCompleteBlocksTotal());
——1.1.1.4》FSNamesystem#setBlockTotal(int total)
this.blockTotal = total; //total 可用的block总个数
//TODO 计算阈值
//1000 * 0.999 = 999
this.blockThreshold = (int) (blockTotal * threshold);
//TODO 检查安全模式
checkMode();
——1.1.1.4》FSNamesystem#checkMode()
//TODO 判断是否进入安全模式
if (smmthread == null && needEnter()) {
——1.1.1.4 ♠ 》FSNamesystem#needEnter()
▼
/* *TODO 条件一
* threshold != 0 && blockSafe < blockThreshold
* HDFS的元数据那儿程序总计分析出来上一次关闭集群之前
* 假设有1000个complete的block,默认是阈值的计算比例是0.999
* 这样blockThreshold的值是999
* 现在集群起来了以后,发现累计datanode汇报过来的complete的block个数(blockSafe)
* 如果小于999就让集群处于安全模式。
TODO 条件二
* datanodeThreshold != 0 && getNumLiveDataNodes() < datanodeThreshold
* 如果存活的datanode的个数小于一定的数目的时候,也会进去安全模式
* 默认是0,所以相当于没启用,但是我们也可以配置,如果存活的datanode个数
* 少于多少就让HDFS集群出入安全模式。
* TODO 条件三
* !nameNodeHasResourcesAvailable()
* 就是前面 检查NameNode写的元数据的目录空间是否大于100M,
* 如果目录的空间小于100M,nameNodeHasResourcesAvailable 就为false
* hdfs就会进入安全模式。
*/
return (threshold != 0 && blockSafe < blockThreshold) || //条件1
//默认这条件是不生效的
(datanodeThreshold != 0 && getNumLiveDataNodes() < datanodeThreshold) || //条件2
(!nameNodeHasResourcesAvailable()); //条件3
▲ 回到——1.1.1》FSNamesystem# startCommonServices
3 启动重要服务 0:5
——1.1.1》FSNamesystem# startCommonServices
▼
//TODO 启动重要服务
blockManager.activate(conf);
——1.1.1.5》BlockManager#activate()
▼
//启动了等待复制的线程
pendingReplications.start();
//TODO 启动了管理心跳的服务
datanodeManager.activate(conf);
this.replicationThread.start();
——1.1.1.5》DatanodeManager#activate()
▼
//启动了 管理下线datanode的服务
decomManager.activate(conf);
//TODO 管理心跳
heartbeatManager.activate(conf);
▲ 回到——1.1.1》FSNamesystem# startCommonServices
--------------- 本节完成 至此namenode 启动部分 完成-----------------------