首页IT科技hdfs -du(04HDFS简介)

hdfs -du(04HDFS简介)

时间2025-08-02 09:02:39分类IT科技浏览6274
导读:HDFS简介 一、什么是HDFS...

HDFS简介

一                、什么是HDFS

HDFS全称是Hadoop Distributed File System                ,简称HDFS                。这是一个分布式文件系统                        ,当数据规模大小超过一台物理计算机的存储能力时        ,就有必要进行分区并存储到若干台物理计算机上                        。管理网络中跨多台计算机的文件系统称为分布式文件系统        。

Hadoop的文件系统是一个抽象的概念            ,java的抽象类是org.apache.hadoop.fs.FileSystem                        ,在创建一个FileSystem的时候            ,FileSystem使用文件系统URI的Schema作为查询配置或者SPI寻找实现类(类似JDBC)            。FileSystem有很多实现        ,HDFS只是其中的一个实现                        ,它的实现类是org.apache.hadoop.hdfs.DistributedFileSystem                ,它的URI schema为hdfs                        。Hadoop默认配置的文件系统实现是org.apache.hadoop.fs.LocalFileSystem    ,URI schema为file                        ,用于管理本地文件            。

二                        、HDFS的基础概念

1        、数据块

块设备(例如硬盘)一般会有一个默认块大小                    ,这是设备读写的最小单位,这类设备的块大小一般为几千字节        。HDFS同样有块的概念                    ,默认情况下HDFS的块大小为128MB                        。但是与硬盘的文件系统不一样                        ,当文件小于HDFS的块大小时    ,不会占用整个块的空间                ,例如一个1MB大小的文件只占用了1MB的空间                        ,而不是128MB                。HDFS的块比硬盘的大是为了最小化寻址开销        ,如果块足够大            ,从磁盘传输数据的时间会明显大于定位这个块位置需要的时间                        ,所以传输一个大文件的时间取决于磁盘传输速率    。

使用块来管理分布式文件系统有很多好处            ,例如一个文件可以大于某个物理设备的容量        ,文件并不需要存储在一个物理设备上                        。另一个好处是块可以存储在多个节点上                        ,防止某个设备因为故障而丢失数据                    。

2            、namenode和datanode

HDFS集群有两种节点                ,分别是namenode和datanode。以管理节点——工作节点方式对外提供服务    ,即client连接namenode                        ,一个namenode节点负责管理多个datanode                    。

namenode负责管理文件系统的命名空间                    ,它维护文件系统元数据信息,例如目录和文件名称                        。这些信息以文件的形式永久保存在硬盘上:分别是命令空间镜像文件和编辑日志文件    。namenode也记录每个文件的块所在的数据节点信息                    ,但它并不永久保存块的位置                        ,这些信息会在启动的时候根据数据节点的数据重建                。

datanode就是文件系统的工作节点                        。它们根据需要存储数据块信息    ,并且定期向namenode发送所存储的块列表        。HDFS通过把数据块冗余到多个datanode实现数据的安全性                ,默认副本数量为3            。

namenode对外提供服务的时候需要把所有的文件元数据加载到内存                        ,重启的时候会利用镜像文件和编辑日志重建数据        ,镜像文件类似于Redis的rdb文件                        。namenode会周期性归档编辑日志来生成一个更加新的镜像文件            ,由于归档编辑日志的时候namenode也会对外提供服务                        ,这段时间的操作会写入到编辑日志中            ,所以namenode需要镜像文件和编辑日志一起重建文件元数据            。一个大规模的HDFS的恢复是非常消耗时间的(取决于所管理的数据规模)        ,由于namenode是管理节点                        ,没有namenode整个文件系统将无法使用                ,所以相对datanode    ,namenode的高可用非常重要        。本节主要为对HDFS简单介绍                        ,故先不讨论HDFS的高可用方案                        。

3                        、联邦HDFS

由于namenode在内存中维护系统内文件和数据块的关系                    ,很明显namenode运行机器的内存会限制整个集群能存储的文件数量                。Hadoop在2.x版本引入的联邦namenode,在联邦环境下                    ,每个namenode管理一个命名空间的一部分    。例如一个namenode管理/a目录下的所有文件                        ,另一个namenode管理/b目录下的所有文件                        。在联邦环境下    ,每个namenode是独立的                ,其中一个namenode失效了也不会影响其他namenode                    。

三            、hadoop命令行

Hadoop命令行的fs参数提供了一些方便访问文件系统的操作                        ,所有的参数和格式可以在官网文档FileSystemShell中查询到        ,这里简单列举一些常用的操作。

-cat:读取文件            ,并且输出到标准输出

格式:hadoop fs -cat [-ignoreCrc] URI [URI ...]

例如:

打印本地文件系统下的text.txt内容

hadoop fs -cat file:///D:/test.txt

打印hdfs上根目录下的a.txt内容

hadoop fs -cat hdfs://192.168.73.130:8082/a.txt -ls:列出路径下的文件内容

格式:hadoop fs -ls URI

例如:

列出hdfs上根目录的文件内容

hadoop fs -ls hdfs://192.168.73.130:8082/

输出每一列含义为:权限                        ,副本数            ,所属用户        ,所属用户组                        ,文件大小                ,修改时间    ,文件名                    。权限字段由有7个标识位                        ,第一个标识位含义是文件类型                    ,如果是目录则为d,然后紧跟的6个标识位表示所属用户        、所属用户组                        、其他用户的是否可读                、可写    、可执行                    ,可执行权限可以忽略                        ,因为不能在HDFS中执行                        。第二列为副本数    ,目录的元数据保存在namenode上                ,所以没有副本数    。

示例输入如下:

hadoop fs -ls hdfs://192.168.73.130:8082/ Found 2 items -rw-r--r-- 3 debian supergroup 19481 2023-01-25 15:30 hdfs://192.168.73.130:8082/a.txt drwxr-xr-x - debian supergroup 0 2023-01-28 09:08 hdfs://192.168.73.130:8082/test -copyFromLocal:复制本地文件到HDFS

格式:hadoop fs -copyFromLocal localsrc URI

例如:

把本地的文件a.txt复制到HDFS的/testDir/a.txt上

hadoop fs -copyFromLocal a.txt hdfs://192.168.73.130:8082/testDir/a.txt -copyToLocal:复制HDFS文件到本地

格式:hadoop fs -copyToLocal URI localsrc

例如:

把HDFS的/testDir/a.txt复制到本地

hadoop fs -copyToLocal hdfs://localhost:8082/testDir/a.txt a.txt

四                        、FileSystem常用api

1                    、文件的读取

使用方法FileSystem#open()可以打开一个FSDataInputStream输入流                        ,然后可以像读取本地文件一样文件中的数据                。但是与一般的输入流不一样        ,FSDataInputStream实现了Seekable和接口PositionedReadable            ,它们分别支持随机读取和指定位置读取                        。

Seekable的声明如下:

public interface Seekable { /** * 设置下一次读取的时                        ,使用的偏移量 */ void seek(long pos) throws IOException; /** * 返回当前读取偏移量 */ long getPos() throws IOException; }

getPos返回当前读取偏移量            ,seek设置下一次read的偏移量        ,偏移量是当前距离文件起始位置的字节数        。例如可以用如下代码重复读取文件开头的2048个字节;

FSDataInputStream in = .....; byte[] buff = new buff[2048]; in.read(buff); in.seek(0); in.read(buff);

seek使用起来很方便                        ,但是是一个相对高开销的操作                ,需要慎重使用            。

PositionedReadable的声明如下:

public interface PositionedReadable { /** * 从position指定的位置开始读取length个长度的数据    ,复制到buffer的offset处                        ,返回实际读取到的字节数 */ int read(long position, byte[] buffer, int offset, int length) throws IOException; /** * 从position指定的位置开始读取length个长度的数据                    ,复制到buffer的offset处 * 如果到达文件结尾抛出EOFException */ void readFully(long position, byte[] buffer, int offset, int length) throws IOException; /** * 从position指定的位置开始读取buffer.length个长度的数据,复制到buffer的offset处 * 如果到达文件结尾抛出EOFException */ void readFully(long position, byte[] buffer) throws IOException; }

read函数把指定偏移量数据读取到buffer中                    ,但是实际读取的字节数需要调用者接受返回值进行判断                        。readFully效果也类似                        ,但是如果到达文件结尾会抛出EOFException            。PositionedReadable所有的方法都不会改变当前流读取文件的位置    ,同时它的方法也都是线程安全的        。

2、文件的写入

传入一个Path对象                ,然后使用FileSystem#create可以创建一个新文件                        ,并且返回一个FSDataOutputStream对象                        。与java其他的api不一样        ,调用create方法会自动创建父级目录                。

使用FileSystem#append()可以向一个已存在的文件尾追加内容            ,需要说明的是这个方法是一个可选的实现                        ,并不是每一个文件系统都正常此方法    。

3                    、目录创建

调用FileSystem#mkdirs()方法可以新建一个目录            ,通常创建文件不需要显示调用此方法        ,因为创建文件会自动创建对应的父级目录                        。

4                        、文件的删除

调用FileSystem#delete()可以删除一个文件或者目录                    。

5    、文件元数据信息

使用FileSystem#getFileStatus方法可以返回一个FileStatus对象来获取文件或者目录的的状态信息                        ,例如是否为目录                、权限                        、文件长度等数据。

FileSystem#listStatus可以列出目录下所有的文件信息                    。listStatus有多个重载方法                ,可以额外传入一个org.apache.hadoop.fs.PathFilter用来过滤目录的文件                        。

6        、HDFS的一致性模型

对于创建一个目录    ,HDFS可以保证操作是立即可见的    。但是对于写入数据并不能保证其可见性                。例如对于以下一段Java程序代码:

OutputStream out = ...; out.write(buff); out.flush();

如果是操作本地文件                        ,调用flush方法                    ,会把缓冲区数据刷新到硬盘上,保证其可见性                        。然而对于HDFS                    ,即使调用了flush方法也不能保证可见性                        ,需要等到数据超过一个块之后才能对其他读取进程可见        。但是HDFS的实现提供了两个方法用于保证可见性    ,分别是FSDataOutputStream#hflushFSDataOutputStream#hsync                ,hsync和操作系统的sync方法类似                        ,保证数据已经存储在datanode的硬盘上        ,而hflush仅仅保证数据写入到datanode的内存            。调用close关闭流会自动调用一次hflush                        。

五            、demo程序

我使用FileSystem常用api实现了一个客户端demo            ,代码地址在github 的hdfsApiExample模块                        ,打包此模块可以得到一个hdfs-api-example-1.0-SNAPSHOT.jar的文件            ,它的使用方法如下:

参数:

fs:指定hdfs的namenode地址        ,假设你有一个namenode地址是hdfs://192.168.73.130:8082 u:操作hdfs的用户                        ,根据hdfs配置情况                ,写入的时候可能需要这个参数 o:实际需要执行的命令    ,分别支持ls(查询目录文件)                        ,rm(删除)                    ,mkdir(创建目录),cp(复制文件)

示例:

列出hdfs上                    ,根目录的文件

hadoop jar hdfs-api-example-1.0-SNAPSHOT.jar -fs hdfs://192.168.73.130:8082 -u debian -o ls /

删除hdfs上                        ,/cnblog目录            。使用额外的r参数递归删除非空目录

hadoop jar hdfs-api-example-1.0-SNAPSHOT.jar -fs hdfs://192.168.73.130:8082 -u debian -o rm r /cnblog

在根目录下创建一个cnblog目录

hadoop jar hdfs-api-example-1.0-SNAPSHOT.jar -fs hdfs://192.168.73.130:8082 -u debian -o mkdir /cnblog

复制本地文件test.txt到hdfs的根目录上

hadoop jar hdfs-api-example-1.0-SNAPSHOT.jar -fs hdfs://192.168.73.130:8082 -u debian -o cp text.txt hdfs:/test.text

复制hdfs的根目录文件text.txt到本地目录上

hadoop jar hdfs-api-example-1.0-SNAPSHOT.jar -fs hdfs://192.168.73.130:8082 -u debian -o cp hdfs:/test.text text.txt

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
如何在python中输入若干个整数(python从键盘输入若干个整数) 网创项目(有什么可以网创的吗-网创界到底有多少年赚百万的人)