HDFS即Hadoop分布式文件系统(Hadoop Distributed Filesystem),以流式数据访问模式来存储超大文件,运行于商用硬件集群上,是管理网络中跨多台计算机存储的文件系统。
优点:
高容错性
数据自动保存多个副本
副本丢失后,自动恢复
适合批处理
移动计算,而非数据
数据位置暴露给计算框架
适合大数据处理
GB、TB、甚至PB级数据
百万规模以上的文件数量
10K+节点规模
流式文件访问
一次写入多次读取
保持数据的一致性
可构建在廉价机器上
通过多副本提高可靠性
提供了容错和恢复机制
缺点:不适合
低延迟数据访问
比如毫秒级
小文件存取
占用NameNode大量内存
寻道时间超过读取时间
并发写入、文件随机修改
一个文件只能有一个写者
仅支持append
命令 说明 示例
-mkdir 在HDFS上创建目录 在HDFS上创建目录/data
hdfs dfs -mkdir /data
在HDFS上级联创建目录/data/input
hdfs dfs -mkdir -p /data/input
-ls 列出hdfs文件系统根目录下的目录和文件 查看HDFS根目录下的文件和目录
hdfs dfs -ls /
查看HDFS的/data目录下的文件和目录
hdfs dfs -ls /data
-ls -R 列出hdfs文件系统所有的目录和文件 查看HDFS根目录及其子目录下的文件和目录
hdfs dfs -ls -R /
-put 上传文件或者从键盘输入字符到HDFS 将本地Linux的文件data.txt上传到HDFS
hdfs dfs -put data.txt /data/input
从键盘输入字符保存到HDFS的文件
hdfs dfs -put - /aaa.txt
-moveFromLocal 与put相类似,命令执行后源文件 local src 被删除,也可以从从键盘读取输入到hdfs file中
hdfs dfs -moveFromLocal data.txt /data/input
-copyFromLocal 与put相类似,也可以从从键盘读取输入到hdfs file中 hdfs dfs -
copyFromLocal data.txt /data/input
-get 将HDFS中的文件被复制到本地
hdfs dfs -get /data/inputdata.txt /root/
-rm 每次可以删除多个文件或目录
hdfs dfs -rm < hdfs file > ... 删除多个文件
hdfs dfs -rm -r < hdfs dir>... 删除多个目录
-getmerge 将hdfs指定目录下所有文件排序后合并到local指定的文件中,文件不存在时会自动创建,文件存在时会覆盖里面的内容 将HDFS上/data/input目录下的所有文件,合并到本地的a.txt文件中
hdfs dfs -getmerge /data/input /root/a.txt
-cp 拷贝HDFS上的文件
-mv 移动HDFS上的文件
-count 统计hdfs对应路径下的目录个数,文件个数,文件总计大小
显示为目录个数,文件个数,文件总计大小,输入路径
-du 显示hdfs对应路径下每个文件夹和文件的大小
hdfs dfs -du /
-text、-cat 将文本文件或某些格式的非文本文件通过文本格式输出
balancer 如果管理员发现某些DataNode保存数据过多,某些DataNode保存数据相对较少,可以使用上述命令手动启动内部的均衡过程
在HDFS上创建目录
// 在HDFS上创建目录
public static void createPath(Configuration conf) throws Exception {
// 获取客户端
FileSystem fs = FileSystem.get(conf);
// 创建目录
boolean flag = fs.mkdirs(new Path("/demo1"));
System.out.println("创建---------" + flag);
}
通过FileSystem API读取数据(下载文件)
// 通过FileSystem API读取数据(下载文件)
public static void downFile(Configuration conf) throws Exception {
// 获取客户端
FileSystem fs = FileSystem.get(conf);
// 构建一个输入流
FSDataInputStream inputStream = fs.open(new Path("/demo/a.txt"));
// 构建一个输出流
OutputStream outputStream = new FileOutputStream("D:\\demo\\a.txt");
IOUtils.copyBytes(inputStream, outputStream, 1024);
}
写入数据(上传文件)
// 写入数据(上传文件)
public static void uploadFile(Configuration conf) throws Exception {
// 获取客户端
FileSystem fs = FileSystem.get(conf);
// 构建一个输入流
InputStream inputStream = new FileInputStream("D:\\\\demo\\\\a.txt");
// 构建一个输出流
FSDataOutputStream outputStream = fs.create(new Path("/demo/b.txt"));
IOUtils.copyBytes(inputStream, outputStream, 1024);
}
查看目录及文件信息
// 查看目录及文件信息
public static void getFileInfo(Configuration conf) throws Exception {
// 获取客户端
FileSystem fs = FileSystem.get(conf);
//获取某目录下file的状态信息
FileStatus[] fileStatus = fs.listStatus(new Path("/demo"));
for (FileStatus file : fileStatus) {
String dir=file.isDirectory()?"目录":"文件";
String name=file.getPath().getName();
String path=file.getPath().toString();
System.out.println(dir+"-----"+name+"------"+path);
System.out.println(file.getAccessTime());
System.out.println(file.getBlockSize());
System.out.println(file.getGroup());
System.out.println(file.getLen());
System.out.println(file.getOwner());
}
}
查找某个文件在HDFS集群的位置
//查找某个文件在HDFS集群的位置
public static void findFileBlockLocation(Configuration conf) throws Exception {
// 获取客户端
FileSystem fs = FileSystem.get(conf);
//得到文件
FileStatus fileStatus= fs.getFileStatus(new Path("/demo/a.txt"));
//获取到文件数据块位置,是一个数组
BlockLocation[] blockLocations=fs.getFileBlockLocations(fileStatus, 0, fileStatus.getLen());
for (BlockLocation block : blockLocations) {
System.out.println(Arrays.toString(block.getHosts())+
"\t"+Arrays.toString(block.getNames()));
}
}