HDFS(Hadoop Distributed File System)是一个运行在商用机器上面的分布式文件系统,其设计思想来自于google著名的Google File System论文。

HDFS的设计目标:为何产生HDFS?

由于数据量的急剧增大,原有的单机多磁盘因为速度,存储量等原因,已经远远无法满足要求,HDFS应运而生。
HDFS解决的痛点:

  1. 高容错性:HDFS设计运行在成百上千的机器上,任何一台机器都有可能随时发生损坏,这要求HDFS能够随时应对机器故障。
  2. 流式数据访问:HDFS适用于批处理而非用户即时交互;高吞吐量而非低数据访问延迟;运行的应用程序对其数据集能够进行流式访问。
  3. 适合大数据量:适合GB或者TB级别的数据存储;在单个集群中,有上百个节点提供服务。
  4. HDFS适合一次写多次读的模型。MapReduce和网络爬虫适合这种模型。
  5. 认为数据的移动比计算的移动代价更小。必要情况下,HDFS提供了将应用程序移动到数据所在位置的接口。
  6. 适用于多种硬件和软件平台。HDFS使用Java写成,可在任意安装了JVM的机器上运行。

    NameNode和DataNode

    HDFS是一个Master/Slave架构。一个HDFS集群包含了一个活动的NameNode和若干个DataNode。

  • NameNode负责管理DataNode,处理客户端的读写服务,如执行打开,关闭和重命名等任务(但是实际的数据流并不经过NameNode);处理确定数据块到具体DataNode节点的映射。
  • DataNode负责处理客户端的读写请求,在NameNode的统一调度下,进行数据块的创建,删除和复制。

    HDFS读写流程

  1. 读过程
  • HDFS客户端通过DistributedFileSystem(HDFS中API里面的一个对象)对NameNode发送Read请求,同时将用户信息和文件名等信息发送给NameNode,NameNode返回给客户端FSDataInputStream,以及文件包含的block及其所在的DataNode位置。
  • HDFS客户端通过FSDataInputStream按顺序读取DataNode中的block信息(它会选择负载最低或者离客户端最近的一个DataNode读取block)
  • 读取完毕,将FSDataInputStream关闭。
  1. 写过程
  • HDFS客户端通过DistributedFileSystem对NameNode客户端发送Write请求,同时将文件要保存的位置,文件名,用户信息发送给NameNode,NameNode返回给客户端FSDataOutputStream,以及文件要写入哪些DataNode(选择负载较低的DataNode)
  • 通过FSDataOutputStream进行写操作,在写文件之前就对文件拆分成block,第一个写操作写在负载较低的DataNode上,并将该block复制到其他DataNode上。
  • 所有block副本复制完成反馈给FSDataOutputStream,FSDataOutputStream关闭。
  • 通过DistributedFileSystem更新NameNode中元数据。
    备注:客户端创建文件请求事实上并没有立即发送给NameNode,事实上,在开始阶段HDFS客户端会将文件数据缓存到本地的一个临时文件,应用程序的写操作会透明的重定向到该临时文件,当这个临时文件累积的数据量达到一个block大小时,客户端才会向NameNode发送Write请求。

    文件系统命名空间

    HDFS支持传统的层次化的文件结构。命名空间由目录,文件和块组成,它支持所有与命名空间相关的文件系统的操作,如创建,删除,修改和列出文件和目录。

    数据复制(Data Replication)

    HDFS被设计通过集群存储超大的文件,它将文件存储为大小相等的块,每个块都有副本以容错,应用程序可以指定备份的数量。在HDFS中,同一时间只允许一个writer写入。
    NameNode定时收到来自集群中DataNode的心跳包和块报告(Heartbeat and Blockreport)。HeartBeat用来表明DataNode正常工作,而Blockreport用来指示该DataNode中block列表。

    block副本放置策略

    副本的存放是HDFS可靠性和性能的关键。优化的副本存放策略是HDFS区别于其他分布式文件系统的重要特性。HDFS采用一种称为机架感知(rack-wise)的策略。HDFS实例一般运行在跨越多个机架的集群上,不同机架上的两台机器通讯需要通过交换机。在大多数情况下,副本系数(一个block的副本数量)为3,HDFS的存放策略是将一个副本存放到本地机架的节点上,一个副本放在同一机架的不同节点上,另一个副本存放在不同机架的节点上。这种策略既减少了机架间的数据传输,提高了写操作的效率,也有效防止了整个机架失效时数据的丢失。

    副本选择

    为了降低整体的宽带消耗和读取延迟,HDFS会尽量让应用程序读取离它最近的副本。

    安全模式

  • NameNode启动时,会进入称为安全状态的特殊状态。它首先将映像文件(fsimage)载入内存,并执行编辑日志(edit)中的各项操作。一旦内存中成功建立文件系统元数据映射,则创建一个新的fsimage文件和一个空的edit。
  • 在安全模式中,NameNode对于客户端是只读的,只可以显示目录,文件内容等。在此阶段NameNode会搜集DataNode的报告,当block达到设定的最小副本数时,就认为该block是"安全"的,当一定比例的block达到“安全”的标准时,安全模式结束。当检测到副本数不足的block时,该block将被复制,直到达到最小副本数。系统中block的位置不是NameNode维护的,而是以块列表存储在DataNode中。

    文件系统元数据的持久化

  • Metadata是存储在NameNode上的元数据信息,它存储在磁盘上的文件名为fsimage。并且,有个名为Edits的文件,记录对metadata的操作日志。例如,在HDFS中创建一个文件,NameNode就会在Edits中插入一条记录表示。总体来说,fsimage和edit文件记录了文件系统目录树,文件中包含哪些块,块到DataNode的映射,block存放在哪些DataNode上。
  • NameNode在内存中保存着整个文件系统的命名空间和文件对block的映射(Blockmap)。这个关键的元数据结构设计的很紧凑,当NameNode启动时,它从硬盘中读取Edits和Fsimage,将所有Edits的事务文件作用在内存中的Fsimage上,并将这个新版本的Fsimage从内存中保存到本地磁盘上,然后删除旧的Edits,这个过程称为检查点(checkpoint)。

    通信协议

    所有的HDFS通讯协议建立在TCP/IP协议之上,客户端通过TCP端口连接到NameNode,通过ClientProtocol协议与NameNode交互;DataNode通过DatanodeProtocol与NameNode交互。ClientProtocol和DatanodeProtocol都是基于TCP/IP的远程过程调用(Remote Procedure Call,RPC)。值得注意的是,NameNode不会主动发起RPC,它只会响应来自客户端或者NameNode的RPC。

    数据错误,心跳检测和重新复制(Re-Replication)

    为了确定DataNode正常工作,需要DataNode周期性向NameNode发送心跳信号HeartBeat,NameNode将近期不再发送心跳信号的DataNode标记为脱机(dead),并不会在将新的IO请求发送给它,任何存储在dead datanode的数据不再有效。DataNode的dead有可能使得某些block的副本数量低于设定值,NameNode检测到它们后,就会启动复制操作。

    数据完整性

    HDFS通过校验和(checksum)确保数据的完整。客户端从DataNode获取文件内容后,都会校验获取的数据的checksum和DataNode中存储的checksum是否相同,如果不同,客户端可以选择从别的DataNode中获取该block的副本。

    元数据磁盘损坏

    Fsimage和Edits是HDFS的核心数据,如果这些数据损坏,整个HDFS的实例也就失效了。因此,HDFS可配置成维持多个Fsimage和Edits的副本,任何对Fsimage和Edits的修改都要同步到它们的副本上。这种同步操作会降低HDFS处理命名空间的速度,但是代价是可接受的。当HDFS重启时,它会选取最近的完整的Fsimage和Edits启动。

    快照机制

    HDFS快照是文件系统的只读时间点副本。HDFS快照文件记录block列表和文件大小,并不对datanode中的块复制。利用快照,可以使HDFS在数据损坏时恢复到过去一个已知正确的时间点。

    数据组织

  • 数据块
    当客户端发送write请求后,NameNode返回DataNode标识符和目标数据块给客户端,客户端将文件上传至指定的DataNode中,当文件关闭后,客户端向NameNode报告文件已关闭,NameNode才会将文件创建操作提交到日志中存储,如果NameNode在文件关闭前失效,文件将丢失。
  • 流水线复制策略
    当客户端向第一个DataNode传输数据,第一个DataNode以每段4KB接受数据,并同时向列表中第二个DataNode传输该部分数据,第二个DataNode存储该部分数据后,也同时向第三个DataNode传输该部分数据...因此,DataNode能够流水线式从前一个节点接受数据,并同时转发给下一个节点。

    HDFS缺点

  • 不适合低延迟的数据访问:HDFS设计目标是批处理,而不是用户交互使用,重点在于数据访问的高吞吐量而非数据访问的低延迟。
  • 不适合小文件存储:小文件会占用NameNode的大量内存,文件读取时,其寻道时间反而会超过读取时间。
  • 无法并发写入,文件随即修改:一个文件同时只能有一个writer,而且仅仅支持追加和截断。

HDFS的几点改进的更多相关文章

  1. 01 HDFS 简介

    01.HDFS简介 大纲: hadoop2 介绍 HDFS概述 HDFS读写流程 hadoop2介绍 框架的核心设计是HDFS(存储),mapReduce(分布式计算),YARN(资源管理),为海量的 ...

  2. HDFS简介【全面讲解】

    http://www.cnblogs.com/chinacloud/archive/2010/12/03/1895369.html [一]HDFS简介HDFS的基本概念1.1.数据块(block)HD ...

  3. Hadoop2 和 Hadoop1 区别

    Hadoop2 和 Hadoop1 区别 Namenode NameNode其实是Hadoop的一个目录服务,它包含着整个集群存储的文件的元数据. 早期发行的Hadoop1版本将所有HDFS目录和文件 ...

  4. Hadoop学习笔记—2.不怕故障的海量存储:HDFS基础入门

    一.HDFS出现的背景 随着社会的进步,需要处理数据量越来越多,在一个操作系统管辖的范围存不下了,那么就分配到更多的操作系统管理的磁盘中,但是却不方便管理和维护—>因此,迫切需要一种系统来管理多 ...

  5. Hadoop学习笔记—21.Hadoop2的改进内容简介

    Hadoop2相比较于Hadoop1.x来说,HDFS的架构与MapReduce的都有较大的变化,且速度上和可用性上都有了很大的提高,Hadoop2中有两个重要的变更: (1)HDFS的NameNod ...

  6. Spark Streaming容错的改进和零数据丢失

    本文来自Spark Streaming项目带头人 Tathagata Das的博客文章,他现在就职于Databricks公司.过去曾在UC Berkeley的AMPLab实验室进行大数据和Spark  ...

  7. 基于Flume的美团日志收集系统(二)改进和优化

    在<基于Flume的美团日志收集系统(一)架构和设计>中,我们详述了基于Flume的美团日志收集系统的架构设计,以及为什么做这样的设计.在本节中,我们将会讲述在实际部署和使用过程中遇到的问 ...

  8. hdfs工作原理

    一.NameNode和DataNode (1)NameNode NameNode的作用是管理文件目录结构,是管理数据节点的.NameNode维护两套数据:一套是文件目录与数据块之间的关系,另一套是数据 ...

  9. 2、分布式文件系统---HDFS

    1.HDFS设计前提与目标 (1)硬件错误是常态而不是异常.  错误检测并快速自动恢复是HDFS最核心设计目标 (2)流式数据访问.运行在HDFS上的应用主要是以流式数据读取为主,做批量处理而不是用户 ...

随机推荐

  1. Oracle数据库sqlplus与plsqldev解决乱码

    (出现乱码 解决方法留存) 问题描述 : 在用eclipse使用jdbc插入中文数据的时,数据用plsqldev查询时,正常显示中文,但是用sqlplus查询时,为中文乱码,当用plsqldev直接插 ...

  2. sgu209:Areas(计算几何)

    意甲冠军: 给一些直.这架飞机被分成了很多这些线性块.每个块的需求面积封闭曲线图. 分析: ①我们应要求交点22的直线: ②每行上的交点的重排序,借此来离散一整行(正反两条边): ③对于连向一个点的几 ...

  3. CUDA中block和thread的合理划分配置

    CUDA并行编程的基本思路是把一个很大的任务划分成N个简单重复的操作,创建N个线程分别执行执行,每个网格(Grid)可以最多创建65535个线程块,每个线程块(Block)一般最多可以创建512个并行 ...

  4. jQuery多库共存处理$.noConflict()

    如果我们需要同时使用jQuery和其他JavaScript库,我们可以使用 $.noConflict()把$的控制权交给其他库.旧引用的$ 被保存在jQuery的初始化; noConflict() 简 ...

  5. node lesson2

    var express = require('express'); var utility = require('utility'); var app = express(); app.get('/' ...

  6. 10.24的注意事项——解决linux_jni编译错误的问题

    公司以opus开源库.因此,我们遇到了一些问题. 我将新下载的opus1.1替换掉老版本号之后,单独编译opus没问题.但是编译相关的文件就会报错. 错误信息例如以下: g++ -Wall -fPIC ...

  7. java学习笔记(7)——I/O流

    一.File类 File(File parent, String child); File(Stirng filename); ------------------------------------ ...

  8. uwp - ContentDialog - 自定义仿iphone提示框,提示框美化

    原文:uwp - ContentDialog - 自定义仿iphone提示框,提示框美化 为了实现我想要的效果花费了我很长时间,唉,当初英语不好好学,翻官网翻了半天才找到,分享给刚入门的新手. 首先看 ...

  9. VC除零异常(错误)捕获

    // testFinally.cpp : Defines the entry point for the console application. // #include "stdafx.h ...

  10. WPF中画虚线

    原文:WPF中画虚线 在WPF中,画线的方法十分简单,只要声明一个Line然后添加到指定的位置就可以了,但Line并不仅仅只能画一条直线,还可以对直线进行修饰. 1.Line.StrokeDashAr ...