HDFS(一)|学习笔记

简介: 快速学习 HDFS(一)

开发者学堂课程【高校精品课-上海交通大学-企业级应用体系架构: HDFS】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/75/detail/15845


HDFS(一)

 

内容介绍

一、HDFS

二、测试

 

一、HDFS

1.分布式文件系统

分布式文件系统,以 Hadoop 中的 HDFS 为例讲解

 image.png

其实前面在讲解 Hadoop 时讲 map reduce 时大家已经看到过了,将目录指定让 map reduce 进行处理就用到了 HDFS,Hadoop 的分布式文件系统用来存储那些非常大的文件,尺寸比较大,单个文件可能就有若干个 g 或若干个 t 这么大,例如下载高清电影,一个电影可能就好几十个 g,这样单个大的文件应该如何存储,以及大的文件在文件系统中存储时应该如何进行管理,同时也支持流式的数据访问,数据可以像上节课讲的 storm 方式以流的方式进入系统,一旦被写入就不会再改变值,可以被多次的读取,整个 HDFS 系统不是要弄一个超级计算机只有大量的硬盘资源存储系统里面需要存储的文件,而是要找一堆廉价的机器,整个也是 Hadoop 的思想,用一堆廉价的机器堆出一个系统,廉价意味着可能容易出错,可能会出现各种各样的问题,这些问题出现之后不能向用户暴露出来,在这种廉价的技术上还要提供很高的可靠性,要提高高可靠性给用户,虽然廉价,这些机器都可能坏,但是无论怎么坏,数据都不会丢失,不会发生无法访问的情况,如何做到这一步,其实再加冗余就可以了,所有的东西都有冗余就不怕坏了,冗余的数量越多可靠性越高,相当于拿空间换可靠性,因为强调用的都是廉价机器,要靠冗余实现这一点提高可靠性,这个想法与拿一个超级计算机做文件系统是背道而驰的,它的想法是如果有一个超级计算机可靠性未必能提高,不如用一堆廉价的机器堆出来,其中要有一点空间,多用一些数量但是总的代价会比较小,比使用超级计算机代价小,HDFS 是用一堆廉价的机器堆一个分布式的文件系统,所以可以想一想,是一个分布式的文件系统,如果在存储大量的数据,不适于以下的情况:第一个是希望很快的读取数据,这种情况下在 HDFS 中显然效率不是特别高,因为他的数据分布在一个集群中,当在访问数据时,如果特别强调延时,低延时,想要快速的定位到数据访问就不太适合,因为在 HDFS 中 会有原数据节点,在上面找到数据存储的数据节点在哪里,就是 name Note 像文件分区表一样,在 name node 上找到数据到底存储在哪一个数据节点上,然后在此数据节点上进行读取,还会有一个问题是在写数据时有冗余,假如系统中有三个冗余,任何一块数据进入以后都会存三块,数据的写入操作就会比较费时,因为逻辑是三块全部写入,无论是新插入还是做更新,三块全部操作完才算是操作结束,从这里可以看到访问效率肯定不如拿一台超级计算机存储所有的文件高,会有一定的开销,首先是分布式的,要查找 name node 的节点,再到数据节点查找数据,第二个是写入要将三个副本都写入成功的情况下才能完成,所以对于低延迟来讲显得有点慢,第三个是面向大文件的,如果存储大量的小文件就有问题了,因为文件在存储完以后,像文件分区表一样的东西存储在 name node 上,name node 上持有文件系统的原数据,其中会有哪一个文件的第一个 block 存储在什么位置,会像文件分区表一棵树一样,如果在操作系统中学习了文件分区是一样的,这个数据会 Node 到内存里,很显然,如果文件的条目非常多,大量的全是小文件,在内存中占用的空间就会非常大,效率就不高了,例如有1t的硬盘,如果是1G 文件,每个文件只有1k,内存至少要有1G 这么大,如果有一 K 个文件,每个文件有1G 的大小,这时候可以看到文件分区表中的内容比较少,主要记录1000个文件的第一个 block 在哪里起,在文件分析表可以在后续的指针指向下一个 block,所以如果文件数量很少,对于同样存储量讲,文件数量少,占用内存少效率就能提高,如果文件数量非常多,而且全是小文件,尽管也是1tb的数据,但是查找速度会变得非常慢,因为占用的内存比较多,树也会比较大,在一棵树里面查找树的深度就决定了查找的速度,数量较多的情况下,数的深度一定会比较高,所以效率就会下降,这种情况不适合,如果数据写进来以后,可能会有并发的写,要对文件做出各种各样的修改,这样效率也不高,还是从刚才的角度讲,再有三个副本的情况下,要想写入同步是串性,写入第一块以后去写入第二块然后写第三块,只有三块都完成才能够结束,这种写入完成以后还要对 name node 去文件分区表对原数据进行修改,所以当有多个 writer 向 HDFS 写多个文件的时候,很显然大家都要去操作文件分区表,都要经过多个副本同步之后将文件分区表进行更新效率非常低,所以在 HDFS 中基本上优化下来用 writer做单个的写操作比较好,多个 writer 同时写是不支持的,在文件中进行修改如果一个文件被切成了很多块,假设一块定义为1G,实际上没有这么大,这里只是为了举例,一个文件有4G,在存储时分为4块,每块1G,可以想象到,如果文件内容发生变化,很显然,在后面追加是比较方便的,后面增加一块链上去,其他的地方都不动,但是如果第二块里面有一块数据有改写,想要插入一些东西,这个操作就很麻烦,如果将新插入的数据填进来,第二个块里面就多了一些内容,这个内容存不下要放到下一块,下一块儿多出的内容,再放到下一块儿,效率就很差,允许写,但是写的数据只能发生在文件末尾,如果想在文件的任意一个便宜量位置,例如中间位置想要插入数据,是不允许的,不光是插入,删除会形成漏洞,更新也无法保证更新完成之后更新的字节与原来的字节所占内存一样,所以压根不允许在中间插入,只能在末尾插入,所以在这些场景下其实并不合适,反过来讲,只要避开这些场景,基本上就可以使用 HDFS了,对读和写的性能要求不是那么的高,其实也不慢,只是与实质性要求非常高的低延迟应用相比慢一点,也有很多大尺寸的文件要存储,而不是有很多小尺寸的文件,在相同数据量的情况下,文件数量越多性能越差,文件数量越少单体的文件的体积越大在相同尺寸下大文件显得效率高,当文件在写入时最好一次性写入,不用修改,如果碰上了修改也只能在后面追加不能在中间进行修改,当有多个文件进行写入时,要交给一个 writer 不能是一堆 writer 同时做,这就是 HDFS 应用场景。

2. 节点

image.png

文件要分块,块就是定义的文件存储的大小,分布式文件系统能够读取的最小的数据量就是一个块,一个块儿在一般情况下是64M,可以设置的更大,可以进行设置但通常是64M,在存储文件时有 name node,name node 在管理文件分区表整个文件系统的空间,能看到的整个是一颗文件系统的树,这棵树里面存储的是有关所有文件和目录的一些原数据,就像点开资源管理器一样,看到的目录结构,Data node 是真正在存储实际数据有效的 workhorse,是实际存储数据的地方,存储的不是原数据而文件本身的数据,原数据可以存储第一个 block 在哪里,文件大小是多少,名字是什么,而真正文件中的内容比如电影中这些视频的数据是存储在data node中的,Data node 中存储的数据将其划分成一个一个的 block,这些 block 会存储在 data Note 中,一个大文件切分成若干个 block,存储在 data Note 中,这些data node 在运行过程中会发送一个类似于心跳的东西是周期性的,给 name node 发送报告,报告中包含存储的block 都有哪些类型,作用是通知 name node 还活着,当某一个 data node 发送不出报告时,name node 去查看之前 data node发送的报告就知道哪些数据在这个节点上可能没有办法访问了会进行切换,切换是每个数据在存储时都会分为若干个副本,开始约定的是在一上进行访问,副本会同步到二和三上,当一这个 data node 没有办法发心跳给 name node 时,name node 会发现这块数据是没有办法进行访问的,回去查询原数据这样就知道了副本在二和三,未来对这些 block 的访问直接映射到二和三的副本上,HDFS 有两个选择,第一是尝试修复这个节点将其数据恢复出来,第二个是在数据无法恢复时另起一个新的使它们同步过去,保证在一个系统仍然是有指定数量的节点,这是 hdfs 两个节点的作用

image.png

name node 中存储的是原数据,包含文件的名字,位置,副本数,大概是这样的结构,所以每一个文件都会有其名字,名字在全路径中,副本数是三个,一个一个文件下来,这是整个文件系统中的源文件,用户到来之后实际上每次HDFS 的客户端时但要打开文件或者对此文件进行操作时,Client 是 HDFS 自己提供的会到 name node 上先来按照要求访问的文件找到相应的位置,然后再去看底下应该怎么操作,这是图上 client 的作用,所以总是在 name node 上找数据究竟在哪个 data node 上进行存储,name node 告诉 Client 之后,Client 才会到相应基架服务器上读取想要读的数据,如果有 replica 只要告诉他在哪就可以进行读取了,如果是写操作,client 在写的时候同时要将副本也写入,两个都写进去以后写操作才能结束,而且在写入的时候,client还要考虑这两个副本首先不能在同一台机器上,这是不允许的,还要看是否能在同一个机架上,这种情况是可以的,如果要求更高,必须在两个机架上,另外一个副本可能在其他的地方,无论有几个 client 在进行操作时必须把副本都写进去才算这一次写操作结束,当然这个 client 不是代码而是 HDFS 开发的客户端的类只是获取了这个类告诉它是执行写操作还是读操作,剩下的事情包括写几个副本,怎么决定在哪里写,从哪里读取都是 client 和 HDFS 系统交互实现的,这就是 HDFS 的结构。

3.副本

在数据存储时为什么会需要副本,因为 name node 决定如果要副本这些副本该如何处理,例如在 name node 上要存储文件名,副本的数量以及 block 的 ID,可以看到一个比较大的文件切完以后分为两个部分,part0和 part1,part0有两个副本,part1有三个副本,会讲 part0分为多少个 block,有两个 block,part1有245三个 block

image.png

这时可以看到对于1这个 block 要求有两个副本,所以可以看到图上有两个1,2是 part1的 block 有三个副本,可以看到图上有三个2,剩下的以此类推,存储方式是有一个大文件切成两部分进行存储上面是 part0下面是 part1,prat0又分为两个 block,如果一个 block 是64MB 一共就有128MB,底下切了三个 block 一共是192MB,这些合起来就是完整的文件,这是存储过程,实际上与在一台机器的对比也一样,一台机器的文件分区表是包含文件名字的,第一个存储的扇区在哪里,标记要看是机械式硬盘还是 SSD,机械式硬盘是三维标识在哪一个盘面上,在哪一个词道上以及在哪一个扇区,SSD 是一维的描述的是偏移量是多少,无论怎么样会描述第一块在哪里,整个硬盘如果在 SSD 上会切成很多很多小块,如果在 HDD 是盘片,每个盘片有很多词道划出来的扇区,这是很容易区分的,扇区或者 SSD 切出来的小的block 就是存储文件的最小单元,一个大的 Word 文件存储以后不是直接存储进去就连续存储了也是按照扇区存储的,比如扇区有512个字节,所以就是前面的512个字节存储到扇区中,其中有指针指向下一个扇区在哪里以此类推,所以一个文件在硬盘里不一定是连续存储的,但是如果不连续存储也可以通过指针方式将所有内容都拿到,如果是这种方式 SSD 可以实现因为是一维的比较快,如果是 HHD 就会比较麻烦里面有词头在一直走,盘片在转像唱盘一样读到其中所有的内容,所以当文件不连续时读取的效率会非常低因为读了一块可能下一块在里面,词头可能是向左的方向,一直走才能读到下一个,而且是链表式的结构不可能跳过去读取,所以读取效率很低,磁盘中有磁盘碎片整理一下就会将一个文件的内容尽量挨着一个词道上面连续的进行存储这样效率就会提高,对比在一台机器上的文件系统和分布式文件系统其实没有什么本质差异,将 block 想象成扇区一排机器 name node 可以想象成一圈更大的东西例如 storm 或磁盘片,将512MB 括到64M,原来是在一台机器上现在可以在多台机器上扩过来就是这样的系统,所以可以看到 HDFS如果有类不需要独立实现完全从无到有的 HDFS,完全可以在 Linux 文件系统基础上构建,将一个大的文件取过来以后会切成很多小文件,每一个小文件都是64MB,在面向 Linux 文件系统会告诉 Linux 文件系统有一堆64MB 文件要进行存储,于是 Linux 文件系统看到的是一堆64MB 的文件,每个文件有自己不同的名字文件之间没有什么关联只是存储到了硬盘上,但是 HDFS 本身要进行管理将大的文件切成很多小文件它们之间映射关系是文件名和 block ID 要映射好,在Linux 的文件系统上跑 HDFS 不需要将现在的文件系统破坏掉,是在此之上进行实现的,也就是在一个 Linux 的机器上跑 HDFS 时不是 Linux 本身有文件系统,又跑了一串 HDFS 不是这样的关系,而是在上面有 HDFS,底层仍然是 Linux 标准文件系统上层是将大文件拆分成若干个 Linux 小文件存储,在 name node 中记住映射关系,如果底层的机器不止一个包含若干个,无非是要记录这些小文件在底层那台机器上存储的就可以实现,所以这一点在跑 HDFS 时会看到一个现象,Hadoop 之后为什么会在 Linux 机器上 map 直接跑就跑起来了,整个操作文件系统最近又没用,为什么能在文件上跑起来,这就是 hdfs 的原理,其实不是一个全新的文件系统什么都不要,可以在文件系统之上实现想要的东西,在机器文件系统上看到的不是一个大文件而是一堆小文件要去存储,在上面将大文件分成了小文件关联,所谓的小文件就是一个一个 block,从上面看就是 block,所以是这样的关系。

4.网络距离

image.png

有了关系以后看要求数据要存放副本,争取副本时要满足一定的条件,条件是这些副本的网络距离,比如网络距离必须要大于多少,下面看如何定义网络距离,如果大家在同一台机器上,像图上所示的黄色和蓝色 N1的情况,属于0没有任何网络上的距离,蓝色和下面N2黄颜色的这块儿如果他们是同一个数据的两个副本他们之间的距离就是二,所谓二是指 d1是数据中心里的基架,这些白颜色的表示服务器,因为在两台服务器中间,所以进行通信中间肯定有交换机或者路由器接上去,距离是到路由器然后再过来就把其称为2,同样的道理如果是一个基架与另一个基架也就是蓝色的与 N3距离是4,总是偶数倍,在两个数据中心里距离是六,在存储时可以想象,如果距离都是零,大家都存储在一台机器上,副本存的意义不是特别大,除非认为这个机器的硬盘有一部分坏,例如有坏道正好蓝色的在上面存储而黄的不在上面存储,除非是这种情况黄颜色的有容错能力,否则如果这台机器坏掉了,或者机架坏掉了,或者数据中心坏了,将这些数据都存放在一个服器上几乎没有什么容错能力,所以会想放在一台机器上距离为0只能防止 stop,放两台机器上能防止机器坏,放两个基架上可以防止基架断裂,放两个数据中心可以哪家防止地震使数据中心不存在了,距离会定义副本距离必须满足最大距离要超过多少这样的约束,越大当然越好,但是,可能会有副作用,因为刚才讲过在数据存储时如果真的有这样五个副本,在写数据时或者更新数据或者插入数据时这两种读写数据操作时是要先写到蓝色这里,例如蓝色是 master 然后再同步到其他几个,同步时会发现同步的越远同步的代价越大,因为网络延迟越高,但是这些数据必须要做同步,否则会认为此系统不安全,因为数据里面的内容不一致,如果在集群中不同的副本可以读取负载均衡,如果不做同步意味着经过读写分离的负载均衡大家读到相同的数据块内容不一致,所以网络的距离越大同步的代价越大,但是可靠性提高了,所以可以看到性能和可靠性之间是相矛盾的,如果想获得更高的性能冗余就要越高,冗余之间的距离就要越大,可靠性越高冗余要越多,之间距离越大,性能会下降,性能越高冗余应该要少一点不要同步,或者大家离得很近,但是可靠性下降了,所以最终选哪一个级别是在这两个属性之间做一种权衡,认为哪个更重要或者哪一个不太容易发生,比如一个数据中心坏掉的概率不大,所以不需要这个副本,在这里部署就可以了,这是 HDFS 依靠副本用廉价的机器堆出一个超大超可靠的分布式文件系统,但是性能是有损的,需要做权衡。

image.png 

HDFS 的副本通常会满足在一台机器上,在两个不同的机器上,甚至在两个不同的基架上做这样的动作,Replica 在写入的时候一定是要做同步的,大家都被写入或者更新之后这次写操作才算做完成。

5.读取数据

image.png

Client node 是客户端会拿到 HDFS client 对象,这个对象是 HDFS 提供的,代码在获取到对象的时候要去 open,Open时会得到分布式文件系统抽象出来的一个对象,未来对此进行操作时反应到文件系统中,通过 open 得到对象,Open里面会有参数,包含file文件名是什么,会到 name node 上找那些 block 的位置在哪里,文件会分成很多个block,拿到以后去读取,读取通过下面分布式文件系统的文件 FSdata input stream 像是在 C++里的文件流一样,拿到FSdata input stream 以后去读取,在读取的时候要到下面的 name node 上读取,如果读取是在多个机器上进行操作,支持并行操作,读这些块数据库之后,将流数据关掉,这就是读取数据操作。读取操作比较好办,写数据比较麻烦,写数据时例如创建,会在 name node 上先创建一个节点,插入一个文件,但是现在还不知道那些块都写到了哪里去,底下通过输出流将文件写入,这时就会到底下的 name node 上写,写数据时会告诉另外一个 name node 也要写副本,告诉下一个 name node 也要写副本,因为保证需要有三个副本,最后一个写完会告诉自己以及后面的都写完了,这时接受到了所有的书写完毕,写完以后流关掉,将刚才书写的 block 存在哪些 Data node 上的信息写入到 name node里,文件分区表里面就带了新的文件信息就能够读取到了,从这个写的过程中可以看到必须几个副本都书写成功,写成功不要忘记在里面是高度的抽象的,其实写入时这个文件可能有20个 GB 分成了很多个 block 在写,在向下写的时候,每一个 block 都要经历这样的动作,所以实际上是相硬盘中写了60gb 的内容上去,只要在此过程中某一个地方失败这次写操作可能就失败了,所以写入操作比较费时间。费时间的根本原因是在读取时可以并行的读,就可以在这个节点上读,也可以在另一个节点上读取,读取是所有的节点必须是同步的不存在不同的情况,数据是一致的,在这种情况下要实时一致性,Data node 写完就说写完了等到不忙的时候进行同步,会带来问题,刚才读的时候只能在这个节点上读,所以为了保证实时性三个必须是同步的,所以写入时必须这样写,带来的问题是写入操作比较耗时。

Hadoop 也是这样跑的

Format the filesystem:

$ bin/hdfs namenode -format <

Start NameNode daemon and DataNode daemon:$ sbin/start-dfs.sh

Browse the web interface for the NameNode;by defaultitis available at:

- NameNode-http://localhost:9870/

Hadoop 下面用 map reduce 处理东西时数据在 HDFS 中,跑起来以后可以进行测试

相关文章
|
存储 分布式计算 负载均衡
Hadoop学习笔记(二)之HDFS
Hadoop学习笔记(二)之HDFS
|
6月前
|
存储 机器学习/深度学习 分布式计算
Hadoop学习笔记(HDP)-Part.12 安装HDFS
01 关于HDP 02 核心组件原理 03 资源规划 04 基础环境配置 05 Yum源配置 06 安装OracleJDK 07 安装MySQL 08 部署Ambari集群 09 安装OpenLDAP 10 创建集群 11 安装Kerberos 12 安装HDFS 13 安装Ranger 14 安装YARN+MR 15 安装HIVE 16 安装HBase 17 安装Spark2 18 安装Flink 19 安装Kafka 20 安装Flume
175 0
Hadoop学习笔记(HDP)-Part.12 安装HDFS
|
6月前
|
存储 SQL 分布式计算
Hadoop(HDFS+MapReduce+Hive+数仓基础概念)学习笔记(自用)
Hadoop(HDFS+MapReduce+Hive+数仓基础概念)学习笔记(自用)
520 0
|
机器学习/深度学习 移动开发 分布式计算
配置 HDFS-配置 core-site-hdfs-size 以及 env.sh 等配置文件|学习笔记
快速学习配置 HDFS-配置 core-site-hdfs-size 以及 env.sh 等配置文件
|
存储 缓存 分布式计算
HDFS(二)|学习笔记
快速学习 HDFS(二)
155 0
HDFS(二)|学习笔记
|
SQL JSON 负载均衡
离线同步 mysql 数据到 HDFS2 | 学习笔记
快速学习离线同步 mysql 数据到 HDFS2
188 0
离线同步 mysql 数据到 HDFS2  |  学习笔记
|
SQL 消息中间件 JSON
离线同步 mysql 数据到 HDFS1 | 学习笔记
快速学习离线同步 mysql 数据到 HDFS1
157 0
离线同步 mysql 数据到 HDFS1  |  学习笔记
|
监控 开发工具 开发者
网站流量日志 Flume收集--hdfs--基于文件闲置策略滚动| 学习笔记
快速学习网站流量日志 Flume收集--hdfs--基于文件闲置策略滚动
网站流量日志 Flume收集--hdfs--基于文件闲置策略滚动| 学习笔记
|
分布式计算 资源调度 Hadoop
CDH 搭建_ Hadoop _ HDFS _主节点|学习笔记
快速学习 CDH 搭建_ Hadoop _ HDFS _主节点
371 0
CDH 搭建_ Hadoop _ HDFS _主节点|学习笔记
|
SQL 分布式计算 资源调度
CDH 搭建_ Hadoop _ HDFS _从节点和总结|学习笔记
快速学习 CDH 搭建_ Hadoop _ HDFS _从节点和总结
172 0
CDH 搭建_ Hadoop _ HDFS _从节点和总结|学习笔记

热门文章

最新文章