02_HDFS概述一

目录

一. HDFS概述

1.1 HDFS特点

1.1.1 优点:

1.2.2 局限性

1.2、HDFS命令

1.2.1 常用命令 hdfs dfs -help/-ls/-put/-get/-cat/-rm/-cp/-mkdir/-touchz/-appendToFile

1.2.2.、hdfs与getconf结合使用

1.2.3、 hdfs与dfsadmin结合使用

1.2.4、hdfs与fsck结合使用

1.2.5、 其他命令

1.3、WEB UI界面

二、block(核心概念)

2.1、数据块block

2.2、block副本

2.3 机架存储策略

2.4 block的一些操作

三、HDFS架构(重点 )

3.1、概念

1、文件系统

2、元数据

3、命名空间

3.2、NameNode

3.3、DataNode

3.4、 SecondaryNameNode

3.5、心跳机制

3.6、负载均衡

四、HDFS java API编程

4.1、建立MAVEN工程

4.2、编写HDFS读写代码

4.3、运行代码


 

一. HDFS概述

  • HDFS是Hadoop中的一个存储子模块

  • HDFS (全称Hadoop Distributed File System),即hadoop的分布式文件系统

    • File System文件系统:操作系统中负责管理和存储文件信息的软件;具体地说,它负责为用户创建文件,存入、读出、修改、转储、删除文件等

    • 比如windows下的文件系统

    • 当数据集大小超出一台计算机的存储能力时,就有必要将它拆分成若干部分,然后分散到不同的计算机中存储。管理网络中跨多台计算机存储的文件系统称之为分布式文件系统(distributed filesystem)

1.1 HDFS特点

  • HDFS是Hadoop中的分布式文件系统

  • HDFS高容错、可扩展

  • HDFS适合存储大文件,不适合存储小文件

  • 不适合处理低延时的数据方问

1.1.1 优点:

  • 1、适合存储大文件,能用来存储管理PB级的数据;不适合存储小文件

  • 2、存储非结构化数据 (https://blog.csdn.net/haishu_zheng/article/details/81844178

  • 3、流式的访问数据,一次写入、多次读写

  • 4、运行于廉价的商用机器集群上,成本低

  • 5、高容错:故障时能继续运行且不让用户察觉到明显的中断

  • 6、容量可扩展

  • 可扩展

1.2.2 局限性

  • 1、不适合处理低延迟数据访问

    • DFS是为了处理大型数据集分析任务的,主要是为达到高的数据吞吐量而设计的

    • 对于低延时的访问需求,HBase是更好的选择

  • 2、无法高效存储大量的小文件

    • 小文件会给Hadoop的扩展性和性能带来严重问题(How?)

    • 利用SequenceFile、MapFile等方式归档小文件(How?)

  • 3、不支持多用户写入及任意修改文件

    • 文件有一个写入者,只能执行追加操作

    • 不支持多个用户对同一文件的写操作,以及在文件任意位置进行修改,但支持追加

 

1.2、HDFS命令

 

HDFS命令与linux 命令的很相似性,前面多了 hadoop fs

HDFS命令有两种风格:hadoop fs开头的  hdfs dfs开头的,两种命令均可使用,效果相同

  • 输入hadoop fs 或hdfs dfs,回车,查看所有的HDFS命令

  • 许多命令与linux命令有很大的相似性,学会举一反三

  • 有用的help,如查看ls命令的使用说明:hadoop fs -help ls

1.2.1 常用命令 hdfs dfs -help/-ls/-put/-get/-cat/-rm/-cp/-mkdir/-touchz/-appendToFile

  1. 查看hdfs或hadoop子命令的帮助信息,如ls子命令

    hdfs dfs -help ls
    hadoop fs -help ls  #两个命令等价
  2. 查看hdfs文件系统中已经存在的文件。对比linux命令ls

    hdfs dfs -ls /
    hadoop fs -ls /
  3. 在hdfs文件系统中创建文件

    hdfs dfs -touchz /edits.txt
  4. 向HDFS文件中追加内容

    hadoop fs -appendToFile edit1.xml /edits.txt
     #将本地磁盘当前目录的edit1.xml内容追加到HDFS根目录 的edits.txt文件
  5. 查看HDFS文件内容

    hdfs dfs -cat /edits.txt
  6. 从本地路径上传文件至HDFS

    #用法:hdfs dfs -put /本地路径 /hdfs路径
    hdfs dfs -put hadoop-2.7.3.tar.gz /
    
    hdfs dfs -copyFromLocal hadoop-2.7.3.tar.gz /  #根put作用一样
    hdfs dfs -moveFromLocal hadoop-2.7.3.tar.gz /  #根put作用一样,只不过,源文件被拷贝成功后,会被删除
  7. 在hdfs文件系统中下载文件

    hdfs dfs -get /hdfs路径 /本地路径
    
    hdfs dfs -copyToLocal /hdfs路径 /本地路径  #根get作用一样
  8. 在hdfs文件系统中创建目录

    hdfs dfs -mkdir /shell
  9. 在hdfs文件系统中删除文件

    hdfs dfs -rm /edits.txt
    hdfs dfs -rm -r /shell
  10. 在hdfs文件系统中修改文件名称(也可以用来移动文件到目录)

     hdfs dfs -mv /xcall.sh /call.sh
     hdfs dfs -mv /call.sh /shell
  11. 在hdfs中拷贝文件到目录

      hdfs dfs -cp /xrsync.sh /shell
  12. 递归删除目录

      hdfs dfs -rmr /shell
  13. 列出本地文件的内容(默认是hdfs文件系统)

      hdfs dfs -ls file:///home/bruce/
  14. 查找文件

      # linux find命令
      find . -name 'edit*'
      
      # HDFS find命令
      hadoop fs -find / -name part-r-00000 # 在HDFS根目录中,查找part-r-00000文件
    

 

1.2.2.、hdfs与getconf结合使用

  1. 获取NameNode的节点名称(可能有多个)

    hdfs getconf -namenodes
  2. 获取hdfs最小块信息

    hdfs getconf -confKey dfs.namenode.fs-limits.min-block-size
  3. 查找hdfs的NameNode的RPC地址

    hdfs getconf -nnRpcAddresses

     

1.2.3、 hdfs与dfsadmin结合使用

  1. 借助帮助信息

    hdfs dfsadmin -help safemode
  2. 查看hdfs dfsadmin的帮助信息

    hdfs dfsadmin
  3. 查看当前的模式

    hdfs dfsadmin -safemode get
  4. 进入安全模式

  hdfs dfsadmin -safemode enter

 

1.2.4、hdfs与fsck结合使用

  1. fsck指令显示HDFS块信息

    hdfs fsck /02-041-0029.mp4 -files -blocks -locations # 查看文件02-041-0029.mp4的块信息

     

1.2.5、 其他命令

  1. 检查压缩库本地安装情况

    hadoop checknative
  2. 格式化名称节点(慎用,一般只在初次搭建集群,使用一次;格式化成功后,不要再使用)

    hadoop namenode -format
  3. 执行自定义jar包

    hadoop jar YinzhengjieMapReduce-1.0-SNAPSHOT.jar com.kaikeba.hadoop.WordCount /world.txt /out

1.3、WEB UI界面

注意:

若在windows下,能够访问node01:50070,需要配置C:\Windows\System32\drivers\etc\hosts文件,末尾添加如下三行内容

192.168.52.100 node01

192.168.52.110 node02

192.168.52.120 node03

  • 访问HDFS的web界面,浏览器访问  node01:50070

 

二、block(核心概念)

2.1、数据块block

  • 向HDFS上传文件,是按照128M为单位切分成一个个block分散的存储在集群的不同数据节点datanode上

    • 问:1、HDFS中一个44M大小的block块会不会占据128M的空间?

      • 不会,小于128M大小的块不会占据128M空间,此例占据44M

    • 问:2、这样存储有没有问题?

      • hadoop集群搭建在廉价的商用服务器上,所以服务器有出问题的几率

2.2、block副本

  • 因为HDFS是用普通的商用服务器搭建起来的;所以有节点出问题的可能性;

  • 那么如果每个block只有一份的话,当block所在的节点宕机后,此block将无法访问,进而导致文件无法完整读取

  • 为保正数据的可用及容错,HDFS设计成每个block共有三份,即三个副本

  • 如何设置副本数?

    • hdfs-site.xml文件中 设置replication = 3

  <property>
  	<name>dfs.replication</name>
  	<value>3</value>
  </property>

2.3 机架存储策略

  • 实际机房中,会有机架,每个机架上若干服务器

每个block有三个副本;以block1为例

  • 第一副本:在本机器(rack1机架中的datanode1)的HDFS目录下存储block1的第一个副本。

  • 第二副本:在不同Rack(如rack2)的某个DataNode(datanode4)上存储block1的第二个副本。

  • 第三副本:在datanode4所在机架rack2下,找一台其它的datanode节点(如datanode5),存储block1的第三个副本。

  • 能有多副本:随机节点

了解下服务器参数:https://item.jd.com/4564487.html

机架:https://item.jd.com/16829137698.html

2.4 block的一些操作

  • 1、设置文件副本数的作用:

    • 数据分块存储和副本的存放,是保证可靠性和高性能的关键

  • 2、设置文件副本数的方法:

    • 方式一:使用命令设置文件副本数;动态生效不需要重启hadoop集群

      • hadoop fs -setrep -R 4 /pathHDFS提供了fsck命令,用于检查HDFS上文件和目录的健康状态、获取文件的block信息和位置信息

    • 方式二:修改配置文件hdfs-site.xml需要重启hadoop集群才能生效

      • <property>
            <name>dfs.replication</name>
            <value>4</value>
        </property>
  • 3、检查HDFS上文件和目录的健康状态、获取文件的block信息和位置信息

    • [hadoop@node01 ~]$ hdfs fsck

(1)查看文件中损坏的块

[hadoop@node01 ~]$ hdfs fsck /tmall-201412-1w.csv -list-corruptfileblocks

(2)删除损坏的文件

hdfs fsck /02-041-0029.mp4 -files -blocks -locations

 

三、HDFS架构(重点 )

  • 大多数分布式大数据框架都是主从架构

  • HDFS也是主从架构 Master|Slave,或称为管理节点|工作节点

    • 主叫NameNode,中文称“名称节点”

    • 从叫DataNode,中文称“数据节点

 

  • NameNode负责存储HDFS集群的元数据,存在内存中

  • DataNode负责存储block块及块的元数据

  • SecondaryNameNode主要负责对HDFS元数据做checkpoint操作

  • 集群的心跳机制,让集群中各节点形成一个整体;主节点知道从节点的死活

  • 节点的上下线,导致存储的不均衡,可以手动触发负载均衡

 

3.1、概念

  • 1、文件系统

    • file system文件系统:操作系统中负责管理文件、存储文件信息的软件

      • 具体地说,它负责为用户创建文件,存入、读取、修改、转储、删除文件等

      • 读文件 =>>找到文件 =>> 在哪 + 叫啥?

  • 2、元数据

    • 关于文件或目录的描述信息,如文件所在路径、文件名称、文件类型等等,这些信息称为文件的元数据metadata

    • 注意:元数据的概念在其他的大数据框架中也屡有提及

  • 3、命名空间

    • 文件系统中,为了便于管理存储介质上的内容,给每个目录、目录中的文件、子目录都起了名字,这样形成的层级结构,称之为命名空间

    • 同一个目录中,不能有同名的文件或目录

    • 用处:这样通过目录+文件名称的方式能够唯一的定位一个文件

 

 

3.2、NameNode

  • 1、HDFS本质上也是文件系统filesystem,所以它也有元数据metadata;

    • HDFS元数据metadata保存在NameNode内存

  • 2、NameNode作用:

    • HDFS的主节点

    • 负责管理文件系统的命名空间,将HDFS的元数据存储在NameNode节点的内存中

    • 负责响应客户端对文件的读写请求

  • 3、HDFS元数据

    • 文件目录树、所有的文件(目录)名称、文件属性(生成时间、副本、权限)、每个文件的块列表、每个block块所在的datanode列表

    • 每个文件、目录、block占用大概150Byte字节的元数据所以HDFS适合存储大文件,不适合存储小文件

  • 4、HDFS元数据信息以两种形式保存:①编辑日志 edits log ②命名空间镜像文件 fsimage

    • ① edits log:(HDFS编辑日志文件)

      • 保存客户端对HDFS的所有更改记录,如增、删、重命名文件(目录),这些操作会修改HDFS目录树;

      • NameNode会在编辑日志edit日志中记录下来;

      • edits log为hdfs-site.xml中属性dfs.namenode.edits.dir的值决定;用于namenode保存edits.log文件

    • ② fsimage:(HDFS元数据镜像文件 )

      • 将namenode内存中的元数据落入磁盘生成的文件;

      • 保存了文件系统目录树信息以及文件、块、datanode的映射关系,如下图

      • fsimage为hdfs-site.xml中属性dfs.namenode.name.dir的值决定;用于namenode保存fsimage文件

3.3、DataNode

  • 1、DataNode数据节点的作用

    • 存储block以及block元数据到datanode本地磁盘;

    • 此处的元数据包括数据块的长度、块数据的校验和、时间戳

 

3.4、 SecondaryNameNode

  • 1、为什么元数据存储在NameNode在内存中?

    • HDFS编辑日志文件 editlog:在NameNode节点中的编辑日志editlog中,记录下来客户端对HDFS的所有更改的记录,如增、删、重命名文件(目录);每次更改对应一个事务,每个事务有一个事务编号;事务编号递增

    • 作用:一旦系统出故障,可以根据editlog恢复元数据;

  • 2、这样做有什么问题?如何解决?

    • editlog日志大小会随着时间变的越来越大,导致系统重启后,根据日志恢复元数据的时间会越来越长。

    • 为了避免这种情况,引入检查点机制checkpoint,命名空间镜像fsimage就是HDFS元数据的持久性检查点,即将内存中的元数据落磁盘生成的文件;

    • 此时,namenode如果重启,可以将磁盘中的fsimage文件读入内容,将元数据恢复到某一个检查点,然后再执行检查点之后记录的编辑日志editlog,最后完全恢复元数据。

  • 3、为什么引入SecondaryNameNode:

    • 随着时间的推移,editlog记录的日志会变多;那么当namenode重启,恢复元数据过程中,会花越来越长的时间执行editlog中的每一个日志;而在namenode元数据恢复期间,HDFS不可用。

    • 为了解决此问题,引入secondarynamenode辅助namenode,用来合并fsimage及editlog,定期做checkpoint检查点操作。

    • 创建检查点checkpoint的两大条件:

      • 另外,SecondaryNameNode每1分钟检查一次,从上一检查点开始,edits日志文件中是否已包括100万个事务,如果是,也会创建检查点

      • SecondaryNameNode每隔1小时创建一个检查点

 

  •  

  • 4、合并流程

    • (1) SNN首先请求原NN进行edits的滚动,这样新的编辑操作就能够进入新的文件中

    • (2) SNN通过HTTP GET方式读取原NN中的fsimage及edits

    • (3) SNN读取fsimage到内存中,然后执行edits中的每个操作,并创建一个新的统一的fsimage文件,有ckpt后缀

    • (4) SNN通过HTTP PUT方式将新的fsimage发送到原NN

    • (5) 原NN用新的fsimage替换旧的fsimage,同时系统会更新fsimage文件到记录检查点的时间。

    • (6) 这个过程结束后,NN就有了最新的fsimage文件和更小的edits文件

5、SecondaryNameNode一般部署在另外一台节点

  • 因为它需要占用大量的CPU时间

  • 并需要与namenode一样多的内存,来执行合并操作

6、如何查看edits日志文件

hdfs oev -i edits_0000000000000000256-0000000000000000363 -o /home/hadoop/edit1.xml

7、如何查看fsimage文件

hdfs oiv -p XML -i fsimage_0000000000000092691 -o fsimage.xml

 

3.5、心跳机制

1、工作原理:

  1. NameNode启动的时候,会开一个ipc server在那里

  2. DataNode启动后向NameNode注册,每隔3秒钟向NameNode发送一个“心跳heartbeat

  3. 心跳返回结果带有NameNode给该DataNode的命令,如复制块数据到另一DataNode,或删除某个数据块

  4. 如果超过10分钟NameNode没有收到某个DataNode 的心跳,则认为该DataNode节点不可用

  5. DataNode周期性(6小时)的向NameNode上报当前DataNode上的块状态报告BlockReport;块状态报告包含了一个该 Datanode上所有数据块的列表

2、心跳的作用:

  1. 通过周期心跳,NameNode可以向DataNode返回指令

  2. 可以判断DataNode是否在线

  3. 通过BlockReport,NameNode能够知道各DataNode的存储情况,如磁盘利用率、块列表;跟负载均衡有关

  4. hadoop集群刚开始启动时,99.9%的block没有达到最小副本数(dfs.namenode.replication.min默认值为1),集群处于安全模式,涉及BlockReport;

3、相关配置项

 

3.6、 负载均衡

  • 1、什么原因会有可能造成不均衡?

    • 机器与机器之间磁盘利用率不平衡是HDFS集群非常容易出现的情况

    • 尤其是在DataNode节点出现故障或在现有的集群上增添新的DataNode的时候

  • 2、为什么需要均衡?

    • 防止热点出现,提升集群存储资源利用率

    • 从存储与计算两方面提高集群性能

  • 3、如何手动负载均衡?下边命令无需重启hadoop

$HADOOP_HOME/sbin/start-balancer.sh -t 5%   # 磁盘利用率最高的节点若比最少的节点,大于5%,触发均衡
  • 停止负载均衡

$HADOOP_HOME/sbin/stop-balancer.sh

四、HDFS java API编程

4.1、建立MAVEN工程

①pom.xml文件;②建包、建类;

  • pom文件

<properties>
        <cdh.version>2.6.0-cdh5.14.2</cdh.version>
    </properties>

    <repositories>
        <repository>
            <id>cloudera</id>
            <url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
        </repository>
    </repositories>

    <dependencies>

        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>2.6.0-mr1-cdh5.14.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>${cdh.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>${cdh.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-mapreduce-client-core</artifactId>
            <version>${cdh.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>RELEASE</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

 

4.2、编写HDFS读写代码

1、本地文件上传到HDFS

package com.kaikeba.hadoop.hdfs;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;

import java.io.*;
import java.net.URI;

/**
 * 将本地文件系统的文件通过java-API写入到HDFS文件
 */
public class CopyFileFromLocal {

    /**
     * @param args
     * args0 windows本地磁盘文件C:/test.txt 或虚拟机本地磁盘文件/kkb/install/hadoop-2.6.0-cdh5.14.2/README.txt
     * args1 hdfs上文件hdfs://node01:8020/test.txt
     */
    public static void main(String[] args){

        // 0、本地磁盘路径
        String source = args[0];
        // 0、先确保/data目录存在
        String destination = args[1];//HDFS的路徑

        InputStream in = null;

        try {
            // 1、创建带缓冲的输入流in
            in = new BufferedInputStream(new FileInputStream(source));

            // 2、创建HDFS读写的配置文件对象
            Configuration conf = new Configuration();

            // 3、创建FileSystem对象
            FileSystem fs = FileSystem.get(URI.create(destination),conf);

            // 4、生成输出流out,根据FileSystem对象
            //调用Filesystem的create方法返回的是FSDataOutputStream对象
            //该对象不允许在文件中定位,因为HDFS只允许一个已打开的文件顺序写入或追加
            OutputStream out = fs.create(new Path(destination));

            // 5、将输入流的数据,拷贝到输出流,
            IOUtils.copyBytes(in, out, 4096, true);

        } catch (FileNotFoundException e) {
            System.out.println("exception");
            e.printStackTrace();
        } catch (IOException e) {
            System.out.println("exception1");
            e.printStackTrace();
        }

    }
}

2、从HDFS上拷贝数据到本地

package com.kaikeba.hadoop.hdfs;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;

/**
 * 从HDFS读取文件
 * 打包运行jar包 [bruce@node01 Desktop]$ hadoop jar com.kaikeba.hadoop-1.0-SNAPSHOT.jar  com.kaikeba.hadoop.hdfs.ReadFileFromHDFS
 */
public class ReadFileFromHDFS {

    /**
     * @param args
     * args0 hdfs上文件hdfs://node01:8020/test.txt
     * args1 windows本地磁盘文件C:/01 HK/高级03班/test01.txt或虚拟机本地磁盘文件
     */
    public static void main(String[] args) {
        try {
            // 0、源文件
            String srcFile = args[0];//HDFS的路径
            // 0、本地文件路径
            String destination = args[1];


            // 1、创建配置文件对象
            Configuration conf = new Configuration();

            // 2、创建文件系统
            FileSystem fs = FileSystem.get(URI.create(srcFile),conf);
            FSDataInputStream hdfsInStream = fs.open(new Path(srcFile));//输入流

            // 3、创建带缓冲的输出流,
            BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(destination));

            // 4、将输出流的数据,拷贝到输入流,
            IOUtils.copyBytes(hdfsInStream, outputStream, 4096, true);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4.3、运行代码

1、本地运行

(代码右键->run)

2、打包运行

(1)打包,两种方式;

方式一(得独立安装maven):

mvn clean package -DskipTests # 在工程目录下执行

方式二:利用IDEA图形化界面

(2) 运行jar包

[hadoop@node01 ~]$ hadoop jar com.kaikeba.hadoop-1.0-SNAPSHOT.jar com.kaikeba.hadoop.hdfs.CopyFileFromLocal /kkb/install/hadoop-2.6.0-cdh5.14.2  /README.txt   /README.txt

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值