//IO流 操作HDFS 参考之前博客IO流文章末尾hadoop IO流操作
//上传文件
@Test public void putFileToHDFS() throws IOException, InterruptedException, URISyntaxException { // 1 获取文件系统 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI("hdfs://linux121:9000"), configuration, "root"); // 2 创建输入流 FileInputStream fis = new FileInputStream(new File("e:/lagou.txt")); // 3 获取输出流 FSDataOutputStream fos = fs.create(new Path("/lagou_io.txt")); // 4 流对拷 IOUtils.copyBytes(fis, fos, configuration); // 5 关闭资源 IOUtils.closeStream(fos); IOUtils.closeStream(fis); fs.close(); }
//下载文件
// 文件下载 @Test public void getFileFromHDFS() throws IOException, InterruptedException, URISyntaxException{ // 1 获取文件系统 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI("hdfs://linux121:9000"), configuration, "root"); // 2 获取输入流 FSDataInputStream fis = fs.open(new Path("/lagou_io.txt")); // 3 获取输出流 FileOutputStream fos = new FileOutputStream(new File("e:/lagou_io_copy.txt")); // 4 流的对拷 IOUtils.copyBytes(fis, fos, configuration); // 5 关闭资源 IOUtils.closeStream(fos); IOUtils.closeStream(fis); fs.close(); }
//seek 定位读取
@Test public void readFileSeek2() throws IOException, InterruptedException, URISyntaxException{ // 1 获取文件系统 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI("hdfs://linux121:9000"), configuration, "root"); // 2 打开输入流,读取数据输出到控制台 FSDataInputStream in = null; try{ in= fs.open(new Path("/lagou.txt")); IOUtils.copyBytes(in, System.out, 4096, false); in.seek(0); //从头再次读取 IOUtils.copyBytes(in, System.out, 4096, false); }finally { IOUtils.closeStream(in); } }
//文件以及文件夹判断 @Test public void isFile() throws URISyntaxException, IOException, InterruptedException {final FileStatus[] fileStatuses = fs.listStatus(new Path("/")); for (FileStatus fileStatus : fileStatuses) { final boolean flag = fileStatus.isFile(); if (flag) { System.out.println("文件:" + fileStatus.getPath().getName()); } else { System.out.println("文件夹:" + fileStatus.getPath().getName()); } } }
HDFS下载数据流程:
1.客户端请求 namenode 需要下载文件,namenode检查权限和路径,返回文件的所有块信息
2.客户端根据节点距离最近,找到最近的存储第一块数据的节点,建立连接,读取数据
3.读取数据是以packet为单位,每个packet 64kb
HDFS写文件流程:
1.客户端请求namenode需要上传文件,namenod检查权限和路径
2.客户端创建FileSystem对象,客户端对单个文件进行切块,客户端请求namenode需要上传第一块
3.namenode 返回节点距离最近的节点,另一个机架的随机节点,第二个节点所在机架的随机节点
4.客户端与namenode返回的第一个节点建立连接,传数据也是以packet为单位,每次传数据packet会被同步放入确认队列
NameNode 元数据存储: 内存+磁盘
镜像文件fsimage +日志文件 edits
服务器开机 将镜像文件和edits plus 加载到内存
服务器关机 镜像文件和edits plus文件合并
2nn 将镜像文件和edits 定期(默认一个小时)合并,或者达到100万次修改合并
合并的流程:
1.创建新的edits plus 文件,用于记录新的操作流程
2.根据旧的edits plus 文件和fsimage 合并 生成新的fsimage
3.覆盖原来的fsimage
HDFS文件限额配置:
1.数量限额
hdfs dfs -mkdir -p /user/root/lagou #创建hdfs文件夹 hdfs dfsadmin -setQuota 2 /user/root/lagou # 给该文件夹下面设置最多上传两 个文件,上传文件,发现只能上传一个文件 hdfs dfsadmin -clrQuota /user/root/lagou # 清除文件数量限制
2.空间大小限额
hdfs dfsadmin -setSpaceQuota 4k /user/root/lagou # 限制空间大小4KB #上传超过4Kb的文件大小上去提示文件超过限额 hdfs dfs -put /export/softwares/xxx.tar.gz /user/root/lagou hdfs dfsadmin -clrSpaceQuota /user/root/lagou #清除空间限额 #查看hdfs文件限额数量 hdfs dfs -count -q -h /user/root/lagou
hdfs 归档技术 解决namenode 内存资源浪费. 一个文件的元数据占用150个字节.
归档:
bin/hadoop archive -archiveName input.har –p
/user/root/input /user/root/output
查看归档:
hadoop fs -lsr har:///user/root/output/input.har
解压归档:
hadoop fs -cp har:/// user/root/output/input.har/* /user/root