Hadoop第二天
1. HDFS的java客户端
1.1. 解决log4j错误警告
log4j.rootLogger=INFO, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n log4j.appender.logfile=org.apache.log4j.FileAppender log4j.appender.logfile.File=target/spring.log log4j.appender.logfile.layout=org.apache.log4j.PatternLayout log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
|
1.2. 参数的优先级别
客户端代码-->工具设置参数-->服务器默认参数
工具设置参数:
配置文件设置方式:
1.3. 抽取公共代码
public class HdfsClient {
FileSystem fs =null;
@Before public void init() throws Exception{ //获取文件系统 Configuration configuration = new Configuration(); //配置连接的集群 configuration.set("fs.defaultFS","hdfs://hadoop01:9000");
//通过配置获取文件系统 fs = FileSystem.get(new URI("hdfs://hadoop01:9000"),configuration,"root"); //fs = FileSystem.newInstance(new URI("hdfs://hadoop01:9000"),configuration,"root");
}
@Test public void testMkdir() throws Exception{ //创建目录 fs.mkdirs(new Path("/cc"));
}
@After public void close() throws Exception{
//关闭fs fs.close(); }
}
|
1.4. 上传文件
/** * 上传文件 * @throws Exception */ @Test public void testUpload() throws Exception{ //上传文件 fs.copyFromLocalFile(new Path("C:\\Users\\hotdas\\Desktop\\clearLastUpdated.bat"),new Path("hdfs://hadoop01:9000/clearLastUpdated.bat")); System.out.println("上传完毕..."); }
|
1.5. 文件下载
/** * 下载文件 * @throws Exception */ @Test public void testdownload() throws Exception{ /** * 第一个参数: 下载完成后,是否删除原文件 * 第二个参数: 要下载的源文件 * 第三个参数: 下载后的目录文件 * 第四个参数: 是否开启文件较验 */ fs.copyToLocalFile(false,new Path("hdfs://hadoop01:9000/clearLastUpdated.bat"),new Path("C:\\Users\\hotdas\\Desktop\\1.bat"),true); System.out.println("下传完毕..."); }
|
1.6. 删除文件夹
/** * 删除文件夹 * @throws Exception */ @Test public void testDeleteDir() throws Exception{ fs.delete(new Path("hdfs://hadoop01:9000/cc"),true); System.out.println("删除完毕..."); }
|
1.7. 更改文件名称
/** * 更改文件夹名称 * @throws Exception */ @Test public void testReName() throws Exception{ fs.rename(new Path("hdfs://hadoop01:9000/clearLastUpdated.bat"),new Path("hdfs://hadoop01:9000/1.bat")); System.out.println("修改完毕..."); }
|
1.8. 获取文件详情信息
查看文件名称,权限,文件大小,块信息
/** * 获取文件详情信息 * @throws Exception */ @Test public void testReadFileMore() throws Exception{ RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("hdfs://hadoop01:9000/"), true);
while (listFiles.hasNext()){ LocatedFileStatus next = listFiles.next(); //输出文件名称 System.out.println(next.getPath().getName()); //长度 System.out.println(next.getLen()); //权限 System.out.println(next.getPermission()); //组 System.out.println(next.getGroup()); //获取块信息 BlockLocation[] blockLocations = next.getBlockLocations();
for(BlockLocation blockLocation:blockLocations){ //获取主机节点 String[] hosts = blockLocation.getHosts(); for (String host:hosts){ System.out.println(host); } } }
System.out.println("完毕..."); }
|
1.9. 判断是文件或文件夹
/** * 判断是文件或文件夹 */ @Test public void testListStatus() throws Exception{ FileStatus[] fileStatuses = fs.listStatus(new Path("hdfs://hadoop01:9000/")); for(FileStatus fileStatus:fileStatuses){ if (fileStatus.isFile()){ System.out.println("f:"+fileStatus.getPath().getName()); }else { System.out.println("D:"+fileStatus.getPath().getName()); } } }
|
1.10. HDFS的I/O流操作
1.10.1. 文件上传
/** * 使用I/O流上传文件 * @throws Exception */ @Test public void testIOupload() throws Exception{ //创建输入流 FileInputStream fis = new FileInputStream(new File("C:\\Users\\hotdas\\Desktop\\clearLastUpdated.bat"));
//创建输出流 FSDataOutputStream fso = fs.create(new Path("hdfs://hadoop01:9000/aa/bb/cc/clearLastUpdated.bat"));
//流复制 IOUtils.copyBytes(fis,fso,configuration);
//关闭流 IOUtils.closeStream(fis); IOUtils.closeStream(fso);
}
|
1.10.2. 文件下载
/** * 使用I/O流下载文件 * @throws Exception */ @Test public void testIOdownload() throws Exception{ //获取输入流 FSDataInputStream fsi = fs.open(new Path("hdfs://hadoop01:9000/aa/bb/cc/clearLastUpdated.bat")); //获取输出流 FileOutputStream fos = new FileOutputStream(new File("C:\\Users\\hotdas\\Desktop\\b.bat")); //流复制 IOUtils.copyBytes(fsi,fos,configuration);
//关闭流 IOUtils.closeStream(fsi); IOUtils.closeStream(fos);
}
|
1.10.3. 定位文件下载
下载第一块文件:
/** * 分块下载:下载第一块文件 */ @Test public void testDownloadByBlock() throws Exception{ //获取输入流 FSDataInputStream fis = fs.open(new Path("hdfs://hadoop01:9000/hadoop-2.7.2.tar.gz")); //获取输出流 FileOutputStream fos = new FileOutputStream(new File("C:\\Users\\hotdas\\Desktop\\hadoop-2.7.2.tar.gz.part1"));
//定义缓冲区 byte[] buf = new byte[1024];
for (int i=0;i<=1024*128;i++){ fis.read(buf); fos.write(buf); }
//关闭流 IOUtils.closeStream(fis); IOUtils.closeStream(fos);
}
|
读取第二块:
/** * 分块下载:下载第二块文件 */ @Test public void testDownloadByBlock2() throws Exception{ //获取输入流 FSDataInputStream fis = fs.open(new Path("hdfs://hadoop01:9000/hadoop-2.7.2.tar.gz"));
//定义读取位置 fis.seek(1024*1024*128);
//获取输出流 FileOutputStream fos = new FileOutputStream(new File("C:\\Users\\hotdas\\Desktop\\hadoop-2.7.2.tar.gz.part2"));
//复制流 IOUtils.copyBytes(fis,fos,configuration);
//关闭流 IOUtils.closeStream(fis); IOUtils.closeStream(fos);
}
|
在windows下合并文件:
type hadoop-2.7.2.tar.gz.part2 >> hadoop-2.7.2.tar.gz.part1
2. HDFS写数据流程原理
- 客户端通过Distributed FileSystem模块向NameNode请求上传文件,NameNode对文件进行检查.
- NameNode返回可以上传
- Distributed FileSystem对文件分块,请求上传第一块,上传到哪些服务器?
- NameNode向客户端响应可以存储的节点
- 客户端通过FsDataOutputSteam向datanode1请求上传块.
- datanode与客户端建通道来实现上传(dn1,dn2,dn3 分级上传响应给客户端)
- 第一块响应成功后,客户端再上传第二块,反复前面上传操作,直到所有块上传完成.
- 向nameNode响应成功信息,namenode读录成功的元数据(存储列表等信息)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端