一、HDFS前言

1、 设计思想
          分而治之:将大文件,大批量文件,分布式的存放于大量服务器上。以便于采取分而治之的方式对海量数据进行运算分析
     2、 在大数据系统架构中的应用
         为各类分布式运算框架( MapReduce, Spark, Tez, Flink, …)提供数据存储服务
     3、 重点概念: 数据块, 负载均衡, 心跳机制, 副本存放策略, 元数据/元数据管理, 安全 模式,机架感知…
二、HDFS相关概念和特性

首先,它是一个文件系统,用于存储文件,通过统一的命名空间——目录树来定位文件   其次,它是分布式的,由很多服务器联合起来实现其功能,集群中的服务器有各自的角色;
重要特性如下:
     1、 HDFS 中的文件在物理上是分块存储( block),块的大小可以通过配置参数( dfs.blocksize)   来规定,默认大小在 hadoop2.x 版本中是 128M,老版本中是 64M
     2、 HDFS 文件系统会给客户端提供一个统一的抽象目录树,客户端通过路径来访问文件,形 如: hdfs://namenode:port/dir-a/dir-b/dir-c/file.data
     3、 目录结构及文件分块位置信息(元数据)的管理由 namenode 节点承担
          ——namenode 是 HDFS 集群主节点,负责维护整个 hdfs 文件系统的目录树,以及每一个路 径(文件)所对应的 block 块信息( block 的 id,及所在的 datanode 服务器)
    4、 文件的各个 block 的存储管理由 datanode 节点承担
          ---- datanode 是 HDFS 集群从节点,每一个 block 都可以在多个 datanode 上存储多个副本(副 本数量也可以通过参数设置 dfs.replication,默认是 3)

5、 HDFS 是设计成适应一次写入,多次读出的场景,且不支持文件的修改,支持追加 (PS:适合用来做数据分析,并不适合用来做网盘应用,因为,不便修改,延迟大,网络开 销大,成本太高)
三、HDFS优缺点:

HDFS优点:

高容错性
                 数据自动保存多个副本
                 副本丢失后,自动恢复
          适合批处理
                移动计算而非数据
                数据位置暴露给计算框架
          适合大数据处理
                GB、 TB、甚至 PB 级数据
                百万规模以上的文件数量
                10K+节点规模
          流式文件访问
               一次性写入,多次读取
              保证数据一致性
              可构建在廉价机器上
              通过多副本提高可靠性
              提供了容错和恢复机制

HDFS缺点:

不适于以下操作:
              低延迟数据访问  :   比如毫秒级     低延迟与高吞吐率
              小文件存取    : 占用 NameNode 大量内存  寻道时间超过读取时间
               并发写入、文件随机修改:     一个文件只能有一个写者  仅支持 append

四、HDFS的shell操作

常用命令参数介绍:


 
五、HDFS的Java API操作
     1、利用eclipse 查看HDFS集群的文件信息

(1)下载一个 eclipse 开发工具 eclipse-jee-luna-SR1-win32-x86_64.zip
       (2) 解压到一个文件夹 C:\myProgram\eclipse
       (3) 把 hadoop-eclipse-plugin-2.6.4.jar 放入到 eclipse/plugins 文件夹下
       (4)双击启动 eclipse
       (5) 将 无 jar 版 windows 平台 hadoop-2.6.1.zip 解压到 windows 系统下一个文件夹下,文件 夹的路径最好不要带中文。我的目录是: C:\myProgram\hadoop-2.6.1
       (6) 打开了 eclipse 之后, 点击 windows –> prefrences -> 会出现一个对话框。找到如图所示 Hadoop MapReduce 选项: 然后把你安装的 hadoop 路径配置上,就是上一步你解压的那 个文件夹: C:\myProgram\hadoop-2.6.1,然后保存

       (注意的是如果 C:\myProgram\hadoop-2.6.1下还有一层文件就是hadoop-2.6.1,要写到C:\myProgram\hadoop-2.6.1\hadoop-2.6.1)

(7) 然后点击 windows  show view  other 在列表中找到图中这个东西: 然后双击

(8)然后会出现这么一个显示框

(9)咱们点击红框中这个东西,会出现相应的这么一个对话框,修改相应的信息,

(10)填完以上信息之后,点击 finish 会出现:

(11)最重要的时候在左上角的这个地方会出现:

至此,我们便完成了,利用 hadoop 的 eclipse 插件链接 hdfs 集群实现查看 hdfs 集群文件的 功能,大功告成。

2、搭建开发环境

创建Java project ,导入操作HDFS的jar包,导入的jar包有:

3、FileSystem实例获取讲解

在 java 中操作 hdfs,首先要获得一个客户端实例:
           Configuration conf = new Configuration()
           FileSystem fs = FileSystem.get(conf)
       而我们的操作目标是 HDFS,所以获取到的 fs 对象应该是 DistributedFileSystem 的实例; get 方法是从何处判断具体实例化那种客户端类呢?
       ——从 conf 中的一个参数 fs.defaultFS 的配置值判断;
       如果我们的代码中没有指定 fs.defaultFS,并且工程 classpath 下也没有给定相应的配置, conf 中的默认值就来自于 hadoop 的 jar 包中的 core-default.xml,默认值为: file:///,则获取的 将不是一个 DistributedFileSystem 的实例,而是一个本地文件系统的客户端对象

4、HDFS常用Java API演示

  1. package com.ghgj.hdfs;
  2.  
  3. import java.io.IOException;
  4.  
  5. import org.apache.hadoop.conf.Configuration;
  6. import org.apache.hadoop.fs.BlockLocation;
  7. import org.apache.hadoop.fs.FileStatus;
  8. import org.apache.hadoop.fs.FileSystem;
  9. import org.apache.hadoop.fs.LocatedFileStatus;
  10. import org.apache.hadoop.fs.Path;
  11. import org.apache.hadoop.fs.RemoteIterator;
  12.  
  13. public class HDFSDemo {
  14. static FileSystem fs = null;
  15. static Configuration conf = null;
  16. public static void main(String[] args) throws Exception {
  17. init();
  18. // testMkdirs();
  19. // testPut();
  20. // testGet();
  21. // testConf();
  22. // testDelete();
  23. // testRename();
  24. // testList();
  25. close();
  26. }
  27.  
  28. public static void testConf(){
  29.  
  30. /**
  31. * 给我们要操作的hdfs集群设置配置信息的方式有三种:
  32. * 第一种:通过代码,用conf.set()
  33. * 第二种:直接接在jar里面所携带的默认的core-default.xml
  34. * 第三种:加载我们项目自带的关于集群配置相关的xml
  35. */
  36.  
  37. /**
  38. * 1 > 3 > 2 加载级别高低,也就是谁后生效
  39. * 加载顺序:默认配置 , 集群安装配置=项目配置文件, 代码里面设置的配置信息
  40. */
  41.  
  42. String fileSystem = conf.get("fs.defaultFS");
  43. String string = conf.get("dfs.replication");
  44. System.out.println(fileSystem);
  45. System.out.println(string);
  46.  
  47. // conf.addResource(new Path("./myxmltext.xml"));
  48. // conf.addResource("myxmltext.xml");
  49. // System.out.println(conf.get("myname"));
  50. }
  51.  
  52. /**
  53. * 初始化fs链接
  54. * @throws IOException
  55. */
  56. public static void init() throws IOException{
  57. conf = new Configuration();
  58. conf.set("fs.defaultFS", "hdfs://hadoop02:9000");
  59. System.setProperty("HADOOP_USER_NAME", "hadoop");
  60. fs = FileSystem.get(conf);
  61. }
  62.  
  63. /**
  64. * 关闭fs链接
  65. * @throws IOException
  66. */
  67. public static void close() throws IOException{
  68. fs.close();
  69. }
  70. /**
  71. * 删除文件夹或者文件
  72. * @throws IOException
  73. */
  74. public static void testDelete() throws IOException{
  75. fs.delete(new Path("/abcd"), true);
  76. }
  77.  
  78. /**
  79. * 重命名
  80. * @throws IOException
  81. */
  82. public static void testRename() throws IOException{
  83. fs.rename(new Path("/txt1.txt"), new Path("/huangbo.txt"));
  84. }
  85.  
  86. /**
  87. * 遍历文件
  88. * @throws IOException
  89. */
  90. public static void testList() throws IOException{
  91.  
  92. // 遍历某个路径下所有的文件节点。包括文件和文件夹
  93. /*FileStatus[] listStatus = fs.listStatus(new Path("/"));
  94. for(FileStatus fss: listStatus){
  95. boolean directory = fss.isDirectory();
  96. if(directory){
  97. System.out.println(fss.getPath()+" -- 文件夹");
  98. }else{
  99. System.out.println(fss.getPath()+" -- 文件");
  100. }
  101. }*/
  102.  
  103. // 只遍历文件
  104. RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);
  105. while(listFiles.hasNext()){
  106. LocatedFileStatus next = listFiles.next();
  107. boolean directory = next.isDirectory();
  108. // next.getBlockSize()
  109. BlockLocation[] blockLocations = next.getBlockLocations();
  110.  
  111. for(BlockLocation bl: blockLocations){
  112. String[] hosts = bl.getHosts();
  113. System.out.println("长度:"+bl.getLength());
  114. for(String s: hosts){
  115. System.out.print(s + "\t");
  116. }
  117. System.out.println(next.getPath());
  118. }
  119.  
  120. /*if(directory){
  121. System.out.println(next.getPath()+" -- 文件夹"+ blockLocations.length);
  122. }else{
  123. System.out.println(next.getPath()+" -- 文件"+ blockLocations.length);
  124. }*/
  125. }
  126. }
  127.  
  128. /**
  129. * s上传文件
  130. * @throws IOException
  131. */
  132. public static void testMkdirs() throws IOException{
  133. boolean mkdirs = fs.mkdirs(new Path("/abcd/nnn/mmm/uuu/jjj"));
  134. System.out.println(mkdirs);
  135. }
  136.  
  137. /**
  138. * 上传文件
  139. * @throws IOException
  140. */
  141. public static void testPut() throws IOException{
  142. fs.copyFromLocalFile(new Path("C:/wdata/student.txt"), new Path("/abcd"));
  143. }
  144.  
  145. /**
  146. * 下载文件
  147. * @throws IOException
  148. */
  149. public static void testGet() throws IOException{
  150. fs.copyToLocalFile(new Path("/abcd/student.txt"), new Path("C:/ss.txt"));
  151. System.out.println("is done");
  152. }
  153.  
  154. }

  5、HDFS流式数据访问

相对那些封装好的方法而言的更底层一些的操作方式 上层那些 mapreduce spark 等运算  框架,去 hdfs 中获取数据的时候,就是调的这种底层的 api

  1. package com.ghgj.hdfs;
  2.  
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.io.FileOutputStream;
  6.  
  7. import org.apache.hadoop.conf.Configuration;
  8. import org.apache.hadoop.fs.FSDataInputStream;
  9. import org.apache.hadoop.fs.FSDataOutputStream;
  10. import org.apache.hadoop.fs.FileSystem;
  11. import org.apache.hadoop.fs.Path;
  12. import org.apache.hadoop.io.IOUtils;
  13.  
  14. public class TestHDFSStream {
  15.  
  16. static Configuration conf = null;
  17. static FileSystem fs = null;
  18.  
  19. public static void main(String[] args) throws Exception {
  20. init();
  21. // getHDFSFileByStream();
  22. putFileToHDFS();
  23. close();
  24. }
  25.  
  26. /**
  27. * 通过流的方式,去HDFS上下载一个文件下来
  28. * 实现思路:
  29. * 1、利用一个输入流读取该文件的数据
  30. * FSI = fs.open(path);
  31. * 2、......
  32. * 3、获取文件输出流,把输入流的数据给存到本地
  33. */
  34. public static void getHDFSFileByStream() throws Exception{
  35.  
  36. // 获取数据输入流
  37. Path path = new Path("hdfs://hadoop02:9000/hadoop-2.6.4-centos-6.5.tar.gz");
  38. FSDataInputStream open = fs.open(path);
  39.  
  40. // 获取文件输出流
  41. FileOutputStream fos = new FileOutputStream(new File("c:/myhadoop.txt"));
  42.  
  43. // 作用:让输入流和输出流对接,进行数据的传输(复制)
  44. // IOUtils.copyBytes(open, fos, conf);
  45. IOUtils.copyBytes(open, fos, conf.getInt("io.file.buffer.size", 4096), true);
  46.  
  47. }
  48.  
  49. /**
  50. * 实现思路:
  51. * 1、获取一个本地文件的输入流
  52. * 2、、、
  53. * 3、在hdfs的客户端创建一个输出流,把输入流上的数据复制到hdfs文件系统里面去
  54. */
  55. public static void putFileToHDFS() throws Exception{
  56.  
  57. // 获取一个本地文件的输入流
  58. FileInputStream fin = new FileInputStream(new File("c:/myhadoop.txt"));
  59.  
  60. // 准备一个hdfs的输出流
  61. Path path = new Path("/myhadoop.tar.gz");
  62.  
  63. FSDataOutputStream create = fs.create(path);
  64.  
  65. IOUtils.copyBytes(fin, create, conf);
  66. }
  67.  
  68. public static void init() throws Exception{
  69. conf = new Configuration();
  70. conf.set("fs.defaultFS", "hdfs://hadoop02:9000");
  71. System.setProperty("HADOOP_USER_NAME","hadoop");
  72.  
  73. fs = FileSystem.get(conf);
  74. }
  75.  
  76. public static void close() throws Exception{
  77. fs.close();
  78. }
  79. }

    经典案例:

在 mapreduce 、 spark 等运算框架中,有一个核心思想就是将运算移往数据,或者说,就是 要在并发计算中尽可能让运算本地化,这就需要获取数据所在位置的信息并进行相应范围读 取。 以下模拟实现:获取一个文件的所有 block 位置信息,然后读取指定 block 中的内容

  1. @Test
  2. public void testCat() throws IllegalArgumentException, IOException {
  3. FSDataInputStream in = fs.open(new Path("/weblog/input/access.log.10"));
  4. // 拿到文件信息
  5. FileStatus[] listStatus = fs.listStatus(new Path(
  6. "/weblog/input/access.log.10"));
  7. // 获取这个文件的所有 block 的信息
  8. BlockLocation[] fileBlockLocations = fs.getFileBlockLocations(
  9. listStatus[0], 0L, listStatus[0].getLen());
  10. // 第一个 block 的长度
  11. long length = fileBlockLocations[0].getLength();
  12. // 第一个 block 的起始偏移量
  13. long offset = fileBlockLocations[0].getOffset();
  14. System.out.println(length);
  15. System.out.println(offset);
  16. // 获取第一个 block 写入输出流
  17. // IOUtils.copyBytes(in, System.out, (int)length);
  18. byte[] b = new byte[4096];
  19. FileOutputStream os = new FileOutputStream(new File("d:/block0"));
  20. while (in.read(offset, b, 0, 4096) != -1) {
  21. os.write(b);
  22. offset += 4096;
  23. if (offset > length)
  24. return;
  25. }
  26. os.flush();
  27. os.close();
  28. in.close();
  29. }

  案例:

  1. package com.ghgj.hdfs;
  2.  
  3. import java.io.File;
  4. import java.io.FileOutputStream;
  5. import java.net.URI;
  6.  
  7. import org.apache.hadoop.conf.Configuration;
  8. import org.apache.hadoop.fs.BlockLocation;
  9. import org.apache.hadoop.fs.FSDataInputStream;
  10. import org.apache.hadoop.fs.FileStatus;
  11. import org.apache.hadoop.fs.FileSystem;
  12. import org.apache.hadoop.fs.Path;
  13. import org.apache.hadoop.io.IOUtils;
  14.  
  15. public class TestRandomStream {
  16.  
  17. public static void main(String[] args) throws Exception {
  18.  
  19. // testSeek();
  20. getSecondBlock();
  21. }
  22.  
  23. /**
  24. * 通过HDFS api 取到对应数据对应数据块的数据
  25. * 作用:
  26. * @throws Exception
  27. */
  28. public static void getSecondBlock() throws Exception{
  29. Configuration conf = new Configuration();
  30. FileSystem fs = FileSystem.get(new URI("hdfs://hadoop02:9000"), conf, "hadoop");
  31.  
  32. FSDataInputStream open = fs.open(new Path("/hadoop-2.6.4-centos-6.5.tar.gz"));
  33.  
  34. // 134217728
  35. // 46595337
  36.  
  37. long offset = 0;
  38. long length = 0;
  39.  
  40. FileStatus[] listStatus = fs.listStatus(new Path("/hadoop-2.6.4-centos-6.5.tar.gz"));
  41. length = listStatus[0].getLen();
  42.  
  43. BlockLocation[] fileBlockLocations = fs.getFileBlockLocations(listStatus[0], 0, length);
  44. // 想要获取到hadoop安装包第二块数据的数据块的起始偏移量
  45. offset = fileBlockLocations[1].getOffset();
  46. // 设置起始偏移量
  47. open.seek(offset);
  48.  
  49. long seekLength = fileBlockLocations[1].getLength();
  50. System.out.println(offset+"\t"+seekLength);
  51.  
  52. // 构建文件输出流
  53. FileOutputStream fout = new FileOutputStream(new File("c:/secondHadoop.tar.gz"));
  54.  
  55. // 把输入流数据,复制到输出流
  56. IOUtils.copyBytes(open, fout, seekLength, true);
  57. fs.close();
  58. }
  59.  
  60. /**
  61. * 从随机位置offset读取任意长度length的数据
  62. * @throws Exception
  63. */
  64. public static void testSeek() throws Exception{
  65. Configuration conf = new Configuration();
  66. // System.setProperty("HADOOP_USER_NAME", "hadoop");
  67. FileSystem fs = FileSystem.get(new URI("hdfs://hadoop02:9000"), conf, "hadoop");
  68.  
  69. FSDataInputStream open = fs.open(new Path("hdfs://hadoop02:9000/shuzi.txt"));
  70.  
  71. long offset = 12;
  72. long length = 23L;
  73.  
  74. // 设置起始偏移量
  75. open.seek(offset);
  76.  
  77. FileOutputStream fout = new FileOutputStream(new File("c:/myshuzi.txt"));
  78.  
  79. // 注意第三个参数:它是long类型。表示取数据的长度
  80. IOUtils.copyBytes(open, fout, length, true);
  81.  
  82. fs.close();
  83. }
  84.  
  85. }

  

hadoop(三)HDFS基础使用的更多相关文章

  1. 每天收获一点点------Hadoop之HDFS基础入门

    一.HDFS出现的背景 随着社会的进步,需要处理数据量越来越多,在一个操作系统管辖的范围存不下了,那么就分配到更多的操作系统管理的磁盘中,但是却不方便管理和维护—>因此,迫切需要一种系统来管理多 ...

  2. Hadoop系列-HDFS基础

    基本原理 HDFS(Hadoop Distributed File System)是Hadoop的一个基础的分布式文件系统,这个分布式的概念主要体现在两个地方: 数据分块存储在多台主机 数据块采取冗余 ...

  3. hadoop(三):hdfs 机架感知

    client 向 Active NN 发送写请求时,NN为这些数据分配DN地址,HDFS文件块副本的放置对于系统整体的可靠性和性能有关键性影响.一个简单但非优化的副本放置策略是,把副本分别放在不同机架 ...

  4. Hadoop(1): HDFS基础架构

    1. What's HDFS? Hadoop Distributed File System is a block-structured file system where each file is ...

  5. Hadoop学习笔记—2.不怕故障的海量存储:HDFS基础入门

    一.HDFS出现的背景 随着社会的进步,需要处理数据量越来越多,在一个操作系统管辖的范围存不下了,那么就分配到更多的操作系统管理的磁盘中,但是却不方便管理和维护—>因此,迫切需要一种系统来管理多 ...

  6. 零基础学习hadoop开发所必须具体的三个基础知识

    大数据hadoop无疑是当前互联网领域受关注热度最高的词之一,大数据技术的应用正在潜移默化中对我们的生活和工作产生巨大的改变.这种改变给我们的感觉是“水到渠成”,更为让人惊叹的是大数据已经仅仅是互联网 ...

  7. hadoop - hdfs 基础操作

    hdfs --help # 所有参数 hdfs dfs -help # 运行文件系统命令在Hadoop文件系统 hdfs dfs -ls /logs # 查看 hdfs dfs -ls /user/ ...

  8. 非常不错 Hadoop 的HDFS (Hadoop集群(第8期)_HDFS初探之旅)

    1.HDFS简介 HDFS(Hadoop Distributed File System)是Hadoop项目的核心子项目,是分布式计算中数据存储管理的基础,是基于流数据模式访问和处理超大文件的需求而开 ...

  9. 快速学习hadoop只有这些基础可不行

    “学习hadoop需要什么基础”这已经不是一个新鲜的话题了,随便上网搜索一下就能找出成百上千篇的文章在讲学习hadoop需要掌握的基础.再直接的一点的问题就是——学Hadoop难吗?用一句特别让人无语 ...

  10. 深入理解Hadoop之HDFS架构

    Hadoop分布式文件系统(HDFS)是一种分布式文件系统.它与现有的分布式文件系统有许多相似之处.但是,与其他分布式文件系统的差异是值得我们注意的: HDFS具有高度容错能力,旨在部署在低成本硬件上 ...

随机推荐

  1. Android 不同分辨率下调整界面

    Android Settings中有修改Disaply size的界面,通过修改Display size,能够修改屏幕分辨率. 由于修改了屏幕分辨率,有可能导致同一界面在不同的分辨率下显示出错(内容显 ...

  2. xampp服务器搭建和使用

    1.安装完XAMPP后会出现Apache端口被占用的问题,一下方法解决 错误信息如下: Error: Apache shutdown unexpectedly. 9:37:01  [Apache] T ...

  3. 一学就会pip换镜像源

    首先介绍一个国内好用的镜像站 阿里云 http://mirrors.aliyun.com/pypi/simple/ 豆瓣 http://pypi.douban.com/simple/ 清华大学 htt ...

  4. Fulfilling Work: The Shippers More entrepreneurs hire 'fulfillment' outfits to store and ship their products

    By Stu Woo June 23, 2011 Brett Teper faced a logistical problem when he and a partner founded ModPro ...

  5. Alpha阶段中间产物——GUI Prototype、WBS及PSP

    作业地址:https://edu.cnblogs.com/campus/nenu/SWE2017FALL/homework/1224 内容: GUI Prototype 我的书架 我的书架→添加图书 ...

  6. 模仿qq列表信息滑动删除效果

    这个效果的完成主要分为两个部分 自定义view作为listview的列表项 一个view里面包括 显示头像,名字,消息内容等的contentView和滑动才能显示出来的删除,置顶的右边菜单menuVi ...

  7. YQCB项目介绍

    YQCB记账本软件 制作人:YQCB团队 团队简介:团队成立于2017年11月21日,由陈美琪,张晨阳,邢全阳,刘昭为四人组成. 陈美琪:团队灵魂人物,背负着巨大的压力带起整个团队. 张晨阳:团队领军 ...

  8. 第一阶段android学习笔记

    1.学习<第一行代码> 第一个android项目: 项目的注意点,如创建项目时包名具有唯一性,在做项目的时候要手动改成Project模式.还知道了引用字符串的两种方式. AS项目的三种依赖 ...

  9. Jquery获取属性值

    jq获取某个标签内的属性值:$("#TeamPerformanceYearUl li:eq(0)").attr('data') jq获取li或者td第一个属性(索引值从零开始)$( ...

  10. React Native 学习-组件说明和生命周期

    组件的详细说明(Component Specifications) 当通过调用 React.createClass() 来创建组件的时候,你应该提供一个包含 render 方法的对象,并且也可以包含其 ...