一文理解HDFS的原理和架构(hdfs基本工作原理)
wxin55 2024-11-11 14:40 9 浏览 0 评论
HDFS概述
HDFS是一个分布式的文件系统。用于存储文件,通过统一的命名空间——目录树来定位文件。
优点
- 高容错性:数据自动保存多个副本,默认是三个副本,副本丢失后,会自动恢复。
- 适合批处理:移动计算而非移动数据,批处理的时候,数据量很大,移动数据是不合适的,好的方式是分布式的移动计算。数据位置暴露给计算框架,数据被切分为 block list,block list 存放在哪些node list 上,在 namenode 上,是有这两个维度的记录的
- 适合大数据处理:GB、TB、甚至 PB 级数据,当然小数据也是可以的,有相应方法百万规模以上的文件数量10K + 节点规模
- 流式文件访问:一次性写入,多次读取。保证数据一致性
- 可构建在廉价机器上,通过多副本提高可靠性,提供了容错和恢复机制
缺点
- 不适合低延迟的数据访问:比如毫秒级,这个 HDFS 是做不到的,HDFS 不适合低延迟的处理场景,适合需要高吞吐率的场景
- 不适合小文件存取:每个文件存入 HDFS 都会被切分为一些 blocks ,namenode 中保存了二个维度的映射,1亿个1k 的小文件,文件大小一共 1G,可能占用10G 的内存,这是不合适的(数据仅为假设)。寻道时间超过读取时间,我们知道,在计算机里面寻找文件,是先要寻道(找到文件存在的扇区),再去读取文件,这两步,时间花费主要在寻道,而不是文件读取
- 不适合并发写入、文件随机修改:HDFS 中,一个文件只能有一个写者仅支持 append,不支持或者不建议文件修改,这里解释下,HDFS 对于文件的修改方式,先读取数据,修改数据,最后再重新写入一个文件
HDFS 基本架构
HDFS架构
HDFS架构是一个典型的主从架构,包括一个NameNode(主节点)和多个DataNode(从节点)。
NameNode
- 用于管理文件系统的命名空间、维护文件系统的目录结构树以及元数据信息,记录写入的每个数据块(Block)与其归属文件的对应关系。
- 此信息以命名空间镜像(FSImage)和编辑日志(EditsLog)两种形式持久化在本地磁盘中。
DataNode
- DataNode是文件的实际存放位置。
- DataNode会根据NameNode或Client的指令来存储或者提供数据块,并且定期的向NameNode汇报该DataNode存储的数据块信息。
Client
通过Client来访问文件系统,然后由Client与NameNode和DataNode进行通信。Client对外作为文件系统的接口,类似于POSIX。
Blocks
HDFS将文件拆分成128 MB大小的数据块进行存储,这些Block可能存储在不同的节点上。HDFS可以存储更大的单个文件,甚至超过任何一个磁盘所能容纳的大小。一个Block默认存储3个副本(EMR Core节点如果使用云盘,则为2副本),以Block为粒度将副本存储在多个节点上。此方式不仅提高了数据的安全性,而且对于分布式作业可以更好地利用本地的数据进行计算,减少网络传输。
Secondary NameNode
对于非高可用集群,默认会启动一个Secondary NameNode进程。Secondary NameNode的作用是消费EditsLog,定期地合并FsImage和EditsLog,生成新的FsImage文件,降低了NameNode的压力。
高可用
对于高可用集群,默认会启动两个NameNode,一个是Active NameNode,另一个是Standby NameNode,两个NameNode承担不同角色。
Active NameNode负责处理DataNode和Client的请求,Standby NameNode跟Active NameNode一样拥有最新的元数据信息,随时准备在Active NameNode出现异常时接管其服务。如果Active NameNode异常,Standby NameNode会感知到并切换成Active NameNode的角色处理DataNode和Client请求。
DN 会向 NN 每隔几秒钟发一次心跳,来告诉 NN 自己的状态,当一个 DN 挂掉,NN 没有收到该 DN 的心跳,该 DN 上的数据会被再次备份到其他 node 上,但这会有一个问题,不同的机器,负载情况,记录的数据量不均衡,此时,可以通过 balance 组件,来进行负载均衡,当集群扩容的时候,同样可以调用 banance 组件来处理。
先介绍下左侧的 NN,它在内存中记录了两个维度(文件结构就是一棵树)的信息
- file —> block list,这一维度会保存在内存,并被序列化到磁盘,这个树(元信息或者这一维度的记录或者文件镜像)被称之为 fsimage(file system image)
- block —> node list,这一维度不会被存到磁盘仅保存在内存,其关系的维持,主要靠 DN 周期性的向 NN 汇报自身的 block list ,当调用 balance 的时候,dn 上面的 node list 会发生变化,dn 同样会告知 nn 自身现在的情况
NN 可以配置副本策略,每个 block 及其副本存放在哪些 node 上,可以处理客户端的读写请求,但是具体执行处理请求是 dn 来做
再说右边 Standby NN,这是 hadoop2 之后提出的一个概念 HA,为了解决 NN 的单点故障,之前一直都是 Second NN,Standby NN 会去监控NN 的健康状态,当发现 NN 挂掉以后,Standby NN 会自动切换为 NN。fsimage 因为是被序列化到磁盘,所以当 NN 挂掉或者重启,这部分数据不会丢失,但机器上的 block 信息,如果正好碰到有写入发生,该 node 挂掉,那么数据是不是会丢失呢?答案是不会,原理是:client 每次有写入或者增加一个文件等请求,这时候是会把这些这些操作都会记录到一个 log,也就是fsedit,而不是立马更新到 NN 的 fsimage,重启时,会先加载 fsimage,再去读取 editlog ,这样,NN 中的文件数就是最新的。
详细介绍:
这个树(fsimage)是写到磁盘了,但是现在有一个对这个树的修改,比如说创建了一个文件,这个时候怎么办,这时候可以引入log。如果重启的时候,我先载入 fsimage ,然后我的log记录了我对文件树的整个修改,我对 fsimage 依次的执行 log,就可以把文件树恢复到最新,但是我如果每次都把修改或者改动记录到log,也不行,因为当log越来越大,重启的时候,会越来越慢,这时候就出现了Second NN,他定期的合并fsimage和editlog,然后将最新的 fsimage 发送给 NN,告诉 NN 可以把旧的 fsimage 删掉,用我这个新的替换Second NN,一个较老的名字,Second 没有热备的功能,后来发展发展成为 HA 的 Standby,Standby 承载了一部分 Second 的功能(合并 fsimage 和 editlog),并成为热备HA 与 Federation
HDFS读写I/O
写流程
HDFS client 创建一个file,会向 NN 申请空间资源,比如写入哪些机器,这些 128M 的块会再次切分成 512字节的package(包含了CRC32的校验,在三个 node 之间验证,来确保数据完整性),因为客户端一次性缓存128M 是比较可怕的事情,会占用大量内存,按照这样的方式依次、流式、串行的写数据
这里为什么不选择同时向三个 DN 写入呢,因为这样会占用更多的带宽,不如串行、流式的写好
写的时候,NN 会生成由三个 DN 构成的一个list,并告诉第一个 DN 要写入的数据以及后面两个 DN 的信息,三个 DN 依次写的时候,有一个 DN 挂掉,则会跳过他,将它从 list 中移除,然后继续入写其余两个 DN
当三个 DN 都遍历写完,DN 才会告知 NN,而不是写完一个 DN 该 DN 就告知 NN
如果一次写入,有两个 DN 都正好挂掉,那么 HDFS 会认为这次写入是失败的,因为这个时候也可能出现唯一写入成功的 DN 挂掉,这违背了 HDFS 高可用高容错性,NN 会重新分配,重新写,这是默认是实现
读流程
HDFS client 读取文件的时候,会向 NN 去获取一个 block locations ,然后打开输入流,按照就近原则,在相应 DN 上读取数据
就近原则是,本地 > 同机架 >同交换机 > 同机房
同一个机架任意两个节点之间共享 1Gbps 带宽,机架之间带宽为 2-10 Gbps,每个机架通常有16-64 个节点
HDFS内部机制—副本放置策略
HDFS 访问方式
主要分为 Shell 命令和 API 这两种方式
相关推荐
- ES6中 Promise的使用场景?(es6promise用法例子)
-
一、介绍Promise,译为承诺,是异步编程的一种解决方案,比传统的解决方案(回调函数)更加合理和更加强大在以往我们如果处理多层异步操作,我们往往会像下面那样编写我们的代码doSomething(f...
- JavaScript 对 Promise 并发的处理方法
-
Promise对象代表一个未来的值,它有三种状态:pending待定,这是Promise的初始状态,它可能成功,也可能失败,前途未卜fulfilled已完成,这是一种成功的状态,此时可以获取...
- Promise的九大方法(promise的实例方法)
-
1、promise.resolv静态方法Promise.resolve(value)可以认为是newPromise方法的语法糖,比如Promise.resolve(42)可以认为是以下代码的语...
- 360前端一面~面试题解析(360前端开发面试题)
-
1.组件库按需加载怎么做的,具体打包配了什么-按需加载实现:借助打包工具(如Webpack的require.context或ES模块动态导入),在使用组件时才引入对应的代码。例如在V...
- 前端面试-Promise 的 finally 怎么实现的?如何在工作中使用?
-
Promise的finally方法是一个非常有用的工具,它无论Promise是成功(fulfilled)还是失败(rejected)都会执行,且不改变Promise的最终结果。它的实现原...
- 最简单手写Promise,30行代码理解Promise核心原理和发布订阅模式
-
看了全网手写Promise的,大部分对于新手还是比较难理解的,其中几个比较难的点:状态还未改变时通过发布订阅模式去收集事件实例化的时候通过调用构造函数里传出来的方法去修改类里面的状态,这个叫Re...
- 前端分享-Promise可以中途取消啦(promise可以取消吗)
-
传统Promise就像一台需要手动组装的设备,每次使用都要重新接线。而Promise.withResolvers的出现,相当于给开发者发了一个智能遥控器,可以随时随地控制异步操作。它解决了三大...
- 手写 Promise(手写输入法 中文)
-
前言都2020年了,Promise大家肯定都在用了,但是估计很多人对其原理还是一知半解,今天就让我们一起实现一个符合PromiseA+规范的Promise。附PromiseA+规范地址...
- 什么是 Promise.allSettled()!新手老手都要会?
-
Promise.allSettled()方法返回一个在所有给定的promise都已经fulfilled或rejected后的promise,并带有一个对象数组,每个对象表示对应的pr...
- 前端面试-关于Promise解析与高频面试题示范
-
Promise是啥,直接上图:Promise就是处理异步函数的API,它可以包裹一个异步函数,在异步函数完成时抛出完成状态,让代码结束远古时无限回掉的窘境。配合async/await语法糖,可...
- 宇宙厂:为什么前端离不开 Promise.withResolvers() ?
-
大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发。1.为什么需要Promise.with...
- Promise 新增了一个超实用的 API!
-
在JavaScript的世界里,Promise一直是处理异步操作的神器。而现在,随着ES2025的发布,Promise又迎来了一个超实用的新成员——Promise.try()!这个新方法简...
- 一次搞懂 Promise 异步处理(promise 异步顺序执行)
-
PromisePromise就像这个词的表面意识一样,表示一种承诺、许诺,会在后面给出一个结果,成功或者失败。现在已经成为了主流的异步编程的操作方式,写进了标准里面。状态Promise有且仅有...
- Promise 核心机制详解(promise机制的实现原理)
-
一、Promise的核心状态机Promise本质上是一个状态机,其行为由内部状态严格管控。每个Promise实例在创建时处于Pending(等待)状态,此时异步操作尚未完成。当异步操作成功...
- javascript——Promise(js实现promise)
-
1.PromiseES6开始支持,Promise对象用于一个异步操作的最终完成(包括成功和失败)及结果值的表示。简单说就是处理异步请求的。之所以叫Promise,就是我承诺,如果成功则怎么处理,失败怎...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- ES6中 Promise的使用场景?(es6promise用法例子)
- JavaScript 对 Promise 并发的处理方法
- Promise的九大方法(promise的实例方法)
- 360前端一面~面试题解析(360前端开发面试题)
- 前端面试-Promise 的 finally 怎么实现的?如何在工作中使用?
- 最简单手写Promise,30行代码理解Promise核心原理和发布订阅模式
- 前端分享-Promise可以中途取消啦(promise可以取消吗)
- 手写 Promise(手写输入法 中文)
- 什么是 Promise.allSettled()!新手老手都要会?
- 前端面试-关于Promise解析与高频面试题示范
- 标签列表
-
- hive行转列函数 (63)
- sourcemap文件是什么 (54)
- display none 隐藏后怎么显示 (56)
- 共享锁和排他锁的区别 (51)
- httpservletrequest 获取参数 (64)
- jstl包 (64)
- qsharedmemory (50)
- watch computed (53)
- java中switch (68)
- date.now (55)
- git-bash (56)
- 盒子垂直居中 (68)
- npm是什么命令 (62)
- python中+=代表什么 (70)
- fsimage (51)
- nginx break (61)
- mysql分区表的优缺点 (53)
- centos7切换到图形界面 (55)
- 前端深拷贝 (62)
- kmp模式匹配算法 (57)
- jsjson字符串转json对象 (53)
- jdbc connection (61)
- javascript字符串转换为数字 (54)
- mybatis 使用 (73)
- 安装mysql数据库 (55)