深入分析HDFS原理及读写流程
本文目录
- 一、架构体系
- 1.1、什么是HDFS?
- 1.2、组成HDFS的各模块作用
- 1.2.1、Client
- 1.2.2、NameNode
- 1.2.3、DataNode
- 1.2.4、SecondaryNameNode
- 二、数据读写
- 2.1、读数据
- 2.2、写数据
- 三、优缺点
一、架构体系
1.1、什么是HDFS?
HDFS即Hadoop Distributed File System的简称,采用Master/Slave主从结构模型来管理数据。在设计上采用了分而治之的思想,将单服务器无法承受的大量的数据分布在多台服务器上。HDFS主要由Client、NameNode、DataNode,SecondaryNameNode这四部分组成。
1.2、组成HDFS的各模块作用
1.2.1、Client
HDFS客户端是在DFSClient类的基础上实现的,提供了命令行接口、API接口、浏览器接口等面向用户的接口,使用户可以不考虑HDFS的实现细节,简化操作。
客户端在整个HDFS的作用可以进行如下总结:
- 上传文件时按照Block块大小进行文件的切分;
- 和NameNode交互,获取文件位置信息;
- 和DataNode交互,读取和写入数据;
- 管理和访问整个HDFS。
1.2.2、NameNode
NameNode在HDFS结构模型里充当Master的就角色,因此一个HDFS集群里只会有一个active的NameNode节点。在集群里主要用来处理客户端的读写请求,它主要负责管理命名空间(NameSpace)和文件Block映射信息。
nameSpace:
nameSpace维护着文件系统树(FileSystem Tree)和文件树上的所有文件及文件夹的元数据(metadata),并使用fsimage和editlog这两个文件来管理这些信息。fsimage(空间镜像文件),它是文件系统元数据的一个完整的永久检查点,内部维护的是最近一次检查点的文件系统树和整棵树内部的所有文件和目录的元数据,如修改时间,访问时间,访问权限,副本数据,块大小,文件的块列表信息等等。editlog(编辑日志文件),当HDFS系统发生打开、关闭、创建、删除、重命名等操作产生的信息除了在保存在内存中外,还会持久化到编辑日志文件。比如上传一个文件后,日志文件里记录的有这次事务的tx id,文件的inode id,数据块的副本数,数据块的id,数据块大小,访问时间,修改时间等。
文件Block映射信息:
作为一个master,NameNode需要记录每个文件的每个块所在的数据节点的位置信息,也就是我们常说的元数据信息metaData。但是由于NameNode并不进行持久化存储,因此NameNode需要管理Block到DataNode的映射信息。一般元数据主要是文件名—> 数据块映射和数据块 —> Datanode列表映射。
其中文件名 —> 数据块映射保存在磁盘上进行持久化存储,但是NameNode并不保存数据块 —> DataNode列表映射,这份列表是通过心跳机制(heartbeat)建立起来的。NameNode执行文件系统的namespace操作,如打开、关闭、重命名文件和目录的同时决定了文件数据块到具体DataNode节点的映射。
HDFS心跳机制:
由于HDFS是master/slave结构,其中master包括namenode和resourcemanager,slave包括datanode和nodemanager。在master启动时会开启一个IPC服务,然后等待slave连接。当slave启动后,会主动以默认3秒一次的频率链接IPC服务。当然这个时间是可以调整的,这个每隔一段时间连接一次的机制,就是心跳机制(默认的 heartbeat.recheck.interval 大小为 5 分钟,dfs.heartbeat.interval 默认的大小为 3 秒)。slave通过心跳给master汇报自己信息,master通过心跳下达命令。具体来说就是:
Namenode通过心跳得知DataNode状态,Resourcemanager通过心跳得知nodemanager状态
当master很长时间没有收到slave信息时,就认为slave挂掉了。
这个判断挂掉的时间计算公式:2recheck+10heartbeat(Recheck的时间单位为毫秒,heartbeat的时间单位为秒 ),默认为10分钟30秒 。
举例:如果 heartbeat.recheck.interval 设置为 6000(毫秒), dfs.heartbeat.interval设置为 5(秒),则总的超时时间为 62 秒。
NameNode作用小结:
- 管理命名空间NameSpace;
- 管理Block映射信息;
- 配置副本策略;
- 处理客户端的读写请求。
1.2.3、DataNode
DataNode在HDFS结构里里是Slave的角色,因此就像咱们的实际生活一样,在整个HDFS集群里DataNode是有很多的。DataNode负责数据块的存储和读取,数据块存储在DataNode节点所在的本地文件系统中(包括block和block meta),并且它会利用心跳机制定期向NameNode发送自己所存储的block块映射列表。
数据块:
数据块是指存储在HDFS中的最小单元,默认会在多个DataNode节点存储3份,每个数据块默认128M。**这里为什么是128M呢?**因为考虑到了寻址时间是10ms,而传输速率为100MB/s,所以为了最小化寻址的开销同时兼顾传输效率,选择了128M,这样寻址只占用传输时间的1%。
DataNode作用小结:
存储实际的Block数据块
执行数据块的读/写操作
1.2.4、SecondaryNameNode
SecondaryNameNode不是NameNode的热备份,因为当NameNode停止服务时,它不能很快的替换NameNode。它更像是咱们现实生活中的老板NameNode的秘书,平时整理整理文档,帮老板分担工作。它主要是用来辅助NameNode进行fsimage和editlog的合并工作,可以减少editlog的文件大小。这样就可以节省NameNode的重启时间,可以尽快的退出安全模式。
检查点机制:
editlog和fsimage两个文件的合并周期,被称为检查点机制(checkpoint)
fsimage文件是文件系统元数据的持久化检查点,不会在写操作后马上更新,因为fsimage写非常慢。
由于editlog不断增长,在NameNode重启时,会造成长时间NameNode处于安全模式,不可用状态,是非常不符合Hadoop的设计初衷。所以要周期性合并editlog,但是这个工作由Namenode来完成,会占用大量资源,这样就出现了SecondaryNamenode,它可以进行image检查点的处理工作。
具体步骤如下:
- SecondaryNamenode请求Namenode进行editlog的滚动也就是创建一个新的editlog,然后将新的编辑操作记录到新生成的editlog文件;
- 通过http get方式,读取NameNode上的fsimage和edits文件,到SecondaryNamenode上;
- 读取fsimage到内存中,即加载fsimage到内存,然后执行edits中所有操作,并生成一个新的fsimage文件(fsimage.ckpt临时文件),也就是这个检查点被创建了;
- 通过http post方式,将fsimage.ckpt临时文件传送到Namenode;
- Namenode使用新的fsimage替换原来的fsimage文件(fsimage.ckpt重命名为fsimage),并且用第一步创建的edits(editlog)替代原来的edits文件;然后更新fsimage文件的检查点时间。
SecondaryNameNode作用小结:
辅助NameNode,分担其部分工作
定期合并fsimage和fsedits,并推送给NameNode
在紧急情况下,可辅助恢复NameNode
二、数据读写
HDFS的数据读写都分为很多步骤,想要轻松的掌握它,有个简单的小技巧------从粗略到细致。也就是我们先知道大致的流程,然后再把每一步进行细化,最终全部掌握。
开始掌握读写流程前,需要先了解3个基本概念:
block
前面也提到过block块,它是数据存储的最大单位,在进行文件上传前client会对文件进行分块,分得的块就是block,默认128M,这是在综合考虑寻址时间和传输效率的的情况下得出的最佳大小。
packet
packet是client向DataNode传输数据时候的基本单位,默认64KB。
chunk
chunk是进行数据校验的基本单位,默认512Byte,加上4Byte的校验位,实际上chunk写入packet的大小为516Byte,常见于client向DataNode进行的数据校验。
2.1、读数据
粗略流程(便于记忆):
- client向namenode请求block所在的datanode节点列表;
- client从最近位置逐个依次从datanode中读取block信息;
- 整个通过io流读取的过程需要校验每个快信息;
- 读取完成,关闭所有流。
细致流程(便于理解):
首先调用FileSystem的open方法获取一个DistributedFileSystem实例;
然后DistributedFileSystem实例通过RPC在NameNode里获得文件的第一批block的locations(可能是需要读取文件的全部,也可能是一部分),同一个block会按照在DataNode的重复数返回多个locations;
返回的多个locations会按照Hadoop拓扑结构排序,按照就近原则来排序;
前面三步结束后会返回一个FSDataInputStream对象,通过调用read方法时,该对象会找出离客户端最近的DataNode并与之建立连接;
数据通过io流从DataNode源源不断地流向客户端;
如果第一个block块数据读取完成,就会关闭指向第一个block块的DataNode连接,接着读取下一个block块,直到把这一批的block块数据读取完成;
每读取完一个block块都会进行checksum验证(校验每个块的信息通过偏移量和预写值对比,写的时候是校验packet的信息),如果读取 DataNode 时出现错误,客户端会 通知 NameNode,然后再从下一个拥有该 block 拷贝的 DataNode 继续读;
如果第一批blocks读取完成,且文件读取还没有结束,也就是文件还没读完。FSDataInputStream就会向NameNode获取下一批blocks的locations,然后重复上面的步骤,直到所有blocks读取完成,这时就会关闭所有的流。
2.2、写数据
粗略流程(便于记忆):
- client向NameNode发送写文件请求;
- NameNode检查文件,如果通过就返回输出流对象;
- client切分文件并且把数据和NameNode返回的DataNode列表一起发送给最近的一个DataNode节点;
- DataNode写完之后返回确认信息;
- 数据全部写完,关闭输入输出流,并发送完成信号给NameNode。
细致流程(便于理解):
- 客户端使用Configuration类加载配置文件信息,然后调用FileSystem的get()方法,获取一个分布式文件系统对象DistributedFileSystem。然后通过调用这个对象的create方法,向NameNode发送写文件请求;
- 客户端通过RPC与NameNode进行通信,NameNode需要经过各种不同的检查,比如命名空间里该路径文件是否存在,客户端是否有相应权限。如果没有通过,返回IOException,反之如果检查通过,NameNode就会在命名空间下新建该文件(此时新文件大小为0字节),并记录元数据,返回一个FSDataOutputStream输出流对象;
- FSDataOutputStream封装了一个DFSOutputStream对象,由该对象负责处理datanode和namenode之间的通信。(DistributedFileSystem.create()会调用DFSClient.create()方法创建DFSOutputStream输出流并构造一个HdfsDataOutputStream来包装DFSOutputStream);
- 客户端把数据按照block块进行切分;
- 然后调用DFSOutputStream的create方法,开始执行写入操作(FSDataOutputStream封装了一个DFSOutputStream对象,由该对象负责处理datanode和namenode之间的通信),DFSOutputStream会把数据切成一个个小packet,然后排成队列 dataQueue;
- DataStreamer(DFSOutputStream的内部线程类)会去处理dataQueue,它先问询 NameNode 这个新的 block 最适合存储的在哪几个DataNode里,比如重复数是3,那么就找到3个最适合的 DataNode,把它们排成一个 pipeline。DataStreamer 把 packet 按队列输出到管道的第一个 DataNode 的内存中,然后第一个 DataNode又把 packet 输出到第二个 DataNode 中,以此类推;
- 在DataStreamer将packet写入pipeline时,同时也会将该packet存储到另外一个由ResponseProcessor线程管理的缓存队列ackqueue确认队列中。ResponseProcessor线程会等待DataNode的确认响应。当收到所有的DataNode的确认信息后,该线程再将ackqueue里的packet删除;
- 如果写入期间发生故障,会首先关闭pipeline,把ackqueue的所有packet都放回dataqueue的最前端,以确保故障节点后的节点不会漏掉任一packet。同时,会标识正常的DataNode,方便在故障节点恢复后,删除错误的部分数据块。然后从管线中删除故障节点,基于新的DataNode构建一个新的管线;
- 在一个block块大小的n个packet数据包写完后,客户端会调用FSDataOutputStream的close方法关闭写入流,当然在调用close之前,DataNode会将内存中的数据写入本地磁盘;
- 最后DataStreamer会继续向NameNode请求下一个块的DataNode列表,开始下一个块的写入。直到写完整个文件的最后一个块数据,然后客户端通知 NameNode 把文件标示为已完成,到这里整个写入过程就结束了。
三、优缺点
数据的读写是HDFS的核心和考察重点,下面在结合着总结一下优缺点:
优点:
- 简单一致性模型:一次写入,多次读取,但要注意不能修改,只能追加;
- 高容错,低成本:可以搭建在廉价的机器上,并且数据以多副本保存在不同的服务器上,某个副本丢失,也能通过别的副本进行恢复;
- 流式数据访问:不是随机读写;
- 适合大规模数据集:能够进行批处理,支持横向扩展,支持PB级数据和10k节点规模。
缺点:
- 延迟高:不支持低延迟数据访问,做不到毫秒级存储数据,但是适合高吞吐率(某一时间内写入大量的数据)的场景;
- 不适合小文件:每条元数据占用空间是一定的,因此大量小文件会占用NameNode大量的内存来存储文件、目录和块信息;
- 不支持并发写入:一个文件只允许一个线程进行写操作,不适合并发写入;
- 不能修改和随机读写:文件不允许修改,只支持追加,同时也不是随机读写。
深入分析HDFS原理及读写流程相关推荐
- (转载)深入分析HDFS原理及读写流程
一.架构体系 1.1.什么是HDFS? HDFS即Hadoop Distributed File System的简称,采用Master/Slave主从结构模型来管理数据.在设计上采用了分而治之的思想, ...
- 2021年大数据Hadoop(十):HDFS的数据读写流程
2021大数据领域优质创作博客,带你从入门到精通,该博客每天更新,逐渐完善大数据各个知识体系的文章,帮助大家更高效学习. 有对大数据感兴趣的可以关注微信公众号:三帮大数据 目录 HDFS的数据读写流程 ...
- Apache Durid (HDFS原理 特性 读写测试 集群部署 架构设计)
Apache Durid (HDFS 集群部署) Apache Durid (HDFS 集群部署) 1. 分布式文件HDFS 1.1 HDFS简介 1.1.1 HDFS发展历史 1.1.2 HDFS设 ...
- hadoop学习笔记(三):hdfs体系结构和读写流程(转)
原文:https://www.cnblogs.com/codeOfLife/p/5375120.html 目录 HDFS 是做什么的 HDFS 从何而来 为什么选择 HDFS 存储数据 HDFS 如何 ...
- HBase原理(读写流程)
1 概述 HBASE是一个数据库----可以提供数据的实时随机读写 HBASE与mysql.oralce.db2.sqlserver等关系型数据库不同,它是一个NoSQL数据库(非关系型数据库) Hb ...
- hdfs读写流程_深度探索Hadoop分布式文件系统(HDFS)数据读取流程
一.开篇 Hadoop分布式文件系统(HDFS)是Hadoop大数据生态最底层的数据存储设施.因其具备了海量数据分布式存储能力,针对不同批处理业务的大吞吐数据计算承载力,使其综合复杂度要远远高于其他数 ...
- hdfs读写流程_一篇文章搞清楚 HDFS 基本原理
随着互联网的发展,数据日益增多,增长超过了单机能够处理的上线,数据如何存储和处理成为了科技公司的难题,随着google的三篇论文的发布,大家终于找到了一个方案-分布式文件系统+MapReduce.Ha ...
- 大数据系列文章-Hadoop的HDFS读写流程(二)
在介绍HDFS读写流程时,先介绍下Block副本放置策略. Block副本放置策略 第一个副本:放置在上传文件的DataNode:如果是集群外提交,则随机挑选一台磁盘不太满,CPU不太忙的节点. 第二 ...
- HDFS详解(架构设计、副本放置策略、读写流程、进程、常用命令等)
前言:当数据集的大小超过一台独立的物理计算机的存储能力时,就有必要对它进行分区(Partition)并存储到若干台单独的计算机上.管理网络中跨多台计算机存储的文件系统成为分布式文件系统(distrib ...
- java基础巩固-宇宙第一AiYWM:为了维持生计,大数据Hadoop之HDFS分布式文件系统(HDFS读写流程、主从集群两种问题“单点故障”及“压力过大内存受限”、HDFS的架构设计)~整起
Hadoop之HDFS 目录 一.大数据 二.HADOOP 三.HDFS 1.HDFS基本概念 2.HDFS的架构设计 3.HDFS自己对于上面两种数据持久化技术的实现: 4.HDFS读写流程 5.H ...
最新文章
- 新手可以做的ai比赛:亲测有效
- 设计模式 - 建造者模式(Builder Pattern)
- 最简单的基于FFmpeg的AVDevice例子(屏幕录制)
- wait()和sleep()
- 面向过程和面向对象的本质理解
- 弹框插件self(动效兼容到IE9,功能兼容IE6)
- python最大公约数计算。从键盘接收两个整数_python如何求解两数的最大公约数
- OpenCms创建网站过程图解
- c语言函数base,c中base的用法
- 南京大学量子计算机陈教授,南京大学于扬教授应邀访问武汉物数所
- 全新的Uber App设计
- 【NLP】一种自写的分词算法-中文基于字,英文基于单词,支持自定义字典
- An error occurred at line: [14] in the generated java file:
- Nagios的插件-nsca
- 虚幻引擎5 C++编程学习
- JSON解析合集:你再也不用怕JSON解析了!!!
- rabbitmq-plugins enable rabbitmq_web_stomp
- 使用LibreOffice将word转化为pdf -解决中文乱码
- ifconfig命令
- 记录nltk的stem操作
热门文章
- 私藏的18个黑科技网站,想找什么软件就找什么软件!!!
- C51系列单片最小机原理图及L298N接线图
- Redis视频教程免费下载
- core net wireless net
- 卡巴斯基激活试用方法
- 手机号归属地查询实例
- 世界黑客编程大赛第一名的作品(97年Mekka ’97 4K Intro比赛)
- 瑞友虚拟化系统搭建服务器,瑞友云电脑虚拟化系统 | 瑞友天翼-应用虚拟化|远程接入|桌面虚拟化|国内虚拟化整体解决方案领导者...
- Android应用程序开发习题答案
- linux 服务器 硬盘测试工具,linux硬盘检测工具:Smartmontools使用指南