HDFS基本操作命令和读写原理

  • 一、基本操作命令
  • 1、创建目录 mkdir
  • 2、查看文件,ls 没有cd命令, 需要指绝对路径
  • 3、上传文件 put
  • 4、下载文件 get
  • 5、复制 cp
  • 6、查看文件内容 cat , 如果数据量比较大,不能使用
  • 7、移动 mv, 物理层面文件没有移动,只是改变了元数据(目录结构)
  • 8、删除文件或者目录 rmr
  • 8.1回收站自动清理
  • 8.2手动删除回收站
  • 8.3强制删除,-skipTrash 当需要删除的文件比较大的时候
  • 9、查看文件末尾 tail -f ; 一直等待查看
  • 10、查看文件的大小
  • 二、读写原理
  • 1.读数据
  • 2.写数据
  • 三、优缺点
  • 1.优点:
  • 2.缺点:


一、基本操作命令

1、创建目录 mkdir

mkdir : 创建目录
/data ; 路径 , 需要从 "/" 开始
hadoop dfs -mkdir /data

-p  : 递归创建多级目录
hadoop dfs -mkdir -p  /a/b/c

2、查看文件,ls 没有cd命令, 需要指绝对路径

hadoop dfs -ls /data

权限(rwx(当前用户的权限) ,r-x (当前用户组的权限) ,r-x 其他用户的权限))
drwxr-xr-x   - root supergroup          0 2021-01-05 00:11 /a
drwxr-xr-x   - root supergroup          0 2021-01-05 00:09 /data

3、上传文件 put

创建路径
hadoop dfs -mkdir /data/student

上传学生表的数据到hdfs,  students.txt: linux本地的一个文件,/data/student: hdfs 目录
hadoop dfs -put students.txt /data/student


hadoop dfs -mkdir /data/score
hadoop dfs -put score.txt /data/score

hadoop dfs -mkdir /data/cource
hadoop dfs -put cource.txt /data/cource

4、下载文件 get

将hdfs文件下载到linux本地

hadoop dfs -get /data/student/students.txt

5、复制 cp

/data/a.txt  :源文件或者目录
 / : 目标目录

hadoop dfs -cp /data/a.txt  /

6、查看文件内容 cat , 如果数据量比较大,不能使用

hadoop dfs -cat /data/student/students.txt

7、移动 mv, 物理层面文件没有移动,只是改变了元数据(目录结构)

hadoop dfs -mv /a.txt /a

8、删除文件或者目录 rmr

hadoop dfs -rmr /a/a.txt

并没有真正删除文件,只是将文件放到了回收站中,

/user/root/.Trash/Current  ; 每一个用户都有一个回收站

文件永久删除:

8.1回收站自动清理

<property>
<name>fs.trash.interval</name>
<value>1440</value>
</property>

8.2手动删除回收站

Hadoop dfs -rmr /user/root/.Trash/Current

8.3强制删除,-skipTrash 当需要删除的文件比较大的时候

hadoop dfs -rmr -skipTrash /a

9、查看文件末尾 tail -f ; 一直等待查看

hadoop dfs -tail /data/student/students.txt

10、查看文件的大小

hadoop dfs -du -h  /data

二、读写原理

首先了解下面三个东西
1.block:
前面也提到过block块,它是数据存储的最大单位,在进行文件上传前client会对文件进行分块,分得的块就是block,默认128M,这是在综合考虑寻址时间和传输效率的的情况下得出的最佳大小。

2.packet:
packet是client向DataNode传输数据时候的基本单位,默认64KB。

3.chunk:
chunk是进行数据校验的基本单位,默认512Byte,加上4Byte的校验位,实际上chunk写入packet的大小为516Byte,常见于client向DataNode进行的数据校验。

1.读数据

dfs指的是什么 在hadoop项目结构中h hdfs dfs -mkdir_客户端


dfs指的是什么 在hadoop项目结构中h hdfs dfs -mkdir_客户端_02

粗略流程:

1.客户端向namenode 请求下载文件,namenode 通过查询元数据,找到文件块所在的datanode地址。
2.挑选一台datanode(就近原则,然后随机)服务器,请求读取数据。
3.datanode 开始传输数据给客户端(从磁盘里面读取数据放入流,以packet 为单位来做校验)。
4.客户端以packet 为单位接收,先在本地缓存,然后写入目标文件。

详细流程:

1.首先调用FileSystem的open方法获取一个DistributedFileSystem实例;

2.然后DistributedFileSystem实例通过RPC在NameNode里获得文件的第一批block的locations(可能
是需要读取文件的全部,也可能是一部分),同一个block会按照在DataNode的重复数返回多个locations;

3.返回的多个locations会按照Hadoop拓扑结构排序,按照就近原则来排序;

4.前面三步结束后会返回一个FSDataInputStream对象,通过调用read方法时,该对象会找出离客户端最近
的DataNode并与之建立连接;

5.数据通过io流从DataNode源源不断地流向客户端;

6.如果第一个block块数据读取完成,就会关闭指向第一个block块的DataNode连接,接着读取下一个block
块,直到把这一批的block块数据读取完成;

7.每读取完一个block块都会进行checksum验证(校验每个块的信息通过偏移量和预写值对比,写的时候是校
验packet的信息),如果读取 DataNode 时出现错误,客户端会 通知 NameNode,然后再从下一个拥有
block 拷贝的 DataNode 继续读;

8.如果第一批blocks读取完成,且文件读取还没有结束,也就是文件还没读完。FSDataInputStream就会
向NameNode获取下一批blocks的locations,然后重复上面的步骤,直到所有blocks读取完成,这时就会
关闭所有的流。

2.写数据

dfs指的是什么 在hadoop项目结构中h hdfs dfs -mkdir_hdfs_03


dfs指的是什么 在hadoop项目结构中h hdfs dfs -mkdir_客户端_04

粗略流程:

1.客户端向namenode 请求上传文件,namenode 检查目标文件是否已存在,父目录是否存在。
2.namenode 返回是否可以上传。
3.客户端请求第一个block 上传到哪几个datanode 服务器上。
4.namenode 返回3 个datanode 节点,分别为dn1、dn2、dn3。
5.客户端请求dn1 上传数据,dn1 收到请求会继续调用dn2,然后dn2 调用dn3,将这个通信管道建立完成
6.dn1、dn2、dn3 逐级应答客户端
7.客户端开始往dn1 上传第一个block(先从磁盘读取数据放到一个本地内存缓存),packet 为单位,dn1 收到一个packet 就会传给dn2,dn2 传给dn3;dn1 每传一个packet 会放入一个应答队列等待应答
8.当一个block 传输完成之后,客户端再次请求namenode 上传第二个block 的服务器。(重复执行3-7 步)

细致流程:

1.客户端使用Configuration类加载配置文件信息,然后调用FileSystem的get()方法,获取一个分布式文
件系统对象DistributedFileSystem。然后通过调用这个对象的create方法,向NameNode发送写文件请求;

2.客户端通过RPC与NameNode进行通信,NameNode需要经过各种不同的检查,比如命名空间里该路径文件是
否存在,客户端是否有相应权限。如果没有通过,返回IOException,反之如果检查通过,NameNode就会在
命名空间下新建该文件(此时新文件大小为0字节),并记录元数据,返回一个FSDataOutputStream输出流对象;

3.FSDataOutputStream封装了一个DFSOutputStream对象,由该对象负责处理datanode和namenode之间
的通信。(DistributedFileSystem.create()会DFSClient.create()方法创建DFSOutputStream输出
流并构造一个HdfsDataOutputStream来包装DFSOutputStream);

4.客户端把数据按照block块进行切分;

5.然后调用DFSOutputStream的create方法,开始执行写入操作(FSDataOutputStream封装了一个DFSOutputStream对象,由该对象负责处理datanode和namenode之间的通信),DFSOutputStream会把
数据切成一个个小packet,然后排成队列 dataQueue;

6.DataStreamer(DFSOutputStream的内部线程类)会去处理dataQueue,它先问询 NameNode 这个新的
block 最适合存储的在哪几个DataNode里,比如重复数是3,那么就找到3个最适合的 DataNode,把它们
排成一个 pipeline。DataStreamer 把 packet 按队列输出到管道的第一个 DataNode 的内存中,然后
第一个 DataNode又把 packet 输出到第二个 DataNode 中,以此类推;
 
7.在DataStreamer将packet写入pipeline时,同时也会将该packet存储到另外一个由ResponseProcessor
线程管理的缓存队列ackqueue确认队列中。ResponseProcessor线程会等待DataNode的确认响应。当收到所
有的DataNode的确认信息后,该线程再将ackqueue里的packet删除;

8.如果写入期间发生故障,会首先关闭pipeline,把ackqueue的所有packet都放回dataqueue的最前端,以
确保故障节点后的节点不会漏掉任一packet。同时,会标识正常的DataNode,方便在故障节点恢复后,删除错
误的部分数据块。然后从管线中删除故障节点,基于新的DataNode构建一个新的管线;

9.在一个block块大小的n个packet数据包写完后,客户端会调用FSDataOutputStream的close方法关闭写入
流,当然在调用close之前,DataNode会将内存中的数据写入本地磁盘;

10.最后DataStreamer会继续向NameNode请求下一个块的DataNode列表,开始下一个块的写入。直到写完整个
文件的最后一个块数据,然后客户端通知 NameNode 把文件标示为已完成,到这里整个写入过程就结束了。

三、优缺点

数据的读写是HDFS的核心和考察重点,下面在结合着总结一下优缺点:

1.优点:

简单一致性模型:一次写入,多次读取,但要注意不能修改,只能追加;
高容错,低成本:可以搭建在廉价的机器上,并且数据以多副本保存在不同的服务器上,某个副本丢失,也能通过别的副本进行恢复;
流式数据访问:不是随机读写;
适合大规模数据集:能够进行批处理,支持横向扩展,支持PB级数据和10k节点规模。

2.缺点:

延迟高:不支持低延迟数据访问,做不到毫秒级存储数据,但是适合高吞吐率(某一时间内写入大量的数据)的场景;
不适合小文件:每条元数据占用空间是一定的,因此大量小文件会占用NameNode大量的内存来存储文件、目录和块信息;
不支持并发写入:一个文件只允许一个线程进行写操作,不适合并发写入;
不能修改和随机读写:文件不允许修改,只支持追加,同时也不是随机读写。