1 NameNode
NameNode 管理文件系统的命名空间
- 文件和目录的元数据:(运行时,元数据放内存)
文件的 block 副本个数
修改和访问的时间
访问权限
block 大小以及组成文件的 block 信息列表 - 以两种方式在 NameNode 本地进行持久化:
命名空间镜像文件(fsimage)和编辑日志(edits log)。 - fsimage 文件不记录每个 block 所在的 DataNode 信息,这些信息在每次系统启动的 时候从 DataNode 重建。之后 DataNode 会周期性地通过心跳包向 NameNode 报告 block 信息。DataNode 向 NameNode 注册的时候 NameNode 请求 DataNode 发送 block 列表信息
1、文件名称和路径
2、文件的大小
3、文件的所属关系
4、文件的 block 块大小 128MB
5、文件的副本个数 3 MR 10 个副本
6、文件的修改时间
7、文件的访问时间
8、文件的权限
9、文件的 block 列表
blk1:0,134217728,node1,node13,node26:blockID blk2:134217728,134217728,node7,node89,node1002 blk2:1342177282,134217728,node7,node89,node1002 blk2:1342177283,134217728,node7,node89,node1002 blk2:1342177284,134217728,node7,node89,node1002 blk2:1342177285,134217728,node7,node89,node1002 blk2:134217728,134217728,node7,node89,node1002 blk2:134217728,134217728,node7,node89,node1002
存储结构:
一个运行的 NameNode 如下的目录结构,该目录结构在第一次格式化的时候创建
如果属性 dfs.namenode.name.dir 指定了多个路径,则每个路径中的内容是一样的, 尤其是当其中一个是挂载的 NFS 的时候,这种机制为管理提供了一些弹性。备份数据 in_use.lock 文件用于 NameNode 锁定存储目录。这样就防止其他同时运行的 NameNode 实例使用相同的存储目录。 edits 表示 edits log 日志文件 fsimage 表示文件系统元数据镜像文件 NameNode 在 checkpoint 之前首先要切换新的 edits log 文件,在切换时更新 seen_txid 的值。上次合并 fsimage 和 editslog 之后的第一个操作编号
VERSION 文件是一个 Java 的属性文件
layoutVersion 是一个负数,定义了 HDFS 持久化数据结构的版本。这个版本数字跟hadoop 发行的版本无关。当 layout 改变的时候,该数字减 1(比如从-57 到-58)。当 对 HDFDS 进行了升级,就会发生 layoutVersion 的改变。
namespaceID 是该文件系统的唯一标志符,当 NameNode 第一次格式化的时候生成。 clusterID 是 HDFS 集群使用的一个唯一标志符,在 HDFS 联邦的情况下,就看出它 的作用了,因为联邦情况下,集群有多个命名空间,不同的命名空间由不同的 NameNode 管理.
blockpoolID 是 block 池的唯一标志符,一个 NameNode 管理一个命名空间,该命 名空间中的所有文件存储的 block 都在 block 池中。
cTime 标记着当前 NameNode 创建的时间。对于刚格式化的存储,该值永远是 0,但 是当文件系统更新的时候,这个值就会更新为一个时间戳。
storageType 表示当前目录存储 NameNode 内容的数据结构。
当文件系统客户端进行了写操作(例如创建或移动了文件),这个事务首先在 edits log 中记录下来。NameNode 在内存中有文件系统的元数据,当 edits log 记录结束后, 就更新内存中的元数据。内存中的元数据用于响应客户端的读请求。
个文件(比如:edits_inprogress_00000000000010),写完后冲刷缓冲区并同 步到磁盘,然后返回客户端 success 状态码。如果 NameNode 的元数据需要写到多个目录 中,则对于每个写事务需要所有的写操作都完成,并冲刷缓冲区同步到磁盘才返回 success 状态码。这样就可以保证在发生宕机的时候没有事务数据丢失.
用户的操作是一个事务,每个操作 NN 都要先将操作记录到 edits log 中,如果给 NN 指定了多个目录,则在多个目录中都存在 edits log 文件,用户的操作要在多个目录中都 写完成,才让 NN 同步数据到内存中。当 NN 在内存中也同步了数据,就返回客户端 success。
每个 fsimage 文件都是系统元数据的一个完整的持久化检查点(checkpoint)(后 缀表示镜像中的最后一个事务)。写操作不更新这个数据,因为镜像文件通常为 GB 数量级, 写到磁盘很慢。如果 NameNode 宕机,可以将最新 fsimage 加载到内存,同时执行 edits log 对应于该 fsimage 之后的操作,就可以重建元数据的状态。而这正是每次启动 NameNode 的时候 NameNode 要做的工作。
2 SecondaryNameNode
edits log 会随着对文件系统的操作而无限制地增长,这对正在运行的 NameNode 而 言没有任何影响,如果 NameNode 重启,则需要很长的时间执行 edits log 的记录以更 新 fsimage(元数据镜像文件)。在此期间,整个系统不可用。
在系统启动期间,NameNode 合并 fsimage+edits log
fsimage=0 edist log=很大
内存fsimage=GB
edits log
内存->执行 edits log 条目
解决方案就是运行 SecondaryNameNode,它的作用就是为 NameNode 内存中的文件 系统元数据生成检查点(checkpoint)。fsimage
工作流程:
edits_inprogress_00000000018_0000000028 seen_txid=29
1、secondarynamenode 请求 namenode 生成新的 edits log 文件并向其中写日志。 NameNode 会在所有的存储目录中更新 seen_txid 文件 2、SecondaryNameNode 通过 HTTP GET 的方式从 NameNode 下载 fsimage 和 edits 文件到本地。 3、SecondaryNameNode 将 fsimage 加载到自己的内存,并根据 edits log 更新内存 中的 fsimage 信息,然后将更新完毕之后的 fsimage 写到磁盘上。
4、SecondaryNameNode 通过 HTTP PUT 将新的 fsimage 文件发送到 NameNode, NameNode 将该文件保存为.ckpt 的临时文件备用。 5、NameNode 重命名该临时文件并准备使用。此时 NameNode 拥有一个新的 fsimage 文 件和一个新的很小的 edits log 文件(可能不是空的,因为在 SecondaryNameNode 合 并期间可能对元数据进行了读写操作)。管理员也可以将 NameNode 置于 safemode,通 过 hdfs dfsadmin -saveNamespace 命令来进行 edits log 和 fsimage 的合并
SecondaryNameNode 要 和 NameNode 拥 有 相 同 的 内 存 。 对 大 的 集 群 , SecondaryNameNode 运行于一台专用的物理主机。
检查点创建时机 对于创建检查点(checkpoint)的过程,有三个参数进行配置:
1、默认情况下,SecondaryNameNode 每个小时进行一次 checkpoint 合并 由 dfs.namenode.checkpoint.period 设置,单位秒
2、在不足一小时的情况下,如果 edits log 存储的事务达到了 1000000 个也进行 一次 checkpoint 合并 由 dfs.namenode.checkpoint.txns 设置事务数量
3、事务数量检查默认每分钟进行一次 由 dfs.namenode.checkpoint.check.period 设置,单位秒。
总结:
namenode 管理文件元数据 文件名称、大小、所属关系、权限、副本大小、副本个数 文件块的列表信息:(块的 ID,偏移量,块的大小,块所在的主机名称列表) 持久化文件 fsimage(内存快照),edits log fsimage 很大,GB 级别;edits log 只追加的文件 用户操作首先记录到 edits log 中,然后更新内存 fsimage 不保存数据块位置信息 在系统启动的时候,datanode 向 namenode 发送文件块列表信息(bid) datanode 通过心跳向 namenode 汇报列表信息。 namenode 元数据正常工作时,元数据放内存,高并发。
secondarynamenode 在系统启动的时候,namenode 首先加载 fsimage,然后逐条执行 edits log 中的日志 操作,如果 edits log 很大,则需要很长时间才能加载完毕,向磁盘写新的 fsimage,之后 才可以对外提供服务。
周期性地从 namenode 拷贝 fsimage+edits log,在 SNN 中合并为新的 fsimage,推 送给 namenode。 条件:1、每小时一次,2、不足一小时,则只要 edits log 中记录的事务数达到了 1000000, 则合并。 datanode
存储结构:
1 、 SecondaryNameNode 中 checkpoint 目 录 布 局 (dfs.namenode.checkpoint.dir)和 NameNode 中的一样。
2 、 如 果 NameNode 完 全 坏 掉 ( 没 有 备 用 机 , 也 没 有 NFS ) , 可 以 快 速 地 从 SecondaryNameNode 恢复。有可能丢数据
3、如果 SecondaryNameNode 直接接手 NameNode 的工作,需要在启动 NameNode 进程 的 时 候 添 加 -importCheckpoint 选 项 。 该 选 项 会 让 NameNode 从 由 dfs.namenode.checkpoint.dir 属性定义的路径中加载最新的 checkpoint 数据,但 是为了防止元数据的覆盖,要求 dfs.namenode.name.dir 定义的目录中没有内容。
3 DataNode
存储结构:
DataNode 不需要显式地格式化;关键文件和目录结构如下:
1、HDFS 块数据存储于 blk_前缀的文件中,包含了被存储文件原始字节数据的一部分。
2、每个 block 文件都有一个.meta 后缀的元数据文件关联。该文件包含了一个版本和类 型信息的头部,后接该 block 中每个部分的校验和。
3、每个 block 属于一个 block 池,每个 block 池有自己的存储目录,该目录名称就是 该池子的 ID(跟 NameNode 的 VERSION 文件中记录的 block 池 ID 一样)。
当一个目录中的 block 达到 64 个(通过 dfs.datanode.numblocks 配置)的时候, DataNode 会创建一个新的子目录来存放新的 block 和它们的元数据。这样即使当系统中 有大量的 block 的时候,目录树也不会太深。同时也保证了在每个目录中文件的数量是可 管理的,避免了多数操作系统都会碰到的单个目录中的文件个数限制(几十几百上千个)。 如果 dfs.datanode.data.dir 指定了位于在不同的硬盘驱动器上的多个不同的目录, 则会通过轮询的方式向目录中写 block 数据。需要注意的是 block 的副本不会在同一个DataNode 上复制,而是在不同的 DataNode 节点之间复制。
存储数据模型(重点)
1、文件线性切割成块(Block)(按字节切割) … Hello world
2、Block 分散存储在集群节点中
3、单一文件 Block 大小一致,文件与文件可以不一致 hdfs dfs -D dfs.blocksize=1048576 -D dfs.replication=2 -put hello.txt /
4、Block 可以设置副本数,副本分散在不同节点中 a) 副本数不要超过节点数量 b) 承担计算 c) 容错
5、文件上传可以设置 Block 大小和副本数
6、已上传的文件 Block 副本数可以调整,大小不变
7、只支持一次写入多次读取,同一时刻只有一个写入者 对同一个文件,一个时刻只有一个写入者
8、可以 append 追加数据
优势:
- 一个文件的大小可以大于网络中任意一个磁盘的容量
- 使用抽象块而非整个文件作为存储单元,大大简化存储子系统的设计
- 块非常适合用于数据备份进而提供数据容错能力和提高可用性