目录
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分布式文件系统
HDFS的特点
一般情况下,块的大小,太大或者太小都不好;
使用块结果存储数据的三个好处:
Hadoop2的HA是通过一个active namenode节点、一个standby namenode节点和一个共享编辑日志的文件系统(常用的是zookeeper)来实现的。这里的standby namenode节点还具有之前secondary namenode节点定期合并镜像和编辑日志的功能。
同时需要注意在切换的时候需要保证只有一个节点作为主节点在对外提供服务,避免同时出现两个namenode编辑日志,也就是规避,避免“脑裂”---多主的情况;
恢复命名空间的流程:
Hadoop常见的shell命令
Hadoop fs 参数 路径
hdfs的java API常见操作归类
对文件的增删改查(注意:HDFS的文件不能修改,而只能在现有的文件中追加或者新建文件)DistributedFileSystem类的方法
FSDataOutputStream create(Path f)
delete方法可以用来递归删除某个目录下的文件信息,因此path可以是具体的文件路径或者目录路径
boolean delete(Path f, boolean recursive)
如果f是一个文件或者空目录,那么recursive的值就会被忽略;只有recursive值为true时,非空目录及其内容才会被删除。
FSDataOutputStream append(Path f)
FSDataOutputStream append(Path f, int bufferSize)
FSDataOutputStream append(Path var1, int var2, Progressable var3)
这里分两部分:获取文件的元数据信息和获取文件的数据信息
文件元数据的封装类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
即列出文件又列出文件夹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,这是一个远程的迭代器,由于HDFS服务器数据量比较多,
不能一次性返回所有文件信息(可能撑爆内存),所以一边迭代一边从远程服务器上获取。分治的思想。
*/
//打印文件列表
public static void listfiles(FileSystem fileSystem) throws Exception, IOException {
RemoteIterator 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());
}
}
}
rename方法可以用来移动文件,也可以用来重命名文件。
boolean rename(Path var1, Path var2)
void copyFromLocalFile(Path src, Path dst) 本地文件上传到HDFS
void copyToLocalFile(boolean delSrc, Path src, Path dst, boolean useRawLocalFileSystem) 把HDFS上的文件下载到本地
四个参数的含义分别是:是否删除HDFS集群下的原始文件、HDFS文件地址、本地文件地址、是否使用原生进行操作。
直接从输入流往输出流写数据,借助于工具类实现
通过网络节点的拓扑结构,可以快速判断哪个datanode节点是距离客户端最近的节点,然后读取数据信息。
参考:
《Hadoop权威指南.大数据的存储与分析.第4版》---第3章 Hadoop分布式文件系统