HDFS基础扫盲(一)
发布时间:2025-06-24 17:05:51 作者:北方职教升学中心 阅读量:568
前言
NameNode 的元数据是保存在内存还是磁盘,如果是内存那满了后怎么办,自己会进行溢写嘛?带着这个问题,我们一起来复习下NN,2NN,DN 的工作机制和原理
NN 的元数据是存储在内存还是磁盘
NameNode(NN)的元数据是 同时保留在内存和磁盘上的,但它的主要存储位置是在 内存中:
1. 内存中的元数据
内存存储:NameNode 将文件系统的所有元数据(如文件名、块位置、目录结构等)加载到内存中,这样可以 快速响应客户端请求。这种方式可以确保对文件系统操作的低延迟响应。
内存大小:由于所有元数据都驻留在内存中,内存的大小直接决定了 NameNode 能够处理的文件数量和元数据的规模。如果内存不够大,NameNode 就无法容纳所有的元数据,导致性能下降或者 OutOfMemoryError(内存溢出)。
内存中的元数据包括:
- 文件和目录结构
- 每个文件的块信息(在哪些 DataNode 上)
- 文件的权限信息、所有者信息等
2. 磁盘上的元数据
磁盘存储:为了保证 数据的持久性和 容错性,NN 会将元数据定期持久化到磁盘上。磁盘上的存储包括:
- FsImage:包含了整个 HDFS 文件系统的快照信息,存储了文件系统的结构及其所有文件的元数据。FsImage 是一个持久化的文件,当 NameNode 重启时,可以从 FsImage 中恢复整个文件系统的状态。
- EditLog:记录了所有对 HDFS 元数据的增量修改操作。每当客户端对 HDFS 执行写操作时,NN 会将这些更改追加到 EditLog 中。EditLog 是增量日志,记录了文件系统的所有变化。
磁盘上的存储配置:
dfs.namenode.name.dir
配置项指定了 FsImage 和 EditLog 文件存储的目录路径。这些文件会持久化在磁盘上,用来恢复 NN 重启后的元数据。
3. 内存与磁盘的关系
- 内存中的元数据:提供了快速查询和高效的文件操作支持。NN 在内存中持有元数据的一个实时快照。
- 磁盘上的元数据:确保了持久性和可靠性。即使 NN 宕机或重启,磁盘上的 FsImage 和 EditLog 文件可以帮助恢复内存中的元数据状态。
4. 如何保持数据一致性
- FsImage 和 EditLog 的作用:
- FsImage是 HDFS 文件系统的完整快照,包含所有的元数据。它定期从内存中保存到磁盘。
- EditLog记录了所有对文件系统所做的修改。它是一个增量日志,在 NN 重启时,通过加载 EditLog 文件,可以将内存中的 FsImage 变为最新状态。
5. 数据恢复和持久化
- 当 NameNode 重启时,它会首先从磁盘加载 FsImage 和 EditLog 文件,并通过 合并这两个文件来恢复元数据。
- 这种方式确保了 持久化的同时,允许 NameNode 在内存中操作更高效的文件系统元数据。
6. 总结
- 内存中的元数据:存储在内存中,确保 NameNode 快速响应客户端请求。
- 磁盘上的元数据:存储在磁盘上(FsImage 和 EditLog),确保数据的持久性和 NameNode 重启后的恢复能力。
关键点:尽管元数据主要存储在内存中,但为了持久性和恢复能力,它会定期持久化到磁盘(FsImage 和 EditLog)。
NN 的元数据在内存中可能遇到的问题
NameNode(NN)的元数据保留在内存中的,并且是 有限的。当 NameNode 内存消耗过高时,可能会遇到 内存满的问题,从而影响系统的稳定性和性能。:
1. NameNode 元数据存储在内存中
- 元数据内容:NameNode 负责管理 HDFS 中所有文件和目录的元数据。这些元数据包括文件名、文件的块信息、每个块存储在哪个 DataNode 上等。NameNode 将这些信息加载到内存中,以便能够快速响应客户端的查询请求。
- 内存占用:随着 HDFS 中文件数量的增加,元数据的数量也会增大,因此 NameNode 需要越来越多的内存来存储这些信息。
2. 内存会满吗?
会,内存可能会满。当元数据量变得非常庞大时,NameNode 可能会耗尽内存,导致以下几种问题:
- 性能下降:内存过满可能导致 垃圾回收(GC)频繁发生,从而降低 NameNode 的响应时间。
- OutOfMemoryError:如果内存耗尽,NameNode 会抛出 OutOfMemoryError错误,导致 NameNode 无法继续正常工作,整个 HDFS 集群可能会不可用。
3. 如何防止内存满?
为了避免内存满,您可以采取以下几种措施:
增加 NameNode 内存:根据 HDFS 集群中文件的数量和大小,适当增加 NameNode 的内存。可以通过修改 JVM 启动参数来设置最大内存,例如:
exportHADOOP_NAMENODE_OPTS="-Xmx16g"# 设置 NameNode 最大内存为 16GB
这个设置可以在 NameNode 启动脚本或 Hadoop 配置文件中进行配置。
合理配置
dfs.namenode.handler.count
:该参数用于设置 NameNode 可以同时处理的请求数量。如果并发请求过多,可能会加剧内存的消耗。合理的设置可以避免过载。定期存储和清理 FsImage 和 EditLog:
- FsImage:定期创建新的 FsImage,并将其存储到磁盘,以减少内存中的数据量。
- EditLog:保持 EditLog 的适当大小,定期进行日志合并(例如,通过
hdfs namenode -finalizeUpgrade
命令)。过大的 EditLog 文件可能导致内存使用过高。
使用 NameNode HA(高可用性)配置:对于非常大的 HDFS 集群,考虑部署 NameNode HA集群,将元数据分摊到多个 NameNode 上。通过这种方式,可以避免单个 NameNode 的内存压力过大。
4. 监控和管理 NameNode 内存
监控内存使用情况:使用工具如 JVM Monitoring、JConsole或 Prometheus等来监控 NameNode 的内存使用情况。一旦接近阈值,您可以及时采取行动。
dfs.namenode.memory-manager
:一些 Hadoop 配置提供了对内存使用的管理功能,可以优化内存的使用和回收。
5. 元数据存储的位置
虽然 NameNode 的元数据被保存在内存中,但它也会定期持久化到 磁盘,以确保数据的持久性:
- FsImage和 EditLog文件存储在磁盘上(通常是
dfs.namenode.name.dir
配置的目录中),它们保存了文件系统的元数据。这样,即使 NameNode 重启,也能从磁盘恢复这些元数据。
6. 如何避免元数据过多导致内存压力?
- 文件管理:避免过多的小文件,尽量减少文件的数量,因为每个文件都会占用一定的元数据内存。
- 集群规模规划:对于非常大的 HDFS 集群,考虑使用 HDFS Federation(多个 NameNode)来分摊元数据的存储压力。
- 定期重启或升级 NameNode:确保 NameNode 不会因长时间运行而积累过多的内存使用负担。
总结
- NameNode将元数据存储在内存中,因此会存在内存满的风险,尤其在 HDFS 中文件数量非常多的情况下。
- 可以通过增加内存、定期清理 FsImage 和 EditLog、合理配置 NameNode 参数来预防内存满的情况。
- 元数据在内存中,但会定期持久化到磁盘上,确保数据不会丢失。
NN、2NN 机制介绍(面试八股)
SecondaryNamenode 作用
为了防止Edits 文件过大,需要定期的合并FsImage和Edits。如果这个操作由NameNode节点完成,又会效率过低。因此,引入一个新的节点SecondaryNamenode,专门用于FsImage和Edits的合并。
NameNode 工作机制
第一阶段:NameNode启动
(1)第一次启动NameNode格式化后,创建Fsimage和Edits文件。如果不是第一次启动,直接加载编辑日志和镜像文件到内存。
(2)客户端对元数据进行增删改的请求。
(3)NameNode记录操作日志,更新滚动日志。
(4)NameNode在内存中对元数据进行增删改。
第二阶段:Secondary NameNode工作
(1)Secondary NameNode询问NameNode是否需要CheckPoint。直接带回NameNode是否检查结果。
(2)Secondary NameNode请求执行CheckPoint。
(3)NameNode滚动正在写的Edits日志。
(4)将滚动前的编辑日志和镜像文件拷贝到Secondary NameNode。
(5)Secondary NameNode加载编辑日志和镜像文件到内存,并合并。
(6)生成新的镜像文件fsimage.chkpoint。
(7)拷贝fsimage.chkpoint到NameNode。
(8)NameNode将fsimage.chkpoint重新命名成fsimage。
Checkpoint 机制
Checkpoint 机制是 HDFS 中为了保证 NameNode 元数据的持久性和 系统一致性而引入的一种机制。Checkpoint 的作用是通过定期合并 FsImage和 EditLog文件,创建一个新的 FsImage 文件,从而防止 EditLog 文件过大,保证系统的可恢复性和性能。
具体而言,Checkpoint 机制在以下几个方面发挥作用:
1. Checkpoint 机制的作用
- 合并 FsImage 和 EditLog:每次生成新的 checkpoint 时,NameNode 会合并当前的 FsImage和 EditLog,生成一个新的 FsImage 文件。这样,系统的元数据就会处于一个一致的状态,并且 EditLog 文件被清空。之后,所有新的修改都会追加到新的 EditLog 文件中。
- 减少 EditLog 大小:随着 HDFS 系统的运行,EditLog 文件会不断增长。通过定期生成 checkpoint,EditLog 文件不会变得过大,从而避免影响性能和恢复时间。
- 提高恢复效率:如果 NameNode 重启,它需要从磁盘加载 FsImage 文件并重新应用 EditLog 中的所有增量修改。定期生成 checkpoint 可以减小恢复时需要应用的 EditLog 日志的数量,加快恢复速度。
2. 配置解释
<property><name>dfs.namenode.checkpoint.txns</name><value>1000000</value><description>操作动作次数</description></property><property><name>dfs.namenode.checkpoint.check.period</name><value>60s</value><description>1分钟检查一次操作次数</description></property>
是关于 Checkpoint 机制的配置,下面逐项说明这些配置的含义。
dfs.namenode.checkpoint.txns
:该配置项表示在创建一个新的 checkpoint 之前,允许 NameNode 执行的最大事务数(即元数据修改操作次数)。一旦执行的操作次数达到这个阈值,NameNode 会生成一个新的 checkpoint。- 示例配置:
1000000
- 解释:当 EditLog 中的操作次数达到 1,000,000 次时,NameNode 会触发 checkpoint 过程。
- 示例配置:
dfs.namenode.checkpoint.check.period
:该配置项表示生成 checkpoint 的检查周期,决定了 NameNode 每隔多长时间检查是否需要生成一个新的 checkpoint。即使操作次数没有达到dfs.namenode.checkpoint.txns
中设置的阈值,NameNode 也会在该时间间隔内检查并生成 checkpoint。- 示例配置:
60s
- 解释:NameNode 每 60 秒检查一次操作次数,如果在该时间内操作次数已经超过阈值,它就会生成一个新的 checkpoint。
- 示例配置:
3. 如何运作?
Checkpoint 过程的运作方式是:
- 操作次数达到阈值:当
EditLog
中的事务次数达到dfs.namenode.checkpoint.txns
设置的值时,NameNode 会进行 checkpoint。 - 定时检查:即使操作次数没有达到
dfs.namenode.checkpoint.txns
的阈值,NameNode 也会在dfs.namenode.checkpoint.check.period
设置的周期内检查是否需要创建新的 checkpoint。例如,每 60 秒进行一次检查。 - Checkpoint 过程:一旦条件满足,NameNode 会通过将 EditLog中的操作合并到 FsImage中,生成一个新的 FsImage 文件,并清空 EditLog。这个新生成的 FsImage 文件包含了所有从上一个 checkpoint 后的修改。
4. Checkpoint 机制的优点
- 减少 EditLog 文件大小:如果不进行 checkpoint,EditLog 会随着时间的推移不断变大,导致磁盘空间消耗过多,影响性能,甚至可能导致 NameNode 重启时无法承受过大的日志文件。
- 提高恢复速度:定期进行 checkpoint 可以减少恢复时需要应用的 EditLog 数量。恢复时,NameNode 只需要从最新的 FsImage 文件开始,并且将 EditLog 中的增量操作应用到 FsImage 上,恢复速度因此会更快。
- 避免 NameNode 宕机导致的丢失数据:Checkpoint 机制确保了 NameNode 即使在发生故障或重启时,也能快速恢复最新的元数据状态,防止数据丢失。
5. 注意事项
- 配置的权衡:
dfs.namenode.checkpoint.txns
设置的值和dfs.namenode.checkpoint.check.period
的设置会影响 checkpoint 的频率。如果设置的值过小,checkpoint 可能会过于频繁,从而增加磁盘 I/O 和 CPU 开销;如果设置的值过大,可能导致 EditLog 文件过大,增加恢复时间。因此,需要根据实际情况合理配置。 - Checkpoint 过程的性能:生成 checkpoint 的过程可能会对 NameNode 的性能产生影响,特别是在大规模集群中,频繁生成 checkpoint 会增加 NameNode 的负担。合理的配置可以平衡性能和数据恢复的速度。
6. 总结
- Checkpoint 机制是 HDFS 中用于减少 EditLog 文件大小和提高恢复效率的机制。
dfs.namenode.checkpoint.txns
设置触发 checkpoint 之前允许的最大事务数。dfs.namenode.checkpoint.check.period
设置检查周期,决定 NameNode 每隔多久检查是否需要生成 checkpoint。- 该机制通过定期将 EditLog 中的增量操作合并到 FsImage 中,减少 EditLog 的大小,提高恢复速度,确保 NameNode 的元数据持久性和系统的稳定性。
NN 内存中的元数据会溢血到磁盘嘛?
NameNode中的元数据通常是 保留在内存中的,但在某些情况下,部分内存中的元数据会被 持久化到磁盘,具体而言,这些元数据会被写入到 FsImage和 EditLog中。以下是详细的解释:
1. 内存中的元数据
- 元数据存储在内存中:当 NameNode 启动时,它会将整个 HDFS 文件系统的结构(包括文件和目录信息、块信息等)加载到内存中。这些信息会驻留在内存中,以便 快速响应客户端的请求(例如读取文件信息、查找块位置等)。
- 内存中的元数据增长:随着 HDFS 中文件数量和目录结构的增加,内存中存储的元数据也会增加。每新增一个文件、目录或对文件系统的操作,都会导致内存中的元数据相应地增加。
2. 内存满了会溢写到磁盘吗?
- 内存不会直接溢写到磁盘:内存中的元数据不会直接“溢写”到磁盘。在 NameNode中,内存用于存储当前的文件系统元数据的实时状态。虽然 磁盘用于存储 FsImage和 EditLog等文件,但内存中的元数据并不会在内存不足时自动写入磁盘。磁盘和内存在这里是两个不同的存储层次:
- 内存:用于快速访问和管理文件系统的元数据。
- 磁盘:用于持久化和恢复元数据,保证数据不丢失,并且保证在重启后可以恢复。
3. 内存中的元数据与 FsImage
- FsImage是 NameNode 的元数据快照,它存储了文件系统的所有元数据的持久副本。NameNode 定期将内存中的元数据(例如文件和目录结构、块映射等)持久化到磁盘上的 FsImage文件中。
- FsImage 的作用:当 NameNode 重启时,系统会通过加载磁盘上的 FsImage 文件恢复内存中的元数据。因此,内存中的元数据并不会直接写入 FsImage,而是通过 周期性 checkpoint 操作将内存中增量变化的元数据合并到 FsImage 中。
4. Checkpoint 机制
Checkpoint 的过程:在定期的 checkpoint 操作中,NameNode 会将内存中的元数据与磁盘上的 EditLog 文件合并,生成一个新的 FsImage 文件。这个过程的主要目的是:
- 将内存中的所有变更写入到磁盘上的 FsImage 文件中。
- 清理 EditLog 文件,防止其变得过大。
内存和磁盘的分工:
- 内存:存储当前最新的元数据,供 NameNode 实时使用。
- 磁盘:存储 FsImage 和 EditLog 文件,保证数据的持久化和恢复能力。FsImage 定期生成,包含内存中元数据的快照。
5. 内存中的元数据会增加吗?
- 会增加:内存中的元数据会随着 HDFS 中文件和目录的增加而增长。每当文件被创建、删除或修改时,相应的元数据都会存储在内存中。
- 内存占用的增加:随着集群中文件数量的增加,内存的占用会逐渐增加,这可能导致 NameNode 内存消耗过高,特别是在大规模集群中。
6. 如何防止内存溢出?
增加内存:可以通过调整 JVM 启动参数来增加 NameNode 可用的最大内存,例如:
exportHADOOP_NAMENODE_OPTS="-Xmx16g"# 设置最大内存为16GB
这可以帮助处理更多的元数据,减少因内存不足导致的性能问题。
合理配置 Checkpoint:通过合理配置
dfs.namenode.checkpoint.txns
和dfs.namenode.checkpoint.check.period
参数,定期进行 checkpoint 操作,生成新的 FsImage 文件,减少 EditLog 的大小,从而减轻内存负担。避免小文件过多:HDFS 中小文件会导致元数据的急剧增加。通过合理的文件管理和合并小文件,可以有效减少内存中的元数据增长。
7. 总结
- 内存中的元数据是 NameNode 存储和管理文件系统状态的核心,负责快速响应客户端请求。随着文件系统规模的增加,内存中的元数据会增加。
- 内存不会直接溢写到磁盘,但定期生成的 FsImage文件会持久化当前内存中的元数据快照。
- Checkpoint 操作会定期将内存中的元数据与 EditLog 合并,生成新的 FsImage 文件,并清理 EditLog。
- 通过合理配置内存、Checkpoint 和避免过多小文件,可以有效管理 NameNode 的内存占用,避免内存溢出和性能瓶颈。
DataNode 工作机制(面试八股)
(1)一个数据块在DataNode上以文件形式存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据包括数据块的长度,块数据的校验和,以及时间戳。
(2)DataNode启动后向NameNode注册,通过后,周期性(6小时)的向NameNode上报所有的块信息。
DN向NN汇报当前解读信息的时间间隔,默认6小时;
<property><name>dfs.blockreport.intervalMsec</name><value>21600000</value><description>Determines block reporting interval in milliseconds.</description></property>
DN扫描自己节点块信息列表的时间,默认6小时
<property><name>dfs.datanode.directoryscan.interval</name><value>21600s</value><description>Interval in seconds for Datanode to scan data directories and reconcile the difference between blocks in memory and on the disk. Support multiple time unit suffix(case insensitive), as described in dfs.heartbeat.interval. </description></property>
(3)心跳是每3秒一次,心跳返回结果带有NameNode给该DataNode的命令如复制块数据到另一台机器,或删除某个数据块。如果超过10分钟没有收到某个DataNode的心跳,则认为该节点不可用。
(4)集群运行中可以安全加入和退出一些机器。
掉线时限参数设置
需要注意的是hdfs-site.xml 配置文件中的heartbeat.recheck.interval的单位为毫秒,dfs.heartbeat.interval的单位为秒。
<property><name>dfs.namenode.heartbeat.recheck-interval</name><value>300000</value></property><property><name>dfs.heartbeat.interval</name><value>3</value></property>