Hadoop权威指南---HDFS简介和java API操作

目录

1、HDFS的设计

2、 HDFS的概念 

2.1 数据块 

2.2 namenode和datanode 概述

2.3 块缓存 

​2.4 联邦HDFS 

2.5 HDFS的高可用性 

3、 命令行接口

4、 Hadoop文件系统分类

5、Java接口API

5.1、增:创建文件create和write、文件夹mkdirs

5.2、删:删除文件夹和文件delete

5.3、改:追加append

5.4、查:查看文件和文件夹open和read

5.4.1、获取文件的元数据信息listFiles、listStatus以及globStatus

5.4.2、获取文件的数据信息open和read

5.5、其他的一些常见操作

5.5.1、重命名rename

5.5.2、文件的上传

5.5.3、文件的下载

5.6、HDFS文件的流式处理

6、 数据流(重点)

6.1 剖析文件读取流程

6.2 剖析文件写入流程

6.3 数据一致模型 

7、 通过distcp并行复制 


Hadoop分布式文件系统 

1、HDFS的设计

HDFS的特点

  • 超大文件,目前已经有PB级数据的Hadoop集群;
  • 流式数据访问,一次写入、多次读取;
  • 运作在普通的硬件上;
  • 不适合底时间延迟的数据访问,hbase基于内存的数据库,可以满足低延时的访问;
  • 不适合大量的小文件,namenode的限制;
  • 只支持单用户写入,而且不支持修改,支持在文件的末尾追加;

2、 HDFS的概念 

2.1 数据块 

一般情况下,块的大小,太大或者太小都不好;

使用块结果存储数据的三个好处:

  • 文件的大小不在局限于磁盘的大小,把大文件拆分成块,分别进行存储;
  • 文件的元数据信息和数据信息分开管理;
  • 块数据更加容易实现容错和可用性;

2.2 namenode和datanode 概述

 

2.3 块缓存 


2.4 联邦HDFS 

2.5 HDFS的高可用性 

Hadoop2的HA是通过一个active namenode节点、一个standby namenode节点和一个共享编辑日志的文件系统(常用的是zookeeper)来实现的。这里的standby namenode节点还具有之前secondary namenode节点定期合并镜像和编辑日志的功能。

同时需要注意在切换的时候需要保证只有一个节点作为主节点在对外提供服务,避免同时出现两个namenode编辑日志,也就是规避,避免“脑裂”---多主的情况;

恢复命名空间的流程:

3、 命令行接口

Hadoop常见的shell命令

Hadoop fs 参数   路径

4、 Hadoop文件系统分类

5、Java接口API

hdfs的java API常见操作归类
对文件的增删改查(注意:HDFS的文件不能修改,而只能在现有的文件中追加或者新建文件)DistributedFileSystem类的方法

5.1、增:创建文件create和write、文件夹mkdirs

FSDataOutputStream create(Path f)

 

 

 

 

5.2、删:删除文件夹和文件delete

delete方法可以用来递归删除某个目录下的文件信息,因此path可以是具体的文件路径或者目录路径
boolean delete(Path f, boolean recursive)
如果f是一个文件或者空目录,那么recursive的值就会被忽略;只有recursive值为true时,非空目录及其内容才会被删除。

5.3、改:追加append

FSDataOutputStream append(Path f)
FSDataOutputStream append(Path f, int bufferSize)
FSDataOutputStream append(Path var1, int var2, Progressable var3)

 

5.4、查:查看文件和文件夹open和read

这里分两部分:获取文件的元数据信息和获取文件的数据信息

5.4.1、获取文件的元数据信息listFiles、listStatus以及globStatus

文件元数据的封装类FileStatus
public class FileStatus implements Writable, Comparable {
    private Path path;  路径
    private long length;   长度
    private boolean isdir;    是不是目录
    private short block_replication;  文件块的备份数
    private long blocksize;     文件块的大小
    private long modification_time;  修改时间
    private long access_time;      访问时间???
    private FsPermission permission;   权限
    private String owner;   所属者
    private String group;   所属组
    private Path symlink;    文件类型,判断是不是链接的文件类型
...	
}


其中LocatedFileStatus在FileStatus基础上扩展了一个字段locations,用于描述该文件的数据块的存储位置
public class LocatedFileStatus extends FileStatus {
    private BlockLocation[] locations;  文件的数据块的存储位置
...	
}


public class BlockLocation {
    private String[] hosts;        block所在的服务器
    private String[] cachedHosts;  block的cachehosts
    private String[] names;        块的名字
    private String[] topologyPaths;
    private long offset;           文件开始偏移量
    private long length;        打印block的大小
    private boolean corrupt;
    private static final String[] EMPTY_STR_ARRAY = new String[0];
...	
}


只列出路径下的文件而不列出文件夹listFiles
RemoteIterator<LocatedFileStatus> listFiles(final Path f, final boolean recursive)  

即列出文件又列出文件夹listStatus
FileStatus[] listStatus(Path var1)
FileStatus[] listStatus(Path f, PathFilter filter)
FileStatus[] listStatus(Path[] files)
FileStatus[] listStatus(Path[] files, PathFilter filter)


通过通配符(正则表达式)来匹配路径globStatus
FileStatus[] globStatus(Path pathPattern)
FileStatus[] globStatus(Path pathPattern, PathFilter filter)
    
    
PathFilter 是用来限制匹配的文件和目录
public interface PathFilter {
    boolean accept(Path var1);
}
通过实现这个接口,开自定义排除指定路径

demo1:listFiles实例

/**
	 为什么使用RemoteIterator<LocatedFileStatus>,这是一个远程的迭代器,由于HDFS服务器数据量比较多,
	 不能一次性返回所有文件信息(可能撑爆内存),所以一边迭代一边从远程服务器上获取。分治的思想。
	 */
	//打印文件列表
	public static void listfiles(FileSystem fileSystem) throws Exception, IOException {
		RemoteIterator<LocatedFileStatus> fileLists = fileSystem.listFiles(new Path("/"), true);
		while (fileLists.hasNext()) {
			LocatedFileStatus locatedFileStatus = fileLists.next();
			// 按照以下格式打印HDFS上的文件信息
			// drwxr-xr-x   - root supergroup          0 2015-12-18 00:24 /itcast/hadoop

			String fileType = "-";
			System.out.print(fileType);//但因文件的类型

			String authority = locatedFileStatus.getPermission().toString();
			System.out.print(authority + "\t");//打印文件的权限

			String user = locatedFileStatus.getOwner();
			System.out.print(user + "\t");//打印文件所属的的用户

			long size = locatedFileStatus.getLen();
			System.out.print(size + "\t");//打印文件的大小

			long date = locatedFileStatus.getModificationTime();
			System.out.print(date + "\t");//打印文件的时间戳

			String path = locatedFileStatus.getPath().toString();
			System.out.print(path + "\t");//打印文件的路径

			System.out.println();

			for (BlockLocation blockLocation : locatedFileStatus.getBlockLocations()) {
				System.out.print("cacheHosts: ");
				for (String hosts : blockLocation.getCachedHosts()) {
					System.out.print(hosts + ",");//打印block的cachehosts
				}
				System.out.println();

				System.out.print("hosts: ");
				for (String hosts : blockLocation.getHosts()) {
					System.out.print(hosts + ",");//打印文件block所在的服务器
				}
				System.out.println();

				System.out.print("block size: ");
				System.out.println(blockLocation.getLength());//打印block的大小

				System.out.print("block start offset: ");
				System.out.println(blockLocation.getOffset()); //文件开始偏移量

				System.out.println("----------------------------------------------");

			}

		}
	}

 

demo2:listStatus实例

//查看HDFS的所有文件信息(使用递归算法)
	public static void fileAll(FileSystem fileSystem) throws Exception {
		printContent(fileSystem,new Path("/"));
	}

	public  static void printContent(FileSystem fileSystem,Path path) throws Exception {
		FileStatus[] fileStatuses = fileSystem.listStatus(path);
		for (FileStatus fileStatus : fileStatuses) {
			String fileType = "d";
			if (fileStatus.isFile()) {
				fileType = "-";
			} else if (fileStatus.isSymlink()) {
				fileType = "l";
			}
			System.out.println(fileType + fileStatus.getPermission() + "\t" + fileStatus.getOwner() + "\t" + fileStatus.getLen() + "\t" + fileStatus.getModificationTime() + "\t" + fileStatus.getPath());
			if (fileStatus.isDirectory()) {
				printContent(fileSystem, fileStatus.getPath());
			}
		}
	}

5.4.2、获取文件的数据信息open和read

5.5、其他的一些常见操作

5.5.1、重命名rename

rename方法可以用来移动文件,也可以用来重命名文件。
boolean rename(Path var1, Path var2)

5.5.2、文件的上传

void copyFromLocalFile(Path src, Path dst)   本地文件上传到HDFS

5.5.3、文件的下载

void copyToLocalFile(boolean delSrc, Path src, Path dst, boolean useRawLocalFileSystem)   把HDFS上的文件下载到本地
四个参数的含义分别是:是否删除HDFS集群下的原始文件、HDFS文件地址、本地文件地址、是否使用原生进行操作。

5.6、HDFS文件的流式处理

直接从输入流往输出流写数据,借助于工具类实现

6、 数据流(重点)

6.1 剖析文件读取流程

 

 通过网络节点的拓扑结构,可以快速判断哪个datanode节点是距离客户端最近的节点,然后读取数据信息。

 

6.2 剖析文件写入流程

6.3 数据一致模型 

 

 

 

7、 通过distcp并行复制 

参考:

《Hadoop权威指南.大数据的存储与分析.第4版》---第3章 Hadoop分布式文件系统

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值