HDFS文件系统

来源:互联网 发布:网络直销平台有哪些 编辑:程序博客网 时间:2024/06/16 08:14

HDFS文件系统

Hadoop 附带了一个名为 HDFS(hadoop分布式文件系统)的分布式文件系统,专门存储超大数据文件,为整个Hadoop生态圈提供了基础的存储服务。

本章内容:

1) HDFS文件系统的特点,以及不适用的场景

2) HDFS文件系统重点知识点:体系架构和数据读写流程

3) 关于操作HDFS文件系统的一些基本用户命令

1. HDFS特点

HDFS专为解决大数据存储问题而产生的,其具备了以下特点:

1) HDFS文件系统可存储超大文件

每个磁盘都有默认的数据块大小,这是磁盘在对数据进行读和写时要求的最小单位,文件系统是要构建于磁盘上的,文件系统的也有块的逻辑概念,通常是磁盘块的整数倍,通常文件系统为几千个字节,而磁盘块一般为512个字节。

HDFS是一种文件系统,自身也有块(block)的概念,其文件块要比普通单一磁盘上文件系统大的多,默认是64MB

HDFS上的块之所以设计的如此之大,其目的是为了最小化寻址开销。

HDFS文件的大小可以大于网络中任意一个磁盘的容量,文件的所有块并不需要存储在一个磁盘上,因此可以利用集群上任意一个磁盘进行存储,由于具备这种分布式存储的逻辑,所以可以存储超大的文件,通常GTP级别

2) 一次写入,多次读取

一个文件经过创建、写入和关闭之后就不需要改变,这个假设简化了数据一致性的问题,同时提高数据访问的吞吐量。

3) 运行在普通廉价的机器上

Hadoop的设计对硬件要求低,无需昂贵的高可用性机器上,因为在HDFS设计中充分考虑到了数据的可靠性、安全性和高可用性。

2. 不适用于HDFS的场景:

1) 低延迟

HDFS不适用于实时查询这种对延迟要求高的场景,例如:股票实盘。往往应对低延迟数据访问场景需要通过数据库访问索引的方案来解决,Hadoop生态圈中的Hbase具有这种随机读、低延迟等特点。

2) 大量小文件

对于Hadoop系统,小文件通常定义为远小于HDFS的block size(默认64MB)的文件,由于每个文件都会产生各自的MetaData元数据,Hadoop通过Namenode来存储这些信息,若小文件过多,容易导致Namenode存储出现瓶颈

3) 多用户更新

为了保证并发性,HDFS需要一次写入多次读取,目前不支持多用户写入,若要修改,也是通过追加的方式添加到文件的末尾处,出现太多文件需要更新的情况,Hadoop是不支持的

针对有多人写入数据的场景,可以考虑采用hbase的方案。

4) 结构化数据

HDFS适合存储半结构化和非结构化数据,若有严格的结构化数据存储场景,也可以考虑采用Hbase的方案。

5) 数据量并不大

通常Hadoop适用于TBPB数据,若待处理的数据只有几十GB的话,不建议使用Hadoop,因为没有任何好处。

3. HDFS体系架构

HDFS是一个主/从(Master/Slave)体系架构,由于分布式存储的性质,集群拥有两类节点NameNode和DataNode

NameNode(名字节点):系统中通常只有一个,中心服务器的角色,管理存储和检索多个DataNode的实际数据所需的所有元数据

DataNode(数据节点):系统中通常有多个,是文件系统中真正存储数据的地方,在NameNode统一调度下进行数据块的创建、删除和复制。

 wKioL1i9KcmCIznvAAB4PhOoKbo579.png

图中的ClientHDFS的客户端,是应用程序可通过该模块与NameNode和DataNode进行交互,进行文件的读写操作。

4. HDFS数据块复制

为了系统容错,文件系统会对所有数据块进行副本复制多份,Hadoop是默认3副本管理。

wKioL1i9KpyiQG9YAACGRYANGLE426.png 

复本管理策略是运行客户端的节点上放一个复本(若客户端运行在集群之外,会随机选择一个节点),第二个复本会放在与第一个不同且随机另外选择的机架中节点上,第三个复本与第二个复本放在相同机架,切随机选择另一个节点。所存在其他复本,则放在集群中随机选择的节点上,不过系统会尽量避免在相同机架上放太多复本。

所有有关块复制的决策统一由NameNode负责,NameNode会周期性地接受集群中数据节点DataNode的心跳和块报告。一个心跳的到达表示这个数据节点是正常的。一个块报告包括该数据节点上所有块的列表。

5. HDFS读取写入流程

1) 读文件的过程:

wKioL1i9Kt6Tt0gKAAHxOTzccog276.png 

首先Client通过File System的Open函数打开文件Distributed File System用RPC调用NameNode节点,得到文件的数据块信息。对于每一个数据块,NameNode节点返回保存数据块的数据节点的地址。Distributed File System返回FSDataInputStream给客户端,用来读取数据。客户端调用stream的read()函数开始读取数据。DFSInputStream连接保存此文件第一个数据块的最近的数据节点。DataNode从数据节点读到客户端(client),当此数据块读取完毕时,DFSInputStream关闭和此数据节点的连接,然后连接此文件下一个数据块的最近的数据节点。当客户端读取完毕数据的时候,调用FSDataInputStream的close函数。

在读取数据的过程中,如果客户端在与数据节点通信出现错误,则尝试连接包含此数据块的下一个数据节点。失败的数据节点将被记录,以后不再连接。

2) 写文件的过程:

wKiom1i9KuuzYBs4AAJLZczgjOs382.png 

客户端调用create()来创建文件Distributed File System用RPC调用NameNode节点,在文件系统的命名空间中创建一个新的文件。NameNode节点首先确定文件原来不存在,并且客户端有创建文件的权限,然后创建新文件。

Distributed File System返回DFSOutputStream,客户端用于写数据。客户端开始写入数据,DFSOutputStream将数据分成块,写入Data Queue。Data Queue由Data Streamer读取,并通知NameNode节点分配数据节点,用来存储数据块(每块默认复制3块)。分配的数据节点放在一个Pipeline里。Data Streamer将数据块写入Pipeline中的第一个数据节点。第一个数据节点将数据块发送给第二个数据节点。第二个数据节点将数据发送给第三个数据节点。

DFSOutputStream为发出去的数据块保存了Ack Queue,等待Pipeline中的数据节点告知数据已经写入成功。

6. 操作HDFS基本命令

1) 打印文件列表(ls)

标准写法:

hadoop fs -ls hdfs:/#hdfs: 明确说明是HDFS系统路径

 

简写:

hadoop fs -ls /#默认是HDFS系统下的根目录

 

打印指定子目录:

hadoop fs -ls /package/test/#HDFS系统下某个目录

2) 上传文件、目录(put、copyFromLocal

put用法

上传新文件:

hdfs fs -put file:/root/test.txt hdfs:/  #上传本地test.txt文件到HDFS根目录,HDFS根目录须无同名文件,否则“File exists”

hdfs fs -put test.txt /test2.txt  #上传并重命名文件。

hdfs fs -put test1.txt test2.txt hdfs:/  #一次上传多个文件到HDFS路径。

 

上传文件夹:

hdfs fs -put mypkg /newpkg  #上传并重命名了文件夹。

 

覆盖上传:

hdfs fs -put -f /root/test.txt /  #如果HDFS目录中有同名文件会被覆盖

copyFromLocal用法:

上传文件并重命名:

hadoop fs -copyFromLocal file:/test.txt hdfs:/test2.txt

 

覆盖上传:

hadoop fs -copyFromLocal -f test.txt /test.txt

3) 下载文件、目录(getcopyToLocal

get用法:

拷贝文件到本地目录:

hadoop fs -get hdfs:/test.txt file:/root/

 

拷贝文件并重命名,可以简写:

hadoop fs -get /test.txt /root/test.txt

copyToLocal用法

拷贝文件到本地目录:

hadoop fs -copyToLocal hdfs:/test.txt file:/root/

 

拷贝文件并重命名,可以简写:

hadoop fs -copyToLocal /test.txt /root/test.txt

4) 拷贝文件、目录(cp

从本地到HDFS,同put

hadoop fs -cp file:/test.txt hdfs:/test2.txt

 

从HDFS到HDFS

hadoop fs -cp hdfs:/test.txt hdfs:/test2.txt

hadoop fs -cp /test.txt /test2.txt

5) 移动文件(mv

hadoop fs -mv hdfs:/test.txt hdfs:/dir/test.txt

hadoop fs -mv /test.txt /dir/test.txt

6) 删除文件、目录(rm

删除指定文件

hadoop fs -rm /a.txt

 

删除全部txt文件

hadoop fs -rm /*.txt

 

递归删除全部文件和目录

hadoop fs -rm -R /dir/

7) 读取文件(cat、tail)

hadoop fs -cat /test.txt  #以字节码的形式读取

hadoop fs -tail /test.txt

8) 创建空文件(touchz

hadoop fs - touchz /newfile.txt

9) 创建文件夹(mkdir

hadoop fs -mkdir /newdir /newdir2#可以同时创建多个

hadoop fs -mkdir -p /newpkg/newpkg2/newpkg3 #同时创建父级目录

10) 获取逻辑空间文件、目录大小(du


hadoop fs - du /  #显示HDFS根目录中各文件和文件夹大小

hadoop fs -du -h /  #以最大单位显示HDFS根目录中各文件和文件夹大小

hadoop fs -du -s /  #仅显示HDFS根目录大小。即各文件和文件夹大小之


HDFS参数调优:


DataNode配置参数(添加到hdfs-site.xml中)
1.dfs.data.dir 或dfs.datanode.data.dir(第二个是新参数,与第一个意思一样) 
    配置多块物理盘,用逗号分割,比如/mnt/disk1,/mnt/disk2等,由于一台机器可能有很多磁盘,hdfs会轮询的将block存储到每块盘上。
<property>
      <name>dfs.datanode.data.dir</name>
      <value>/mnt/disk1,/mnt/disk2</value>
    </property>
2. dfs.datanode.failed.volumes.tolerated
    物理磁盘快容忍失败数目(超过该数目,该DN不再提供服务),默认为0;
3.dfs.datanode.du.reserved
    单位为byte,每块物理磁盘预留给非HDFS服务(比如yarn、mapreduce)的存储空间,默认为0;
4.dfs.balance.bandwithPerSec或dfs.datanode.balance.bandwithPerSec  单位是字节byte
   balancer时,hdfs移动数据的速度,默认值为1048576(也即1MB/s)的速度。一般情况下设置为10M;设置的过大会影响当前job的运行。
   修改dfs.balance.bandwidthPerSec参数,需要在namenode上重启hdfs生效。
   stop-dfs.sh
   start-dfs.sh
   
5.dfs.datanode.handler.count
   Datanode RPC线程数,默认是10
6.dfs.datanode.max.xcievers或dfs.datanode.max.transfer.threads
datanode接受和发送数据的线程数,默认是4096,如果集群中datanode小于200个节点,5和6不需要进行优化。


NameNode配置参数(添加到hdfs-site.xml中)
1.fs.trash.interval
    单位为分钟,被删除的文件存放到垃圾桶的时间,默认是0,即不开启(在core-site.xml中配置)
2.dfs.replication
    数据块的副本数,默认是3(core-site.xml)
3.dfs.block.size 或 dfs.blocksize
   数据块的大小,单位为byte,默认为134217728(也即128)(core-site.xml)。如果文件基本都很大,可以适当改成256MB或512MB
4.dfs.namenode.handler.count
    NameNode RPC线程数,默认是10(hdfs-site.xml中配置)
JVM内存参数(hadoop-env.sh配置)
1.NameNode 进程的JVM配置:HADOOP_NAMENODE_OPTS
--需要配置大内存,1亿个对象(文件和block总数)约占20G内存,如果线上有上百个节点,建议Namenode的机器内存配置在128G甚至更高。
   --启用CMS(Concurrent Mark Sweep)垃圾回收
  export HADOOP_NAMENODE_OPTS="-XX:+UseConcMarkSweepGC -XX:ParallelGCThreads=8 -XX:+UseCMSInitingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 -Xms20G -Xmx20G -XX:NewSize=128M -XX:MaxNewSize=128M -XX:PermSize=128M -XX:MaxPermSize=256M"
2.Datanode 进程的JVM配置:HADOOP_DATANODE_OPTS
  --配置内存为2GB或4GB
  export HADOOP_DATANODE_OPTS="-XX:+UseConcMarkSweepGC -XX:ParallelGCThreads=8 -XX:+UseCMSInitingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 -Xms4G -Xms4G"

-Xmx:JVM最大允许分配的堆内存;
-Xms:JVM初始分配的堆内存(一般等于-Xmx);
-Xmn:JVM堆中年轻代的大小;
-Xss:每个线程都需要一定的栈空间,-Xss定义栈空间的大小;
-XX:StackYellowPages:线程栈尾部会预留两块受保护的内存区域,分别是yellow page和red page,此参数配置yellow page的大小。访问到此处的代码会抛出StackOverflowError异常;
-XX:StackRedPages:同上,red page的大小
-XX:+UseConcMarkSweepGC:该标志意味着激活CMS收集器;
-XX:UseParNewGC:一般与上述标志配合使用,激活年轻代使用多线程并行执行垃圾收集;
-XX:+CMSConcurrentMTEnbaled:启动该标志,并发的CMS阶段以多线程执行;
-XX:ConcGCThreads:定义了上述并发CMS过程运行时的线程数;
-XX:CMSInitiatingOccupancyFraction:JVM满了之后,会启动并行收集器开始full GC,此时JVM STW,为了尽量减少Full GC,需要在应用程序用完内存之间尽量使用CMS GC回收尽量多的空间,这个参数指定了CMS GC启动的时机,表示内存消耗达到此比例时开启CMS GC,默认68%。
-XX:+CMSClassUnloadingEnabled:设置此标志,开启永久代垃圾回收。
-XX:+CMSIncrementalMode:开启CMS收集器的增量模式,所谓增量模式是指CMS GC的过程中可以暂停,以对应用程序作出让步。很明显,开启此标志会延长CMS GC的时间。
-XX:+DisableExplicitGC:通知JVM忽略所有的系统GC调用;
-XX:+UseCompactAtFullCollection:由于在CMS的回收步骤中,不会对内存进行压缩,所以会有内存碎片出现,CMS提供了一个整理碎片的功能,通过此标志开启。默认为0,意味着每次GC结束后都会进行内存碎片整理。内存碎片会导致不可预知的full GC行为,因此该值建议取0。
-XX:+UseCompressedOops:压缩普通对象的指针,可用于压缩应用消耗的内存空间。需要注意的是:堆大于32G时,该标志会失效。
-XX:+CMSScavengeBeforeRemark:意思是在执行CMS remark之前进行一次youngGC,这样能有效降低remark的时间。
-XX:+SoftRefLRUPolicyMSPerMB:贴一下官方解释softly reachable objects will remain alive for some amount of time after the last time they were referenced.The default value is one second of lifetime per free megabyte in the heap,没有必要等1s,可以设置成0.


原创粉丝点击