Overview
NameNode 服务器,在启动的之初,必须先初始化自己的文件系统原数据,它是通FSNameSystem来实现这部分工作的,FsNameSystem类似一个容器,它包含以下几个方面的内容:
1: 它是BlockManger, DatanodeManaer, DelegationTokens, LeaseManager 等服务的容器;
2:所有的对Namenode 所属命名空间的修改必须委托由FSNameSystem来实现;
3:所有的对Block的操作,FSNameSystem 将委托由BlockManager来实现;
4:所有的对方件的操作(包含对目录的操作),将委托由FSDirectory来实现;
5:其赛它的复合的操作也将在这儿协调;
6:所有的操作日志,由FSEditlog来实现;
FSNameSystem 会维护以下信息:
- 可用的文件名--> 组成文件的blocks的映射(filename ----> blocklist) 这些信息会保存到存储设备上;
- 可用的block---->block文件的映射(block---->filename);
- bock----> 数据节点有映射;
- 数据节点---->block的映射;
- 最新的到其它节点的心跳LRU缓存信息;
创建FSImage 对像
创建存储设备(NNStorage)对像
NNStrage 简略类图:
NNStorage 类的主要责任是管理存储止录的信息,这些目录是在本地系统存储设备上面,而不是在hdfs文件系统中,所以在实例化的时候,要确定存储目录,这些信息是从配置文件hdfs-site.xml中读取的,参数为:
- dfs.namenode.name.dir, 存放fsimage的目录, 默认为:file://${hadoop.temp.dir}/dfs/name;
- dfs.namenode.edits.dir, 存放操作日志的目录,默认为:file://${hadoop.temp.dir}/dfs/edits;
- dfs.namenode.shared.edits.dir,存放与其它节点共享的日志信息, 用在HA环境中;在这里只是用来判断名字目录或日志目录是否同时为共享目录,NNStorage不维护该目录。
所有的这些配置都可以是一个目录的列表,用逗号分隔。
之后设置NNStorage是否在checkpoint时候偿试恢复之前出错的name目录;
创建 FSEditLog 对像
FSEditLog 的简略类图:
FSEditLog主要负责维护对系统的名称空间的修改记录, 可以用来执行重做,回退等操作;FSEditLog 有几个状态,在不同的状态,可执行的操作名不同:
在Standalone环境下:
- UNINITIALIZED: 实例化后,FEditLog处于该状态,在这个状态的时候,FSDiditLog不能执行任何操作, 只持有log目录,及NNStorage的引用,所有的日志止录,还没有格式化。
- IN_SEGMENT: 初始化完成后,处于该状态,现在可以向FSEditLog中写入数据;
- BETWEEN_LOG_SEGMENTS: 当一个Segment已经写满,要关闭并重新打开一个新的segment,或正在保存当前的名称空间时,处于该状态,表明现在不可以写入数据,
在HA环境下:
- UNINITIALIZED: 实例化后,FEditLog处于该状态,在这个状态的时候,FSDiditLog不能执行任何操作, 只持有log目录,及NNStorage的引用,所有的日志止录,还没有格式化。
- OPEN_FOR_READING: 初始化完成后,处于该状态, 在namenode作为standby的整个生命周期中,一直处于该状态,直到 namenode 转变为Active;
- CLOSED:当namenode从standby转变为Active的过程中,FSEditLog 会先CLOSE然后重新打开;
- BETWEEN_LOG_SEGMENTS: FSEditLog重新打开后,处于状态,之后的操作与Standalone一样;
- IN_SEGMENT: 与Standalone一样。
FSEditLog 状态变化 简图:
创建档案管理器(NNStrorageRetentionManager) 对像
该对像将定期检查NNStorage管理的所有目录是否有付合已定义的策略的文件,并委托NNStoragePurger从本文件系统中删除相关文件;
创建FSNameSystem 对像
FSNamesystem对像主要完成以下信息的初始化:
- fsLock: 这是一个ReentrantReadWriteLock对像,系统可以用键:dfs.namenode.fslock.fair 配置是否启用公平锁机制, 默认启用;
- resourceRecheckInterval:从键dfs.name.resource.check.interval 读取,默认值为:5000ms
- blockManager 对像的创建;
- datanodeStatistics,从blockManager中获取DatanodeStatistics 对像;
- 创建blockIdGenerator对像;
- 获取当前系统用户,作为hdfs文件系统用户;
- 从配置键:dfs.permissions.superusergroup, 默认为:supergroup, 从键:dfs.permissions.enable 获取permission是否启用flag, 默认启用;
- 从键:dfs.persist.blocks读取是否持久化block信息, 对HA环境,譔标志始终为true;
- 根据配置:dfs.checksum.type,创建Checksum对像,默认为CRC32
- 创建FsServerDefaults信息,这些信息收集了所有的与hdfs文件直接相关的信息包括:
- block size:从健:dfs.blocksize读取: 默认为:128M
- CheckSum每次计算的字节数;从键:dfs.bytes-per-checksum读取,黰认为:512B
- 允许客户端一次写入的包的大小从键:dfs.client-write-packet-size:默认为64K
- Replication大小,从键:dfs.replication读取, 默认为:3
- 文件buffer大小,键:io.file.buffer.size,黪认为:4096(4K);
- 设置传输安全标志,从hdfs中读取或写入文件是否要加密, 键:dfs.encrypt.data.transfer, 默认不开启;
- Checkpoint 删除时间,checkpoint 执行之后多 少分钟删除,键:fs.trash.invterval,默认为0 ,功能关闭;
- CheckSum 实例;
- 系统中允许的最大文件数:dfs.namenode.max.objects, 0 表示无上限;
- 文件中最大的block数, dfs.namenode.fs-limit.max-blcoks-per-file,默认为:1M
- 文件访问时间精度:dfs.namenode.accesstime.precision; 默认为1hour, 0 关闭该功能;
- 是否支持向文件尾添加, dfs.support.append,默认支持;
- 创建ReplaceDatanodeOnFailure 对像;
- 标志,当namenode运行为standby时是否要执行checkpoint,dfs.ha.standby.checkpoint,默认为true;
- 创建INodeId对像;
- 创建DelegationTokenSecretManager 对像;
- 创建FSDirectory对像;
- 创建SnapshotManager 对像
- 创建SafeModeInfo 对像;
- 初始化所有的AuditLogger 对像;
- 如果需要初始化retryCache对像;
Load FSImage
FSImage load 是由类FSImage完成的,FSNamesystem类通过调用FSImage的recoverTransitionRead 方法让FSImage去加载自己。FSImage会做加载image前的名种检查包括:
- 所有要加载的目录的状态,如果要加载的目录已经格式化但目录是非正常状态,会先偿试修复该目录;如果某个目录不存在则系统直接退出;
- 如果要所有的目录都没有格式化,则系统退出;
- 如果layout version与当前的version不匹配,则系统退出;
- 如果有目录没有格式化,则格式化它们;
- 最后开始load 这些目录。
FSImage的load主要分两部分内容
- FSImage 文件的load
- FSEditLog的日志文件的load
首先通过NNStorage对像获得FSImageStorageInspector对像,该实例用来获取所有的fsimage 文件列表; 然后初始化FSEditLog对像,用来读取日志文件,然后如果有日志文件打开所有的日志文件输入流,然后按照文件的从旧新到顺序加载image文件,最后如果存在,加载日志文件。
最后返回一个标志给FSNamesystem,是否要保存新的image文件,这会让FSNamesystem 合并所有的FSImage文件及日志文件,便于保存备份,之前的文件会被删除。
至此FSNamesystem初始化完成。下一步是各服务的启动。