目录
技能目标
目录
三.掌握HDFS文件的读写流程、副本摆放策略,认知HDFS数据负载均衡和机架感知。
一.掌握HDFS文件系统的访问方式
org.apache.hadoop.fs.FileSystem是抽象的文件访问接口
使用shell方式访问
1.列出文件目录 hdfs dfs -ls /
2.递归方式列出目录包括子目录 hdfs dfs -ls -R /
3.在HDFS中创建文件夹 hdfs dfs -mkdir /datatest
4.级联创建一个文件夹 hdfs dfs -mkdir -p /datatest/set
5.上传文件至HDFS hdfs dfs -put /local/input.txt /datatest (/local/input.txt本地文件路径,/datatest hdfs文件路径)
6.从HDFS上下载文件 hdfs dfs -get /datatest/input.txt /home (/datatest/input.txt hdfs文件路径,/home 本地路径)
7.查看HDFS上某个文件的内容 hdfs dfs -text /datatest/input.txt (或者cat)
8.统计目录下各文件的大小 hdfs dfs -du /datatest/
9.删除HDFS上的某个文件或者文件夹 hdfs dfs -rmr /datatest/
10.使用help命令寻求帮助 hdfs dfs -help 命令(例如 rm,cat)
二.掌握HDFS的体系结构
hdfs概念
1.数据块(Block)
HDFS默认的最基本的存储单位是数据块(Block),默认的块大小(Block Size)是64MB(有些发布版本为128MB)。HDFS中的文件是分成以Block Size为大小的数据块存储的。如果一个文件小于一个数据块的大小,并不占用整个数据块存储空间,文件大小是多大就占用多少存储空间。
2.元数据节点(Name Node)
Name Node的职责是管理文件系统的命名空间,它将所有的文件和文件夹的元数据保存在一个文件系统树中,如一个文件包括哪些数据块,这些数据块分布在哪些数据节点上,这些信息都要存储下来。
Name Node目录结构如下所示。
${dfs.name.dir}/current/VERSION
/edits
/fsimage
/fstime
目录结构描述如下。
(1)VERSION文件是存放版本信息的文件,它保存了HDFS的版本号。
(2)edits:当文件系统客户端进行写操作时,首先记录在修改日志中,元数据节点在内存中保存了文件系统的元数据信息。在记录了修改日志后,元数据节点则修改内存中的数据结构。每次写操作成功之前,修改日志都会同步到文件系统。
(3)fsimage文件即名字空间文件。
3.数据节点(Data Node)
Data Node是文件系统中真正存储数据的地方,一个文件被拆分成多个Block后,会将这些Block存储在对应的数据节点上。客户端向Name Node发起请求,然后到对应的数据节点上写入或者读出对应的数据Block。
Data Node目录结构如下所示。
${dfs.name.dir}/current/VERSION
/blk_<id_1>
/blk_<id_1>.meta
/...
/blk_<id_64>
/blk_<id_64>.meta
/subdir0/
/subdir1/
/...
/subdir63/
目录结构描述如下。
(1)blk_<id>保存的是HDFS的数据块,其中保存了具体的二进制数据。
(2)blk_<id>.meta保存的是数据块的属性信息:版本信息、类型信息和校验和。
(3)subdirxx:当一个目录中的数据块达到一定数量的时候,则创建子文件夹来保存数据块及数据块属性信息。
4.从元数据节点(Secondary Name Node)
Secondary Name Node并不是Name Node节点出现问题时的备用节点,它和元数据节点分别负责不同的功能。其主要功能就是周期性地将Name Node的namespace image和edit log合并,以防日志文件过大。合并后的namespace image也在元数据节点保存了一份,以防在Name Node失效的时候进行恢复。
Secondary Name Node目录结构如下所示。
${dfs.name.dir}/current/VERSION
/edits
/fsimage
/fstime
/previous.checkpoint/VERSION
/edits
/fsimage
/fstime
Secondary Name Node用来帮助Name Node将内存中的元数据信息checkpoint到硬盘上。
5.架构概述
HDFS采用master/slave架构。一个HDFS集群由一个Name Node和一定数量的Data Node组成。Name Node是一个中心服务器,负责管理文件系统的名字空间(namespace)以及客户端对文件的访问。集群中的Data Node一般是一个节点对应一个,负责管理它所在节点上的存储数据。HDFS暴露了文件系统的名字空间,用户能够以文件的形式在上面存储数据。从内部看,一个文件其实被分成一个或多个数据块,这些块存储在一组Data Node上。Name Node执行文件系统的名字空间操作,比如打开、关闭、重命名文件或目录,它也负责确定数据块到具体DataNode的映射。Data Node负责处理文件系统客户端的读写请求,在Name Node的统一调度下进行数据块的创建、删除和复制。HDFS架构如图2.2所示。
三.掌握HDFS文件的读写流程、副本摆放策略,认知HDFS数据负载均衡和机架感知。
HDFS运行原理
1.掌握HDFS文件读写流程。
1)HDFS文件读流程
(1)客户端通过调用File System的open方法获取需要读取的数据文件,对于HDFS来说该FileSystem就是Distribute File System。
(2)Distribute File System通过RPC来调用Name Node,获取到要读取的数据文件对应的Block存储在哪些Data Node之上。 (3)客户端先到最佳位置(距离最近)的Data Node上调用FSData Input Stream的read方法,通过反复调用read方法,可以将数据从Data Node传递到客户端。
(4)当读取完所有的数据之后,FSData Input Stream会关闭与Data Node的连接,然后寻找下一块的最佳位置,客户端只需要读取连续的流。
(5)一旦客户端完成读取操作后,就对FSData Input Stream调用close方法来完成资源的关闭操作。
2)HDFS文件写流程
(1)客户端通过调用Distribute File System的create方法来创建一个文件。
(2)Distribute File System会对Name Node发起RPC请求,在文件系统的名字空间中创建一个新的文件,此时会进行各种检查,比如检查要创建的文件是否已经存在,如果该文件不存在,Name Node就会为该文件创建一条元数据记录。
(3)客户端调用FSData Output Stream的write方法将数据写到一个内部队列中。假设副本系数为3,那么将队列中的数据写到3个副本对应存储的Data Node上。
(4)FSData Output Stream内部维护着一个确认队列,当接收到所有Data Node确认写完的消息后,数据才会从确认队列中删除。
(5)当客户端完成数据的写入后,会对数据流调用close方法来关闭相关资源。
2.认知HDFS的副本机制。
HDFS上的文件对应的Block保存有多个副本且提供容错机制,因此副本丢失或宕机时能够自动恢复。默认保存3个副本。HDFS副本摆放机制如图2.5所示。
1).副本摆放策略第一个副本:放置在上传文件的Data Node上;如果是集群外提交,则随机挑选一个磁盘不太慢、CPU不太忙的节点。第二个副本:放置在与第一个副本不同的机架的节点上。第三个副本:放置在与第二个副本相同机架的不同节点上。如果还有更多的副本则随机放在节点中。
2)副本系数
3)HDFS负载均衡
HDFS的架构支持数据均衡策略。如果某个Data Node上的空闲空间低于特定的临界点,按照数据均衡策略,系统就会自动将数据从这个Data Node移动到其他空闲的Data Node上。当对某个文件的请求突然增加,也可能启动一个计划来创建该文件新的副本,同时重新平衡集群中的其他数据。当HDFS负载不均衡时,需要对HDFS进行数据的负载均衡调整,即对各节点机器上数据的存储分布进行调整,从而让数据均匀地分布在各个Data Node上,以均衡IO性能、平衡IO负载、平均数据、平衡集群,防止热点的发生。
在Hadoop中,包含一个start-balancer.sh脚本,通过运行这个脚本,可以启动HDFS的数据均衡服务Balancer。该脚本位于$HADOOP_HOME/bin目录下。启动命令为:$HADOOP_HOME$HADOOP_HOME/bin/start-balancer.sh –threshold
影响Balancer的几个参数。
(1)-threshold默认设置:10,参数取值范围:0~100参数含义:判断集群是否平衡的阈值。理论上,该参数值越小整个集群越平衡。
(2)dfs.balance.bandwidth Per Sec默认设置:1048576(1M/s)参数含义:Balancer运行时允许占用的带宽。
示例如下:
#启动数据均衡,默认阈值为10%
$HADOOP_HOME/bin/start-balancer.sh
#启动数据均衡,阈值5%
$HADOOP_HOME/bin/start-balancer.sh –threshold 5
#停止数据均衡
$HADOOP_HOME/bin/stop-balancer.sh
在hdfs-site.xml文件中可以设置数据均衡占用的网络带宽限制。
<property>
<name>dfs.balance.bandwidth Per Sec</name>
<value>1048576</value>
<description> Specifies the maximum bandwidth that each datanode can utilize forthe balancing purpose in term of the number of bytes per second.</description>
</property>
3.了解HDFS文件数据的负载均衡和机架感知。
HDFS机架感知
HDFS不能自动判断集群中各个Data Node的网络拓扑情况。但Hadoop允许集群的管理员通过配置dfs.network.script参数来确定节点所处的机架。配置文件提供了ip到rackid的翻译。NameNode通过这个配置可以知道集群中各个Data Node机器的rackid。如果topology.script.file.name没有设定,则每个ip都会被翻译成/default-rack。机架感知如图2.6所示。
图中D和R代表交换机,H代表Data Node。则H1的rackid=/D1/R1/H1,有了rackid信息(这些rackid信息可以通过topology.script.file.name 配置),就可以计算出任意两台Data Node之间的距离。
distance(/D1/R1/H1,/D1/R1/H1) = 0 相同的Data Node
distance(/D1/R1/H1,/D1/R1/H2) = 2 同一rack下的不同Data Node
distance(/D1/R1/H1,/D1/R1/H4) = 4 同一IDC下的不同Data Node
distance(/D1/R1/H1,/D1/R1/H7) = 6 不同IDC下的Data Node
四.了解HDFS的序列化使用
1.什么是序列化和反序列化序列化:将对象转化为字节流,以便在网络上传输或者写在磁盘上进行永久存储。
反序列化:将字节流转回成对象。序列化在分布式数据处理的两个领域经常出现:进程间通信和永久存储。
Hadoop中多个节点进程间通信是通过远程过程调用(Remote Procedure Call,RPC)实现的。
2.Hadoop的序列化
Hadoop的序列化并不采用Java的序列化,而是采用自己的序列化机制。
在Hadoop的序列化机制中,用户可以复用对象,这就减少了Java对象的分配和回收,提高了应用效率。Hadoop通过Writable接口实现序列化机制,但没有提供比较功能,所以和Java中的Comparable接口合并,提供了一个Writable Comparable接口。
public interface Writable{ void write(DataOutput out)throws IOException; //状态写入到DataOutput二进制流 void readFields(DataInput in)throws IOException; //从DataInput二进制流中读取状态}
public interface Writable Comparable<T> extends Writable, Comparable<T>{}
3.Hadoop的序列化案例
4.Sequence File概述
Sequence File是Hadoop提供的一种对二进制文件的支持。二进制文件直接将<Key, Value>对序列化到文件中。而HDFS是适合存储大文件的,很小的文件如果很多的话,Name Node的压力会非常大,因为每个文件都会有一条元数据信息存储在Name Node上,小文件非常多也就意味着在Name Node上存储的元数据信息非常多。Hadoop是适合存储大数据的,所以可以通过Sequence File将小文件合并,从而获得更高效率的存储和计算。Sequence File中的Key和Value可以是任意类型的Writable或者自定义Writable类型。
注意
对于一定大小的数据,比如说100GB,如果采用Sequence File进行存储的话,占用的空间将是大于100GB的,因为为了查找方便Sequence File的存储中添加了一些额外的信息。
1) Sequence File特点
1.1)支持压缩:可定制为基于Record(记录)和Block(块)压缩。
无压缩类型:如果没有启动压缩(默认设置),那么每个记录就由它的记录长度(字节数)、键的长度、键和值组成,长度字段为4字节。Sequence File内部结构如图2.7所示。
Record针对行压缩,只压缩Value部分不压缩Key;而Block对Key和Value都压缩。
1.2)本地化任务支持:因为文件可以被切分,因此在运行Map Reduce任务时数据的本地化情况应该是非常好的;尽可能多地发起Map Task来进行并行处理,进而提高作业的执行效率。
2)Sequence File写操作
优化:
1.hdfs不适合存储大量小文件
无法高效存储大量小文件。HDFS中的元数据(元数据信息包括:文件和目录自身的属性信息,例如文件名、目录名、父目录信息、文件大小、创建时间、修改时间等,记录与文件内容存储相关的信息,例如文件块情况、副本个数、每个副本存放在哪儿等)存放在Name Node中,所以HDFS所能容纳的文件数目由Name Node的内存大小决定。一旦集群中的小文件过多,会导致Name Node的压力陡增,进而影响到集群的性能。所以可以采用Sequence File等方式对小文件进行合并,或者是使用Name Node Federation的方式来改善。