本文源码:GitHub·点这里 || GitEE·点这里

一、读写机制

1、数据写入

  • 客户端访问NameNode请求上传文件;
  • NameNode检查目标文件和目录是否已经存在;
  • NameNode响应客户端是否可以上传;
  • 客户端请求NameNode文件块Block01上传服务位置;
  • NameNode响应返回3个DataNode节点;
  • 客户端通过输入流建立DataNode01传输通道;
  • DataNode01调用DataNode02,DataNode02调用DataNode03,通信管道建立完成;
  • DataNode01、DataNode02、DataNode03逐级应答客户端。
  • 客户端向DataNode01上传第一个文件块Block;
  • DataNode01接收后传给DataNode02,DataNode02传给DataNode03;
  • Block01传输完成之后,客户端再次请求NameNode上传第二个文件块;

2、数据读取

  • 客户端通过向NameNode请求下载文件;
  • NameNode查询获取文件元数据并返回;
  • 客户端通过元数据信息获取文件DataNode地址;
  • 就近原则选择一台DataNode服务器,请求读取数据;
  • DataNode传输数据返回给客户端;
  • 客户端以本地处理目标文件;

二、基础API案例

1、基础演示接口

  1. public interface HdfsFileService {
  2. // 创建文件夹
  3. void mkdirs(String path) throws Exception ;
  4. // 文件判断
  5. void isFile(String path) throws Exception ;
  6. // 修改文件名
  7. void reName(String oldFile, String newFile) throws Exception ;
  8. // 文件详情
  9. void fileDetail(String path) throws Exception ;
  10. // 文件上传
  11. void copyFromLocalFile(String local, String path) throws Exception ;
  12. // 拷贝到本地:下载
  13. void copyToLocalFile(String src, String dst) throws Exception ;
  14. // 删除文件夹
  15. void delete(String path) throws Exception ;
  16. // IO流上传
  17. void ioUpload(String path, String local) throws Exception ;
  18. // IO流下载
  19. void ioDown(String path, String local) throws Exception ;
  20. // 分块下载
  21. void blockDown(String path, String local1, String local2) throws Exception ;
  22. }

2、命令API用法

  1. @Service
  2. public class HdfsFileServiceImpl implements HdfsFileService {
  3. @Resource
  4. private HdfsConfig hdfsConfig ;
  5. @Override
  6. public void mkdirs(String path) throws Exception {
  7. // 1、获取文件系统
  8. Configuration configuration = new Configuration();
  9. FileSystem fileSystem = FileSystem.get(new URI(hdfsConfig.getNameNode()),
  10. configuration, "root");
  11. // 2、创建目录
  12. fileSystem.mkdirs(new Path(path));
  13. // 3、关闭资源
  14. fileSystem.close();
  15. }
  16. @Override
  17. public void isFile(String path) throws Exception {
  18. // 1、获取文件系统
  19. Configuration configuration = new Configuration();
  20. FileSystem fileSystem = FileSystem.get(new URI(hdfsConfig.getNameNode()),
  21. configuration, "root");
  22. // 2、判断文件和文件夹
  23. FileStatus[] fileStatuses = fileSystem.listStatus(new Path(path));
  24. for (FileStatus fileStatus : fileStatuses) {
  25. if (fileStatus.isFile()) {
  26. System.out.println("文件:"+fileStatus.getPath().getName());
  27. }else {
  28. System.out.println("文件夹:"+fileStatus.getPath().getName());
  29. }
  30. }
  31. // 3、关闭资源
  32. fileSystem.close();
  33. }
  34. @Override
  35. public void reName(String oldFile, String newFile) throws Exception {
  36. // 1、获取文件系统
  37. Configuration configuration = new Configuration();
  38. FileSystem fileSystem = FileSystem.get(new URI(hdfsConfig.getNameNode()),
  39. configuration, "root");
  40. // 2、修改文件名
  41. fileSystem.rename(new Path(oldFile), new Path(newFile));
  42. // 3、关闭资源
  43. fileSystem.close();
  44. }
  45. @Override
  46. public void fileDetail(String path) throws Exception {
  47. // 1、获取文件系统
  48. Configuration configuration = new Configuration();
  49. FileSystem fileSystem = FileSystem.get(new URI(hdfsConfig.getNameNode()),
  50. configuration, "root");
  51. // 2、读取文件详情
  52. RemoteIterator<LocatedFileStatus> listFiles =
  53. fileSystem.listFiles(new Path(path), true);
  54. while(listFiles.hasNext()){
  55. LocatedFileStatus status = listFiles.next();
  56. System.out.println("文件名:"+status.getPath().getName());
  57. System.out.println("文件长度:"+status.getLen());
  58. System.out.println("文件权限:"+status.getPermission());
  59. System.out.println("所属分组:"+status.getGroup());
  60. // 存储块信息
  61. BlockLocation[] blockLocations = status.getBlockLocations();
  62. for (BlockLocation blockLocation : blockLocations) {
  63. // 块存储的主机节点
  64. String[] hosts = blockLocation.getHosts();
  65. for (String host : hosts) {
  66. System.out.print(host+";");
  67. }
  68. }
  69. System.out.println("==============Next==============");
  70. }
  71. // 3、关闭资源
  72. fileSystem.close();
  73. }
  74. @Override
  75. public void copyFromLocalFile(String local, String path) throws Exception {
  76. // 1、获取文件系统
  77. Configuration configuration = new Configuration();
  78. FileSystem fileSystem = FileSystem.get(new URI(hdfsConfig.getNameNode()),
  79. configuration, "root");
  80. // 2、执行上传操作
  81. fileSystem.copyFromLocalFile(new Path(local), new Path(path));
  82. // 3、关闭资源
  83. fileSystem.close();
  84. }
  85. @Override
  86. public void copyToLocalFile(String src,String dst) throws Exception {
  87. // 1、获取文件系统
  88. Configuration configuration = new Configuration();
  89. FileSystem fileSystem = FileSystem.get(new URI(hdfsConfig.getNameNode()),
  90. configuration, "root");
  91. // 2、执行下载操作
  92. // src 服务器文件路径 ; dst 文件下载到的路径
  93. fileSystem.copyToLocalFile(false, new Path(src), new Path(dst), true);
  94. // 3、关闭资源
  95. fileSystem.close();
  96. }
  97. @Override
  98. public void delete(String path) throws Exception {
  99. // 1、获取文件系统
  100. Configuration configuration = new Configuration();
  101. FileSystem fileSystem = FileSystem.get(new URI(hdfsConfig.getNameNode()),
  102. configuration, "root");
  103. // 2、删除文件或目录 是否递归
  104. fileSystem.delete(new Path(path), true);
  105. // 3、关闭资源
  106. fileSystem.close();
  107. }
  108. @Override
  109. public void ioUpload(String path, String local) throws Exception {
  110. // 1、获取文件系统
  111. Configuration configuration = new Configuration();
  112. FileSystem fileSystem = FileSystem.get(new URI(hdfsConfig.getNameNode()),
  113. configuration, "root");
  114. // 2、输入输出流
  115. FileInputStream fis = new FileInputStream(new File(local));
  116. FSDataOutputStream fos = fileSystem.create(new Path(path));
  117. // 3、流对拷
  118. IOUtils.copyBytes(fis, fos, configuration);
  119. // 4、关闭资源
  120. IOUtils.closeStream(fos);
  121. IOUtils.closeStream(fis);
  122. fileSystem.close();
  123. }
  124. @Override
  125. public void ioDown(String path, String local) throws Exception {
  126. // 1、获取文件系统
  127. Configuration configuration = new Configuration();
  128. FileSystem fileSystem = FileSystem.get(new URI(hdfsConfig.getNameNode()),
  129. configuration, "root");
  130. // 2、输入输出流
  131. FSDataInputStream fis = fileSystem.open(new Path(path));
  132. FileOutputStream fos = new FileOutputStream(new File(local));
  133. // 3、流对拷
  134. IOUtils.copyBytes(fis, fos, configuration);
  135. // 4、关闭资源
  136. IOUtils.closeStream(fos);
  137. IOUtils.closeStream(fis);
  138. fileSystem.close();
  139. }
  140. @Override
  141. public void blockDown(String path,String local1,String local2) throws Exception {
  142. readFileSeek01(path,local1);
  143. readFileSeek02(path,local2);
  144. }
  145. private void readFileSeek01(String path,String local) throws Exception {
  146. // 1、获取文件系统
  147. Configuration configuration = new Configuration();
  148. FileSystem fileSystem = FileSystem.get(new URI(hdfsConfig.getNameNode()),
  149. configuration, "root");
  150. // 2、输入输出流
  151. FSDataInputStream fis = fileSystem.open(new Path(path));
  152. FileOutputStream fos = new FileOutputStream(new File(local));
  153. // 3、部分拷贝
  154. byte[] buf = new byte[1024];
  155. for(int i =0 ; i < 1024 * 128; i++){
  156. fis.read(buf);
  157. fos.write(buf);
  158. }
  159. // 4、关闭资源
  160. IOUtils.closeStream(fos);
  161. IOUtils.closeStream(fis);
  162. fileSystem.close();
  163. }
  164. private void readFileSeek02(String path,String local) throws Exception {
  165. // 1、获取文件系统
  166. Configuration configuration = new Configuration();
  167. FileSystem fileSystem = FileSystem.get(new URI(hdfsConfig.getNameNode()),
  168. configuration, "root");
  169. // 2、输入输出流
  170. FSDataInputStream fis = fileSystem.open(new Path(path));
  171. // 定位输入数据位置
  172. fis.seek(1024*1024*128);
  173. FileOutputStream fos = new FileOutputStream(new File(local));
  174. // 3、流拷贝
  175. IOUtils.copyBytes(fis, fos, configuration);
  176. // 4、关闭资源
  177. IOUtils.closeStream(fos);
  178. IOUtils.closeStream(fis);
  179. fileSystem.close();
  180. }
  181. }

3、合并切割文件

  1. cat hadoop-2.7.2.zip.block1 hadoop-2.7.2.zip.block2 > hadoop.zip

三、机架感知

Hadoop2.7的文档说明

第一个副本和client在一个节点里,如果client不在集群范围内,则这第一个node是随机选取的;第二个副本和第一个副本放在相同的机架上随机选择;第三个副本在不同的机架上随机选择,减少了机架间的写流量,通常可以提高写性能,机架故障的概率远小于节点故障的概率,因此该策略不会影响数据的稳定性。

四、网络拓扑

HDFS写数据的过程中,NameNode会选择距离待上传数据最近距离的DataNode接收数据,基于机架感知,NameNode就可以画出上图所示的datanode网络拓扑图。D1,R1都是交换机,最底层是datanode。

  1. Distance(/D1/R1/N1,/D1/R1/N1)=0 相同的节点
  2. Distance(/D1/R1/N1,/D1/R1/N2)=2 同一机架下的不同节点
  3. Distance(/D1/R1/N1,/D1/R2/N1)=4 同一IDC下的不同datanode
  4. Distance(/D1/R1/N1,/D2/R3/N1)=6 不同IDC下的datanode

五、源代码地址

  1. GitHub·地址
  2. https://github.com/cicadasmile/big-data-parent
  3. GitEE·地址
  4. https://gitee.com/cicadasmile/big-data-parent

推荐阅读:编程体系整理

序号 项目名称 GitHub地址 GitEE地址 推荐指数
01 Java描述设计模式,算法,数据结构 GitHub·点这里 GitEE·点这里 ☆☆☆☆☆
02 Java基础、并发、面向对象、Web开发 GitHub·点这里 GitEE·点这里 ☆☆☆☆
03 SpringCloud微服务基础组件案例详解 GitHub·点这里 GitEE·点这里 ☆☆☆
04 SpringCloud微服务架构实战综合案例 GitHub·点这里 GitEE·点这里 ☆☆☆☆☆
05 SpringBoot框架基础应用入门到进阶 GitHub·点这里 GitEE·点这里 ☆☆☆☆
06 SpringBoot框架整合开发常用中间件 GitHub·点这里 GitEE·点这里 ☆☆☆☆☆
07 数据管理、分布式、架构设计基础案例 GitHub·点这里 GitEE·点这里 ☆☆☆☆☆
08 大数据系列、存储、组件、计算等框架 GitHub·点这里 GitEE·点这里 ☆☆☆☆☆

Hadoop框架:HDFS读写机制与API详解的更多相关文章

  1. 大数据学习笔记——Spark工作机制以及API详解

    Spark工作机制以及API详解 本篇文章将会承接上篇关于如何部署Spark分布式集群的博客,会先对RDD编程中常见的API进行一个整理,接着再结合源代码以及注释详细地解读spark的作业提交流程,调 ...

  2. Hadoop(9)-HDFS的NameNode和SecondaryNameNode详解

    1.NN和2NN工作机制 首先,我们做个假设,如果存储在NameNode节点的磁盘中,因为经常需要进行随机访问,还有响应客户请求,必然是效率过低.因此,元数据需要存放在内存中.但如果只存在内存中,一旦 ...

  3. HDFS常用的Java Api详解

    转自:http://blog.csdn.net/michaelwubo/article/details/50879832 一.使用Hadoop URL读取数据 package hadoop; impo ...

  4. hibernate框架学习笔记3:API详解

    Configuration对象: package api; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configur ...

  5. 百度地图API详解之事件机制,function“闭包”解决for循环和监听器冲突的问题:

    原文:百度地图API详解之事件机制,function"闭包"解决for循环和监听器冲突的问题: 百度地图API详解之事件机制 2011年07月26日 星期二 下午 04:06 和D ...

  6. 转】Mahout推荐算法API详解

    原博文出自于: http://blog.fens.me/mahout-recommendation-api/ 感谢! Posted: Oct 21, 2013 Tags: itemCFknnMahou ...

  7. SDN 网络系统之 Mininet 与 API 详解

    SDN 网络系统之 Mininet 与 API 详解 Mininet 是轻量级的软件定义网络系统平台,同时提供了对 OpenFlow 协议的支持.本文主要介绍了 Mininet 的相关概念与特性,并列 ...

  8. Webdriver之API详解(1)

    说明 Webdriver API详解,基于python3,unittest框架,driver版本和浏览器自行选择. 本内容需要对python3的unittest框架有一个简单的了解,这里不再赘述,不了 ...

  9. Java8学习笔记(五)--Stream API详解[转]

    为什么需要 Stream Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念.它也不同于 StAX 对 ...

随机推荐

  1. 从零开始的SpringBoot项目 ( 六 ) 整合 MybatisPlus 实现代码自动生成

    1.添加依赖 <!-- MySQL数据库 --> <dependency> <groupId>mysql</groupId> <artifactI ...

  2. 基于Nodejs的sequelize操纵数据库

    ## 使用基于ORM架构的sequelize操纵数据库 ### 1.技术背景 ```Sequelize是一个基于promise的关系型数据库ORM框架,*********************技术文 ...

  3. node-sass安装失败解决方法

    node-sass安装失败,提示如下: gyp verb check python checking for Python executable "python" in the P ...

  4. MES系统与喷涂设备软件基于文本文件的数据对接方案

    产品在生产过程中除了记录产品本身的一些数据信息,往往还需要记录下生产设备的一些参数和状态,这也是MES系统的一个重要功能.客户的药物支架产品,需要用到微量药物喷涂设备,客户需要MES系统能完整记录下每 ...

  5. Git深入浅出使用教程:Git安装、远程控制、常用命令(全)

    一.软件安装 1.先安装[Git-2.24.1.2-64-bit.exe]软件.(官网下载的很慢,可以在百度云盘下载我的) 链接:https://pan.baidu.com/s/1uoIS9DWSBp ...

  6. Lua 调用的 C 函数保存 state 的两种方式: Storing State in C Functions 笔记

    http://yanbin.is-programmer.com/posts/94214.html Registery的Key 1. 整数Key用于Lua的引用机制,所以不要使用整数作为Key 2. 通 ...

  7. Rng(求逆元)

    Problem Description Avin is studying how to synthesize data. Given an integer n, he constructs an in ...

  8. 东方通Linux应用部署手册

    东方通应用部署文档   进入东方通访问地址: http://192.168.0.12:9060/console/输入用户名密码(thanos/thanos123.com)首页是对东方通软件的一些信息描 ...

  9. Kubernetes 服务部署最佳实践(一) ——如何更好地设置 Request 与 Limit

    如何为容器配置 Request 与 Limit? 这是一个即常见又棘手的问题,这个根据服务类型,需求与场景的不同而不同,没有固定的答案,这里结合生产经验总结了一些最佳实践,可以作为参考. 所有容器都应 ...

  10. Fabric1.4 架构和原理

    #1.Fabric总体架构Fabric架构主要包括三个模块:会员(Membership),区块链(Blockchan)和链码(chaincode). 1.1成员服务 包含下列组件:注册.身份认证管理及 ...