HDFS1.0
1 什么是HDFS?
HDFS的全称是:Hadoop DistributeFiles System,分布式文件系统。
在整个Hadoop技术体系中,HDFS提供了数据分布式存储的底层技术支持。
HDFS 由三个组件构成:NameNode(NN)、DataNode(DN)、SecondaryNameNode(SNN)
2 系统架构
HDFS 是一个主/从(Master/Slave)体系架构,由于分布式存储的性质,集群拥有两类节点 NameNode 和 DataNode。
(1) Client:客户端,是应用程序可通过该模块与 NameNode 和DataNode 进行交互,进行文件的读写操作;
(2) NameNode:主节点、名字节点、Master(进程),一个hadoop集群只有一个,管理存储和检索多个 DataNode 的实际数据所需的所有元数据;
(3) DataNode:从节点、数据节点、Worker(进程),一个hadoop集群可以有多个,是文件系统中真正存储数据的地方,在NameNode 统一调度下进行数据块的创建、删除和复制;
(4) SecondaryNameNode不是第二主节点,是助手节点,也可以理解为镜像文件,或者是数据备份;
(5) NameNode与DataNode的联系
- Heartbeat:NameNode与DataNode之间存在心跳连接,DataNode每隔一段一时间就主动向NameNode汇报消息
- Balance:当一个datanode挂了,为了达到平衡block,内部数据会被平均分配到其他datanode上
(6) 为什么1.0里只有一个NameNode?
因为hadoop1.0是在zookeeper诞生之前,没有满足高可用的工具。
3 关于NameNode
(1) 管理着文件系统命名空间:维护着文件系统树及树中的所有文件和目录
(2) 存储元数据:NameNode保存元信息的种类有:
- 文件名目录名及它们之间的层级关系
- 文件目录的所有者及其权限
- 每个文件块的名及文件有哪些块组成
(3) 元数据保存在内存中
NameNode元信息并不包含每个块的位置信息(每个块的信息存储在block中,block存储在datanode中)
(4) 保存文件,block,datanode之间的映射关系,有2种映射关系数据
- 文件名->blockid list列表
- block数据块->datanode节点地址(数据是通过DN->NN发送心跳组织起来的)
(5) 元信息持久化
在NameNode中存放元信息的文件是 fsimage。在系统运行期间所有对元信息的操作都保存在内存中并被持久化到另一个文件edits中。并且edits文件和fsimage文件会被SecondaryNameNode周期性的合并。
(6) 运行NameNode会占用大量内存和I/O资源,一般NameNode不会存储用户数据或执行MapReduce任务。
4 Hadoop更倾向存储大文件原因:
一般来说,一条元信息记录会占用200byte内存空间。假设块大小为64MB,备份数量是3,那么一个1GB大小的文件将占用16*3=48个文件块。如果现在有1000个1MB大小的文件,则会占用1000*3=3000个文件块(多个文件不能放到一个块中)。我们可以发现,如果文件越小,存储同等大小文件所需要的元信息就越多,所以Hadoop更喜欢大文件。
5 关于DataNode
(1) 负责存储数据块,负责为系统客户端提供数据块的读写服务;
(2) 根据NameNode的指示进行创建、删除和复制等操作;
(3) 心跳机制,定期向NameNode报告文件块列表信息;
(4) DataNode之间进行通信,块的副本处理。
6 关于block
(1) 数据块,磁盘读写的基本单位;
(2) Hadoop1.0默认数据块大小64MB,Hadoop2.0默认是128M;
(3) 磁盘块一般为512B;
(4) 块增大可以减少寻址时间,降低寻址时间/文件传输时间,若寻址时间为10ms,磁盘传输速率为100MB/s,那么该比例仅为1%;
(5) 数据块过大也不好,因为一个MapReduce通常以一个块作为输入,块过大会导致整体任务数量过小,降低作业处理速度。
7 关于SecondaryNameNode
(1) 两个文件:
- fsimage:它是在NameNode启动时对整个文件系统的快照(镜像文件)
- edit logs:它是在NameNode启动后,对文件系统的改动序列(存在磁盘中)
(2) 两个文件状态:数据是不断增加的,而NameNode是很少重启的,所以edit log是不断增大的,而fsimage是比较旧的,永远也赶不上edit log文件,所以需要借助别的东西来更新fsimage文件
解析:NameNode重启那一瞬间,内存数据是空白的,那么NameNod在重启的时候就需要把还原出内存的元数据状态,这些状态数据是来自fsimage的;
NameNode重启之后会先读fsimage,再读eidt,两者合并才能得到完整数据,这时edit log数据会比fsimage大很多,合并需要很长时间,这时就需要一个机制,尽可能想办法怎样减小你的eidt,并且让fsimage这个文件能够尽可能的保持最新的数据状态,这样的话NameNode重启的话就不需要受合并的影响了,它就可以从fsimage直接读数据然后启动。所以,这个事情就由SecondNameNode来干的。
(3) SecondNameNode作用
- 用来保存HDFS的元数据信息,比如命名空间信息、块信息等,由于这些信息是在内存的,SecondNameNode是为了考虑持久化到磁盘;
- 定时到NameNode去获取edit logs,并更新到fsimage[Secondary NameNode自己的fsimage];
- 一旦它有了新的fsimage文件,它将其拷贝回NameNode中。(这时有两个数据一样的fsimage);
- NameNode在下次重启时会使用这个新的fsimage文件,从而减少重启的时间;
- Secondary NameNode所做的不过是在文件系统中设置一个检查点来帮助NameNode更好的工作。它不是要取代掉NameNode也不是NameNode的备份。
(4) SecondNamenode存在意义?
- 备份:是为了数据不丢失
- 数据恢复:是数据找回
(5) NameNode把每一次改动都会存在editlog中,但是整个事件是由谁来触发的?是由DataNode触发的
(6) 元数据持久化的过程(SNN来完成):
内存->editlog(磁盘)-> fsimage
(7) fsimage多久加载一次:重启才会加载。
8 Client访问数据流程
Client访问数据流程:(先简单梳理)
Client先是访问NameNode,从NameNode中得知文件的block,从block中得知数据存储的path,也就是数据存储在哪个datanode上,之后client就直接到该datanode上读取数据。
namenode:
1、文件名---》block
2、block---》datanode
datanode:
block---》path
9 防止单点故障
两个方案:
(1) NFS:将hadoop元数据写入到本地文件系统的同时再实时同步到一个远程挂载的网络文件系统;
(2) secondary NameNode:它的作用是与NameNode进行交互,定期通过编辑日志文件合并命名空间镜像,当NameNode发生故障时它会通过自己合并的命名空间镜像副本来恢复。需要注意的是secondaryNameNode保存的状态总是滞后于NameNode,所以这种方式难免会导致丢失部分数据。
10 副本机制
为了系统容错,文件系统会对所有数据块进行副本复制多份,Hadoop 是默认 3 副本管理:
第一个副本,在客户端相同的节点(如果客户端是集群外的一台机器,就随机算节点,但是系统会避免挑选太满或者太忙的节点);
第二个副本,放在不同机架(随机选择)的节点;
第三个副本,放在与第二个副本同机架但是不同节点上;
所有有关块复制的决策统一由NameNode负责,NameNode 会周期性地接受集群中数据节点 DataNode 的心跳和块报告。一个心跳的到达表示这个数据节点是正常的。一个块报告包括该数据节点上所有块的列表。
特殊情况:比如我目前的集群环境(1个master、2个slaves),此时并不是3个副本而是2个,因为datanode数量就只有2个。
11 数据完整性校验
不希望存储和处理数据时丢失或损失数据,HDFS会对写入的数据计算检验和,并在读取数据时验证校验和。
(1) 校验和(传输检测---csc32)
需要校验两次:
- a) client向DataNode写数据的时候,要针对所写的数据每个检查单位(512字节)创建一个单独的校验和,将该校验码和数据本身一起传送给DataNode;
- b) DataNode接收的时候,也要创建校验和进行校验,新生成的校验和原始的校验和不完全匹配,那么数据就会被认为是被损坏的。
(2) 数据块检测程序DataBlockScanner(本地检测)
在DataNode节点上开启一个后台线程,来定期验证存储在它上面的所有块,这个是防止物理介质出现损减情况而造成的数据损坏。
12 容错-可靠性措施
HDFS有一套可靠性保证(保证数据完整性)
(1) 心跳:DN-NN
(2) 副本:通过数据冗余保证高可用
(3) 数据完整性:crc32
(4) SNN,保证元数据避免一定程度上不丢失(日记文件、镜像文件)
(5) 空间回收:回收站(.Trash目录,在有效时间内,可以把误删数据恢复回来)
(6) 快照
(7) 报告:快报告 ./hdfs fsck /passwd -files -blocks -locations
13 HDFS特点
HDFS 专为解决大数据存储问题而产生的,其具备了以下特点:
(1) HDFS 文件系统可存储超大文件
- 每个磁盘都有默认的数据块大小,这是磁盘在对数据进行读和写时要求的最小单位,文件系统是要构建于磁盘上的,文件系统的也有块的逻辑概念,通常是磁盘块的数倍;
- 通常文件系统为几千个字节,而磁盘块一般为 512 个字节;
- HDFS 是一种文件系统,自身也有块(block)的概念,其文件块要比普通单一磁盘上文件系统大的多,默认是 64MB;
- HDFS 上的块之所以设计的如此之大,其目的是为了最小化寻址开销;
- HDFS 文件的大小可以大于网络中任意一个磁盘的容量,文件的所有块并不需要存储在一个磁盘上,因此可以利用集群上任意一个磁盘进行存储,由于具备这种分式存储的逻辑,所以可以存储超大的文件,通常 G、T、P 级别。
(2) 一次写入,多次读取(write-once-read-many)
一个文件经过创建、写入和关闭之后就不需要改变,这个假设简化了数据一致性的问题,同时提高数据访问的吞吐量。保证系统性能和稳定。
(3) 运行在普通廉价的机器上
Hadoop 的设计对硬件要求低,无需昂贵的高可用性机器上,因为在HDFS设计中充分考虑到了数据的可靠性、安全性和高可用性。
14 不适用于HDFS的场景
(1) 低延迟
HDFS 不适用于实时查询这种对延迟要求高的场景,例如:股票实盘。往往应对低延迟数据访问场景需要通过数据库访问索引的方案来解决,Hadoop 生态圈中的Hbase 具有这种随机读、低延迟等特点。
(2) 大量小文件
对于 Hadoop 系统,小文件通常定义为远小于 HDFS 的 block size(默认 64MB)的文件,由于每个文件都会产生各自的 MetaData 元数据,Hadoop 通过 Namenode来存储这些信息,若小文件过多,容易导致 Namenode 存储出现瓶颈。
(3) 多用户更新
为了保证并发性,HDFS 需要一次写入多次读取,目前不支持多用户写入,若要修改,也是通过追加的方式添加到文件的末尾处,出现太多文件需要更新的情况Hadoop是不支持的。针对有多人写入数据的场景,可以考虑采用 Hbase 的方案。
(4) 结构化数据
HDFS 适合存储半结构化和非结构化数据,若有严格的结构化数据存储场景,也可以考虑采用 Hbase 的方案。
(5) 数据量并不大
通常 Hadoop 适用于 TB、PB 数据,若待处理的数据只有几十 GB 的话,不建议使用 Hadoop,因为没有任何好处。
15 HDFS写流程
1)写流程
客户端调用 create()来创建文件,Distributed File System 用 RPC 调用 NameNode节点,在文件系统的命名空间中创建一个新的文件。NameNode 节点首先确定文件原来不存在,并且客户端有创建文件的权限,然后创建新文件。Distributed File System 返回 FSDOutputStream,客户端用于写数据。客户端开始写入数据,FSDOutputStream 将数据分成块,写入 Data Queue。Data Queue 由 DataStreamer 读取,并通知 NameNode 节点分配数据节点,用来存储数据块(每块默认复制 3块)。分配的数据节点放在一个 Pipeline 里。Data Streamer 将数据块写入 Pipeline 中的第一个数据节点。第一个数据节点将数据块发送给第二个数据节点。第二个数据节点将数据发送给第三个数据节点。DFSOutputStream 为发出去的数据块保存了 Ack Queue,等待 Pipeline 中的数据节点告知数据已经写入成功。写入一个datanode都说明写入数据成功,内部datanode会数据冗余。
Client写数据流程总结:
(1) client通过java类DistibutedFileSystem向NameNode发送creat请求)
(2) NameNode借助DistributedFileSystem来返回一个对象类FSDataOutputStream
(3) Client通过FSDataOutputStream往datanode里写数据
(4) OutputStream会把写入的文件切分成一个一个的数据块,这时候还是在client上的
(5) Data Stream通过一个分发机制分别把数据块写入到datanode中
(6) 第一个datanode写成功后,就会返回一个ack packet包给FSDataOutputStream
(7) 内部副本数据冗余
16 HDFS读取流程
首先 Client 通过 File System 的 Open 函数打开文件,Distributed File System 用 RPC调用 NameNode 节点,得到文件的数据块信息。对于每一个数据块,NameNode 节点返回保存数据块的数据节点的地址。Distributed File System 返回 FSDataInputStream 给客户端,用来读取数据。客户端调用 stream的 read()函数开始读取数据。FSDInputStream连接保存此文件第一个数据块的最近的数据节点。DataNode 从数据节点读到客户端(client),当此数据块读取完毕时,FSDInputStream 关闭和此数据节点的连接,然后连接此文件下一个数据块的最近的数据节点。当客户端读取完毕数据的时候,调用FSDataInputStream 的 close 函数。在读取数据的过程中,如果客户端在与数据节点通信出现错误,则尝试连接包含此数据块的下一个数据节点。失败的数据节点将被记录,以后不再连接。
Clinet读流程总结:
(1) 客户端发送请求,调用DistributedFileSystemAPI的open方法发送请求到Namenode,获得block的位置信息,因为真正的block是存在Datanode节点上的,而namenode里存放了block位置信息的元数据。
(2) Namenode返回所有block的位置信息,并将这些信息返回给客户端。
(3) 客户端拿到block的位置信息后调用FSDataInputStreamAPI的read方法并行的读取block信息,图中4和5流程是并发的,block默认有3个副本,所以每一个block只需要从一个副本读取就可以。
(4) datanode返回给客户端。
17 同步和异步
同步:保证数据一致性,问题慢
异步:速度快,不能保证数据强一致
同步是指:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式。
异步是指:发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式。
同步就是你叫我去吃饭,我听到了就和你去吃饭;如果没有听到,你就不停的叫,直到我告诉你听到了,才一起去吃饭。
异步就是你叫我,然后自己去吃饭,我得到消息后可能立即走,也可能等到下班才去吃饭。
所以,要我请你吃饭就用同步的方法,要请我吃饭就用异步的方法,这样你可以省钱。
18 HDFS&MapReduce本地模式
本地模式:保证计算框架和任务调度管理部署在同一台机器上,体现本地化原则,尽量减少数据移动开销。
mapreduce有map阶段和reduce阶段,本地化原则针对map阶段,因为reduce阶段有远程partition,不能保证是同一机器。
HDFS2.0
HDFS2.0相对HDFS1.0有几个新特性
1 NameNode HA
1.1 高可用方案
(1) 在Hadoop1.0中NameNode在整个HDFS中只有一个,存在单点故障风险,
一旦NameNode挂掉,整个集群无法使用,虽然有SNN,但还是不可靠;在Hadoop2.0中,就针对NameNode提供了一个高可用方案。
1.0简图
2.0简图
(2) HDFS的高可用性将通过在同一个集群中运行两个NameNode (active NameNode & standby NameNode)来解决;
(3) 在任何时间,只有一台机器处于Active状态;另一台机器是处于Standby状态;
(4) Active NN负责集群中所有客户端的操作;
(5) Standby NN主要用于备用,它主要维持足够的状态,如果必要,可以提供快速的故障恢复。
1.2 高可用架构
(1) 不管2.0还是1.0,底层都是datanode,2.0有两个NN,一个是Active状态,一个是Standby状态,datanode中的block一旦发生了修过,就同时通过心跳的方式通知两个NN,NN中的元数据就随即更新。
(2) 为了保证两个NN数据一致性,必须满足两个条件:
- 数据同步:要保证数据同步,DataNode要对两个NN同时发送心跳
- 命名空间同步(namespace/文件目录树),有以下两种方法:
• 借助NFS文件系统,network File system
• Hadoop自身提供了一个服务,叫做QJM
NFS:属于操作系统支持的配置---》镜像文件和编制日记文件
QJM:属于应用软件级别的配置----》JN
(3) DataNode要对两个NN同时发送心跳,为了保证数据一致性,为什么还需要JN?
原因:两者同步的数据不同,之前说过Namenode中有两种不同类型的映射数据
JN对应的映射关系:文件名->block
NN对应的映射关系:block->DN
总结以上:
完成数据一致性要保证这两个之间数据完全一致就需要两个一致:一个是数据(通过数据管理部保证),一个是命名空间(通过JN(QJM起来的进程)来保证的),一个集群中,最少要运行3个JN系统,使得系统有一定的容错能力
(4) 命名空间保持同步
当Active NameNode的命名空间发生变化的时候,它会把这个变化通知所有JN,有的JN收到信息,有的JN是没有收到信息的,如果大部分JN进程接到信息,就认为这个事件是可信的,如果少数的JN接到信息,就认为这个信息是错误的,是屏蔽的,对于可信的信息,standby Namenode才会去同步过来,通过JN这种方式,才能保证Standby Namenode和Active Namenode之间有效信息的一个同步。
(5) NN与FailoverController、ZK的联系
a. FailoverController进程(ZKFC)主要是用来协助故障转移用的,是部署在NN上的,对NN进行健康状态检查;
b. ZK是用来用来完成故障转移的,ZK不会与NN建立直接关系,ZKFC是ZK集群的客户端,通过ZKFC用来监控NN的状态信息,ZKFC在ZK上创建节点(删除节点、临时节点、顺序节点等),与NN保持心跳;
c. 每一个NN就需要一个ZKFC,Active NN对应Active ZKFC,Standby NN对应Standby ZKFC;
(6) 故障转移
a. 什么叫故障转移:就是说当active突然挂掉了,standby立马就把状态变成active状态,就是起到这么一个作用。
b. ZKFC对自己负责的NN进行健康检查,ZKFC是和NN部署在同节点上的,是时时健康检查的,ZKFC与zookeeper通过心跳检测连接,ZKFC会在ZK上注册一个临时节点(要监控,必须要临时节点),目的用于监控NN,ZK通过一些监控的命令不断的去检查NN进程,如果NN失效,相应的临时节点消失,接下来的动作类似于选主(或者申请锁)的流程。
c. 如果当本地的namenode是健康的话,并且当前namenode也是刚好是active状况,那么ZKFC就会持有一把锁,这把锁就是一个临时节点,当本地的namenode失效了,这个节点也就失效了。
d. 还有另外一种情况,NN是健康的,但是,不是Active状态而是Standby状态,这个时间ZKFC进程就会去帮我检查,ZZ中有没有这个临时节点,如果没有的话,就去创建一个,如果创建不了,那么说明当前集群里面有一个NN是处于active状态。
e. ZKFC进程,相当于对zookerper服务和NN服务进行了一定的隔离。
f. 以上就是ZK通过ZKFC进程来完全了整体的一个故障迁移。
(7) 为什么只能有一个Active Namenode
对于HA集群来说,同一时刻一定要确保只有一个namenode的状态active,如果有两个active的话,这两个active会互相争夺信息,会出现丢数据,会导致集群不可靠,发现错误的结果。
(8) 关于JN
JN目的:让StandbyNN和ActiveNN保持数据同步(文件名->block)
JN通常有两种选择:一种是NFS(需要额外的磁盘空间),另外一种QJM(不需要空间)
JN通常要配置成奇数个(2n+1),如果n+1个数据是一致的,数据就确定下来,也就是说能最大允许出错的JN个数是n个。
(9) 关于QJM
QJM:最低法定人数管理机制,原理:用2n+1台JN机器存储editlog,每次写数据操作属于大多数(>=n+1)的时候,返回成功(认为当前写成功),保证高可用
QJM本质也是一个小集群,好处:
a.不需要空间
b.无单点问题
c.不会因为个别机器延迟,影响整体性能
d.系统配置
(10)为什么用QJM来实现HA?
第一:不需要配置额外的共享存储(相比NFS来说的)
第二:消除单点问题,
第三:可配置,使得系统更加鲁棒
第四:JN不会因为其中一台的延迟而影响整体的延迟,也不会因为JN的数量增多而影响------》为什么呢?
因为avtive namenode一旦里面命名空间发生数据变化,它会把这个数据同步的写到JN上,它是并行发送的状态,不管是部署少也好,多也好,它都是并行发出的
(11) 节点分配
a. NN和JN通常不在一个机器上
b. FC和NN在同一台机器
c. RM(Yarn中的资源管理器,相当于1.0中Jobtracker部分功能)和NN在同一台机器
d. NM(Yarn中从节点)和DN在同一个机器上
e. 通常工业界,Zookeeper是单独维护的独立集群
=================================
HA集群:
【192.168.1.1】master1:NN,ZKFC,RM
【192.168.1.2】master2:NN,ZKFC,RM
【192.168.1.3】slave1:DN,NM,ZK,JN
【192.168.1.4】slave2:DN,NM,ZK,JN
【192.168.1.5】slave3:DN,NM
【192.168.1.6】slave4:DN,NM,ZK,JN
2 联邦
(1) 1.0中除了单节点故障还有一个问题,内存空间有限,因为只有一个Namenode,它保持了整个HDFS所有的元数据,创建一个文件,就必然在内存里面占用一定的空间,影响整个HDFS的扩展,所以为什么之前说HDFS不利于过多的保存小文件,因为也就是在这里。
(2) Federation
联邦,主要是针对namenode来说的,所以也叫namenode Federation,是有多个namenode条件下才建立起来的一个机制,有多个namenode就意味着有多套的命名空间(namespace),一个namenode负责一个命名空间,一个命名空间对应一个block pool(是同一个namespace下的所有block集合,就是一个namenode只对应自己管理的文件目录,目录里面就是文件数据,也就是block)
(3) 联邦架构
Federation意味着集群里面有多个block pool,上图中,底层是一个datanode存储,上层是命名空间,每一个命名空间都维护着自己的文件目录树,文件目录树下面都存在着一些文件和数据,这些数据都是由block组成的,block都是由datanode通过心跳数据同步更新过来的。
(4) 数据同步
datanode会先把数据存到各自各自pool里,也就是缓冲区里,然后由namenode管理起来,不管是1.0也好,2.0也好,在整个集群里面,所有的文件,就是整体空间的全集,把所有pool里的信息加起来就是一个整体概念,那这个时候呢,因为要组成一个联邦,每个namenode要管理自己的空间,要把每一个pool分开,每一个namenode来维护自己的一个pool,每一个节点都是这样的,好比这个集群里面有三个namenode,每个namenode都要去维护自己的pool,维护自己的那一套缓存,而且两两之间的内部缓存信息都是不一样的,因为文件内部的逻辑概念不一样。
所以这就是联邦解决内部空间不足的一个解决方案。
(5) 联邦优势:
a. 命名空间可以横向扩展,使得Hadoop集群的规模可以达到上万台
减轻单一NN压力,将一部分文件转移到其他NN上管理,如果集群中某一个目录比较大,建议用单独的NN维护起来,命名空间精简,横向扩展,真正突破单台NN的限制
b. 性能提升
就是说当namenode持有的数据达到一个非常大规模量级时候,比如说集群里面有十亿个文件,这个时候呢,namenode处理效率可以会受到一点影响,但是呢,它可以会容易陷入到一个比较繁难的状态,而且整个集群会受限于单个namenode来处理的这个效率,从而影响整个集群的吞吐量,这个时候呢,你如果用联邦这种方式,显然可以提高性能,原来一个namenode它承载了外部所有的请求,现在不是了,现在是把这个请求给分流了,性能也会提升的
c. 资源的隔离(跟具体应用有关)
通过多个命名空间,可以将关键文件移动到不同的namenode上,那些相对不关键的数据修改,一旦发生了问题,至少不影响关键数据的破坏就相当于每一个namenode维护的空间可以按部门去分,也可以看重要程度去分
每个NN共享所有的DN数据,一个命名空间对应一个块池(是同一个命名空间下的所有块集合)
(6) 联邦的本质:将一部分文件迁移到其他NN进行管理,让元数据管理(NN)和存储(DN)进行解耦(分开),但是真实的数据存储还是共享的。
3 HDFS快照
(1) 概念:在某一时刻给当前的文件系统照一个照片,这一照片就是当前时刻,整个集群的数据状态
(2) 作用:主要用来做数据备份、灾备、快速恢复
(3) 本质:只记录了block列表和文件大小,但不会出现数据的复制
(4) 快照也是数据,也会占空间,但不是占特别大的空间(有些可以忽略不计)
(5) 假设:一个集群,如果全部备份,可能还需要另外一个集群,操作很麻烦,成本还特高,快照的创建时瞬间完成的,高效!
(6) 并不会影响HDFS 的正常操作:修改会按照时间的反序记录,这样可以直接读取到最新的数据。
(7) 快照数据是当前数据减去修改的部分计算出来的。
(8) 快照会存储在snapshottable的目录下。
(9) HDFS快照是对目录进行设定,是某个目录的某一个时刻的镜像
(10)对于一个snapshottable文件夹,“.snapshot”被用于进入他的快照 /foo 是一个snapshottable目录,/foo/bar是一个/foo下面的文件目录,/foo有一个快s0,那么路径就是:/foo/.snapshot/s0/bar
(11)操作命令
• hdfs dfsadmin-allowSnapshot /user/spark
• hdfs dfs-createSnapshot /user/spark s0
• hdfs dfs-renameSnapshot /user/spark s0 s_init
• hdfs dfs-deleteSnapshot /user/spark s_init
• hdfsdfsadmin -disallowSnapshot /user/spark
(12)举例
三个目录是包含的关系,A最上层,B在A中,C在B中,当B做了个快照,这时C还能做快照吗?不能,因为B做了快照,它下面的所有子目录都包含了;这时候A也是不能做快照的,子目录做了快照,父目录也是不允许的。
4 HDFS缓存
HDFS1.0中也讲过类似缓存的情况,就是当客户端去读这个DN的时候,如果这个数据被频繁读取,在操作系统级别会有一个预读取,这个数据读了,会把未来的数据会提前加载到一个系统级别缓存里面去,这样会加快数据访问。
把HDFS1.0中的缓存叫做是依赖于操作系统本身的缓存机制。这种缓存机制是不能被系统管理员或者中央节点所管理的,这些缓存都是在datanode上的,由datanode自身操作系统来决定的,那对于想在namenode或者master控制整个路径缓存的话是不行的。2.0针对这种情况做了升级。
在HDFS2.0中,叫做是集中式缓存(不局限在具体的机器cpu和操作系统层面上的优化),即是由Namenode集中式管理的,可以提高对于缓存内存的可性。
集中式缓存作用或者优点:
(1)允许用户指定要缓存的HDFS路径
自由控制缓存,提高缓存内存的可控性。
(2)明确的锁定可以阻止频繁使用的数据被从内存中清除
对于频繁读取的数据,一旦明确了存储路径,就会告知系统,这个数据是要频繁读取的,让内存清缓存的机制不清除这些数据。
(3)集中化缓存管理对于重复访问的文件很有用
(4)可以换成目录或文件,但目录是非递归的
集中式缓存只能对文件和目录操作,目录是非递归的,只能缓存当前目录
就比如下图,对目录B做了缓存,那C是不受影响的,也没有缓存C中的数据,C还可以再做缓存
非递归这是集中式缓存的特点,但是不能说是优点
Namenode下的内容已经是在内存中的了,没必要再做缓存了
主要问题是缓存数据还是缓存映射关系?
是缓存数据的,加快读取速度
5 HDFS ACL
(1) Hadoop从2.4.0开始支持ACL
(2) 目前HDFS的权限控制与Linux一致,包括用户、用户组、其他用户组三类权限,这种方式有很大局限性
(3) 首先参数上要开启基本权限和访问控制列表功能
dfs.permissions.enabled
dfs.namenode.acls.enabled
(4) 常用命令:
hadoop fs-getfacl /input/acl
hdfs dfs-setfacl -m user:mapred:r-- /input/acl
hdfs dfs-setfacl -x user:mapred /input/acl