当前位置: 首页 > news >正文

探索HDFS读写流程、节点机制和数据完整性

目录

  • 写在前面
  • 一、HDFS的读写流程
    • 1.1 HDFS写数据流程
    • 1.2 机架感知
    • 1.3 HDFS读数据流程
    • 1.4 小结
  • 二、 NameNode和SecondaryNameNode
    • 2.1 NN和2NN工作机制
    • 2.2 Fsimage和Edits解析
      • 2.2.1 oiv查看Fsimage文件
      • 2.2.2 oev查看Edits文件
    • 2.3 CheckPoint时间设置
  • 三、DataNode
    • 3.1 DataNode工作机制
    • 3.2 数据完整性
    • 3.3 掉线时限参数设置

写在前面

Hadoop分布式文件系统(HDFS)是一种适用于大数据处理的分布式文件系统。在HDFS中,数据被分割成块并分布在多台机器上存储,以实现高容量、高可靠性和高吞吐量的数据存储和处理。以下是关于HDFS的读写流程、NameNode和Secondary NameNode、DataNode的简单介绍。

一、HDFS的读写流程

1.1 HDFS写数据流程

(1)客户端通过Distributed FileSystem模块向NameNode请求上传文件,NameNode审核权限、剩余空间后,满足条件允许写入;
(2)客户端请求第一个 Block上传到哪几个DataNode服务器上;
(3)NameNode返回3个DataNode节点,分别为dn1、dn2、dn3;
(4)客户端通过FSDataOutputStream模块请求dn1上传数据,dn1收到请求会继续调用dn2,然后dn2调用dn3,将这个通信管道建立完成。
(5)dn1、dn2、dn3逐级应答客户端。
(6)客户端开始往dn1上传第一个Block(先从磁盘读取数据放到一个本地内存缓存),以Packet为单位,dn1收到一个Packet就会传给dn2,dn2传给dn3;dn1每传一个packet会放入一个应答队列等待应答。
(7)当一个Block传输完成之后,客户端再次请求NameNode上传下一个Block的服务器。(重复执行2-7步)。

注意:

  • NameNode不负责数据的写入,只负责元数据记录和权限审批
  • 客户端直接向一台DateNode写数据,这个DateNode一般是离客户端最近(网络距离)的那一个
  • 数据块副本的复制工作,由DateNode之间自行完成(构建一个PipLine,按顺序复制分发)

1.2 机架感知

HDFS通过机架感知来提高数据的读写性能和可靠性。机架感知是指在选择数据副本节点时,将优先选择同一机架内的节点,以减少数据跨机架传输的延迟和带宽消耗。具体的机架感知策略可以通过配置文件进行调整。

在这里插入图片描述
简单来说就是,当文件副本数为三时,HDFS的放置策略是,如果写入程序位于数据节点上,则将一个副本放置在本地机器上,否则放置在与写入程序位于同一机架中的随机数据节点上、另一个副本放在不同(远程)机架中的节点上,最后一个副本则放在同一远程机架中的不同节点上。

1.3 HDFS读数据流程

(1)客户端通过DistributedFileSystem向NameNode请求读取某文件,NameNode通过查询元数据,找到文件块所在的DataNode地址。
(2)挑选一台DataNode(就近原则,然后随机)服务器,请求读取数据。
(3)DataNode开始传输数据给客户端(从磁盘里面读取数据输入流,以Packet为单位来做校验)。
(4)客户端以Packet为单位接收,先在本地缓存,然后写入目标文件。

1.4 小结

  • 客户端读写HDFS的数据流程简单来说:
    • 不管是都还是写,NameNode都不经手数据,均是客户端和DataNode直接通讯,不然对NameNode的压力太大
    • NameNode做授权判断(是否能写、是否能读)
    • 客户端直连DataNode进行写入、客户端直连DataNode进行block读取
    • 写入,客户端会被分配找距离自己最近的DataNode写数据
    • 读取,客户端拿到的Block列表会事网络距离最近的一份

二、 NameNode和SecondaryNameNode

2.1 NN和2NN工作机制

思考:NameNode中的元数据是存储在哪里的?
首先,我们做个假设,如果存储在NameNode节点的磁盘中,因为经常需要进行随机访问,还有响应客户请求,必然是效率过低。因此,元数据需要存放在内存中。但如果只存在内存中,一旦断电,元数据丢失,整个集群就无法工作了。因此产生在磁盘中备份元数据的FsImage。
这样又会带来新的问题,当在内存中的元数据更新时,如果同时更新FsImage,就会导致效率过低,但如果不更新,就会发生一致性问题,一旦NameNode节点断电,就会产生数据丢失。因此,引入Edits文件(只进行追加操作,效率很高)。每当元数据有更新或者添加元数据时,修改内存中的元数据并追加到Edits中。这样,一旦NameNode节点断电,可以通过FsImage和Edits的合并,合成元数据。
但是,如果长时间添加数据到Edits中,会导致该文件数据过大,效率降低,而且一旦断电,恢复元数据需要的时间过长。因此,需要定期进行FsImage和Edits的合并,如果这个操作由NameNode节点完成,又会效率过低。因此,引入一个新的节点SecondaryNamenode,专门用于FsImage和Edits的合并。

  1. 第一阶段:NameNode启动
  • 第一次启动NameNode格式化后,创建Fsimage和Edits文件。如果不是第一次启动,直接加载编辑日志和镜像文件到内存。
  • 客户端对元数据进行增删改的请求。
  • NameNode记录操作日志,更新滚动日志。
  • NameNode在内存中对元数据进行增删改。
  1. 第二阶段:Secondary NameNode工作
  • Secondary NameNode询问NameNode是否需要CheckPoint。直接带回NameNode是否检查结果。
  • Secondary NameNode请求执行CheckPoint。
  • NameNode滚动正在写的Edits日志。
  • 将滚动前的编辑日志和镜像文件拷贝到Secondary NameNode。
  • Secondary NameNode加载编辑日志和镜像文件到内存,并合并。
  • 生成新的镜像文件fsimage.chkpoint。
  • 拷贝fsimage.chkpoint到NameNode。
  • NameNode将fsimage.chkpoint重新命名成fsimage。

2.2 Fsimage和Edits解析

NameNode被格式化之后,将在/opt/module/hadoop-3.2.4/data/dfs/name/current目录中产生如下文件:

在这里插入图片描述

FsImage文件:HDFS文件系统元数据的一个永久性检查点,其中包含HDFS文件系统的所有目录和文件inode的序列化信息。
Edits文件:存放HDFS文件系统的所有更改操作的路径,文件系统客户端执行的所有写操作首先会被记录到Edits文件中。
seen_txid文件:保存的是一个数字,即最后一个edits的数字。

每次NameNode启动的时候都会将FsImage文件读入内存,加载Edits里面的更新操作,保证内存中的元数据信息是最新的、同步的,可以看成NameNode启动的时候就将FsImage和Edits文件进行了合并。

2.2.1 oiv查看Fsimage文件

(1)查看oiv和oev命令

[amo@hadoop102 current]$ hdfs
oiv            apply the offline fsimage viewer to an fsimage
oev            apply the offline edits viewer to an edits file

(2)基本语法
hdfs oiv -p 文件类型 -i镜像文件 -o 转换后文件输出路径
(3)案例实操

[amo@hadoop102 current]$ hdfs oiv -p XML -i fsimage_0000000000000000877 -o /opt/module/fsimage.xml
2024-03-12 22:08:53,287 INFO offlineImageViewer.FSImageHandler: Loading 5 strings
2024-03-12 22:08:53,329 INFO namenode.FSDirectory: GLOBAL serial map: bits=29 maxEntries=536870911
2024-03-12 22:08:53,329 INFO namenode.FSDirectory: USER serial map: bits=24 maxEntries=16777215
2024-03-12 22:08:53,329 INFO namenode.FSDirectory: GROUP serial map: bits=24 maxEntries=16777215
2024-03-12 22:08:53,329 INFO namenode.FSDirectory: XATTR serial map: bits=24 maxEntries=16777215
[amo@hadoop102 current]$ cat /opt/module/fsimage.xml

思考:Fsimage中没有记录块所对应DataNode,为什么?

在集群启动后,要求DataNode上报数据块信息,并间隔一段时间后再次上报。

2.2.2 oev查看Edits文件

(1)基本语法
hdfs oev -p 文件类型 -i 编辑日志 -o 转换后文件输出路径
(2)案例实操

[amo@hadoop102 current]$ hdfs oev -p XML -i edits_0000000000000000876-0000000000000000877 -o /opt/module/edits.xml
[amo@hadoop102 current]$ cat /opt/module/edits.xml 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<EDITS><EDITS_VERSION>-65</EDITS_VERSION><RECORD><OPCODE>OP_START_LOG_SEGMENT</OPCODE><DATA><TXID>876</TXID></DATA></RECORD><RECORD><OPCODE>OP_END_LOG_SEGMENT</OPCODE><DATA><TXID>877</TXID></DATA></RECORD>
</EDITS>
[amo@hadoop102 current]$ 

思考:NameNode如何确定下次开机启动的时候合并哪些Edits?

2.3 CheckPoint时间设置

  1. 通常情况下,SecondaryNameNode每隔一小时执行一次。
    [hdfs-default.xml]
<property><name>dfs.namenode.checkpoint.period</name><value>3600s</value>
</property>
  1. 一分钟检查一次操作次数,当操作次数达到1百万时,SecondaryNameNode执行一次。
<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>

三、DataNode

3.1 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 describedin dfs.heartbeat.interval.</description>
</property>
  1. 心跳是每3秒一次,心跳返回结果带有NameNode给该DataNode的命令如复制块数据到另一台机器,或删除某个数据块。如果超过10分钟没有收到某个DataNode的心跳,则认为该节点不可用。
  2. 集群运行中可以安全加入和退出一些机器。

3.2 数据完整性

思考:如果电脑磁盘里面存储的数据是控制高铁信号灯的红灯信号(1)和绿灯信号(0),但是存储该数据的磁盘坏了,一直显示是绿灯,是否很危险?同理DataNode节点上的数据损坏了,却没有发现,是否也很危险,那么如何解决呢?

如下是DataNode节点保证数据完整性的方法。

  • 当DataNode读取Block的时候,它会计算CheckSum。
  • 如果计算后的CheckSum,与Block创建时值不一样,说明Block已经损坏。
  • Client读取其他DataNode上的Block。
  • 常见的校验算法crc(32),md5(128),sha1(160)
  • DataNode在其文件创建后周期验证CheckSum。

3.3 掉线时限参数设置

需要注意的是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>

相关文章:

  • 基于EasyCVR视频技术的流媒体视频融合与汇聚管理系统建设方案
  • 【ARM linux mqtt协议连接服务器】
  • 16 OpenCV Laplance算子
  • 初识Spring MVC
  • 【数据挖掘】练习1:R入门
  • 自然语言处理(NLP)—— 语义关系提取
  • HTML 学习笔记(九)颜色值和长度单位
  • ThingsBoard开源物联网平台介绍
  • python3:No module named ‘pandas‘
  • LeetCode454 四数相加
  • 用Docker Compose实现负载均衡【入门篇】
  • 数据库管理-第160期 Oracle Vector DB AI-11(20240312)
  • STM32外设分类--学习笔记
  • Kotlin Retrofit 网络请求
  • Facebook:连接世界的社交巨人
  • Android框架之Volley
  • Babel配置的不完全指南
  • JavaScript新鲜事·第5期
  • java中的hashCode
  • leetcode-27. Remove Element
  • PHP的Ev教程三(Periodic watcher)
  • PHP的类修饰符与访问修饰符
  • Rancher如何对接Ceph-RBD块存储
  • ReactNativeweexDeviceOne对比
  • 对超线程几个不同角度的解释
  • 想写好前端,先练好内功
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • 学习Vue.js的五个小例子
  • 用 Swift 编写面向协议的视图
  • 扩展资源服务器解决oauth2 性能瓶颈
  • ​MPV,汽车产品里一个特殊品类的进化过程
  • ​渐进式Web应用PWA的未来
  • # Maven错误Error executing Maven
  • #1015 : KMP算法
  • #define 用法
  • #NOIP 2014#Day.2 T3 解方程
  • #微信小程序:微信小程序常见的配置传旨
  • (MATLAB)第五章-矩阵运算
  • (二开)Flink 修改源码拓展 SQL 语法
  • (非本人原创)我们工作到底是为了什么?​——HP大中华区总裁孙振耀退休感言(r4笔记第60天)...
  • (附源码)springboot青少年公共卫生教育平台 毕业设计 643214
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (接口自动化)Python3操作MySQL数据库
  • (九)c52学习之旅-定时器
  • (推荐)叮当——中文语音对话机器人
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • (转)VC++中ondraw在什么时候调用的
  • (转)程序员疫苗:代码注入
  • (转)总结使用Unity 3D优化游戏运行性能的经验
  • (转载)Google Chrome调试JS
  • .NET CORE 第一节 创建基本的 asp.net core
  • .Net 知识杂记
  • .NET/C# 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中(Constrained Execution Regions)
  • .Net8 Blazor 尝鲜