HDFS基础

HDFS分布式文件系统

Hadoop作者:Doug Cutting

遇到了海量数据存储以及海量数据计算的问题,谷歌发表了三篇论文:GFS、MapReduce、Bigtable

一.Hadoop运行模式

本地运行模式

伪分布式运行模式

完全分布式运行模式(开发重点)

二.Hadoop架构设计

Hadoop组成模块:HDFS、Yarn、MapReduce

1、HDFS:分布式文件存储系统,主要用于存储海量数据

namenode:主节点。管理整个集群,保证集群的正常运行

datanode:从节点。主要用于存储用户的数据

client:客户端。用于用户操作集群

2、Yarn:资源调度管理系统,主要用于调度整个集群的资源

resourceManager:主节点。主要用于yarn集群的管理,保证整个集群的正常运行

nodeManager:从节点。主要用于提供资源进行计算:CPU,Mem

3、MapReduce:分布式文件计算框架

三.HDFS:Hadoop Distribute FileSystem

文件系统:可以实现文件的增删改查

分布式文件系统:将多台电脑联合起来,形成一个文件系统,一个文件可能存储在多台机器上,每台机器保存文件的部分数据,“三个臭皮匠顶个诸葛亮”

1、分块存储&机架感知&三副本

hdfs当中,数据都是按照block块方式存储的,默认大小是128m(Hadoop2)

300m文件会切分成三个块,128m 128m 44m

一个3m的文件A,占用磁盘文件3m,会占用一个128m的块

125m的文件B,不会和3m的文件a共用一个块,不同文件不能共用一个block块

2、抽象成数据块的好处

1.文件可能大于集群中任意一个磁盘

2.使用块抽象而不是文件可以简化存储子系统

hdfs将所有文件全部抽象成块来进行存储,不管文件大小,全部一视同仁都是以块的方式进行存储,方便对分布式文件系统对文件的管理

3.块非常适合用于数据备份,进而提供数据的容错能力和可用性

3、hdfs架构

NameNode:主节点,集群管理,存储元数据信息,保存在内存中

DataNode:从节点,存储数据,保存在磁盘中

SecondaryNameNode:Namenode的冷备份,协助Namenode处理元数据信息

HDFS Client:客户端,用户连接集群入口

heartbeats:心跳,DataNode每30s发送信息给Namenode,确保DataNode存活

balancing:负载均衡,数据平衡

replication:副本机制

四.HDFS的shell命令

hdfs所有命令在Hadoop安装目录下的bin/hdfs里

1、查看帮助

hdfs dfs -help

2、创建文件

hdfs dfs -touchz /1.txt

3、向文件追加内容

hdfs dfs -appendToFile 1.xml /1.txt #将本地磁盘当前路径的1.xml文件内容追加到hdfs的1.txt文件

4、查看路径文件

hdfs dfs -ls /

5、查看文件内容

hdfs dfs -cat /1.txt

6、上传文件

hdfs dfs -put 1.xml /
hdfs dfs -copyFromLocal /linux /hdfs
hdfs dfs -moveFromLocal /linux /hdfs #本地文件移动到hdfs上,完成后本地会删除文件

7、下载文件

hdfs dfs -get /1.txt /opt

8、创建文件夹

hdfs dfs -mkdir -p /test

9、删除文件目录

hdfs dfs -rm -r /test

10、移动文件

hdfs dfs -mv 1.txt 2.txt

11、复制文件

hdfs dfs -cp 1.txt 2.txt

12、查找文件

hdfs dfs -find / -name xx

13、查看Namenode配置信息

hdfs getconf -namenode

14、查看NamenodeRPC地址

hdfs dfs getconf -nnRpcAddresses

15、hdfs dfsadmin使用

hdfs dfsadmin -safemode get #查看安全模式状态
hdfs dfsadmin -safemode enter #进入安全模式
hdfs dfsadmin -safemode leave #退出安全模式
#安全模式下不能修改和插入数据

16、hdfs fsck使用

hdfs fsck /1.txt -file -block -locations #查看文件1.txt的块信息,也可以用来修复块

五.hdfs的优缺点

1、hdfs优点

1.高容错性:因为副本的原因,可以容错block的丢失

2.适合批量数据处理,不适合实时数据处理

3.适合大规模数据的处理,不适合小文件数据的处理

4.流式数据访问:一次写入,多次读取的操作。不支持随机修改,只能追加文件

5.可以构建在廉价的设备上

2、hdfs缺点

1.不适合低延迟的数据访问,适合高吞吐,同一时间写入大量数据

2.无法存储海量小文件,适合存储大文件,每一个小文件都会占用一份元数据信息,大文件一会,存储大量小文件会占用过多内存

3.不支持并发写入,数据不支持随机修改,支持append追加

六.hdfs安全模式

1、安全模式下只支持读请求,不支持修改和删除等变更请求
2、Namenode主节点启动时,hdfs首先进入安全模式
3、何时退出安全模式

1.Namenode知道集群共有多少个block(不考虑副本),假设值是total

2.Namenode启动后,会上报block report,Namenode开始累加统计满足最小副本数的block数,假设值是num

3.当num/total > 99.9%时,退出安全模式

七.hdfs的java编程

1、配置windows本地hadoop和maven,安装jdk,安装IDEA

2、在IDEA创建maven工程,修改pom.xml文件

        <hadoop.version>2.7.3</hadoop.version>
    </properties>
    <dependencies>
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-client</artifactId>
        <version>${hadoop.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-common</artifactId>
        <version>${hadoop.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-hdfs</artifactId>
        <version>${hadoop.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-mapreduce-client-core</artifactId>
        <version>${hadoop.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>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                    <!-- <verbal>true</verbal>-->
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.4.3</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <minimizeJar>true</minimizeJar>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

3、在开始编程之前,请先确保相关依赖已经下载完成,配置IDEA自动导包

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-twcvTObE-1679037434169)(C:\Users\Msxt186\AppData\Roaming\Typora\typora-user-images\image-20230228160735968.png)]

4、Java API操作

   //创建文件夹
    @Test
    public void mkdirTest() throws IOException {
        //操作hdfs集群核心类FileSystem
        Configuration configuration = new Configuration();
        configuration.set("fs.defaultFS","hdfs://hadoop002:9000");
        FileSystem fileSystem = FileSystem.get(configuration);

        fileSystem.mkdirs(new Path("/chen"));
        fileSystem.close();
    }


    //创建文件夹,指定用户
    @Test
    public void mkdirTest2() throws IOException, URISyntaxException, InterruptedException {
        //操作hdfs集群核心类FileSystem
        Configuration configuration = new Configuration();
        configuration.set("fs.defaultFS","hdfs://hadoop002:9000");
        FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop002:9000"),configuration,"hadoop");
        //FileSystem fileSystem = FileSystem.get(configuration);

        fileSystem.mkdirs(new Path("/chen1"));
        fileSystem.close();
    }


    //创建文件夹,指定权限
    @Test
    public void mkdirTest3() throws IOException, URISyntaxException, InterruptedException {
        //操作hdfs集群核心类FileSystem
        Configuration configuration = new Configuration();
        configuration.set("fs.defaultFS","hdfs://hadoop002:9000");
        FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop002:9000"),configuration,"hadoop");
        //FileSystem fileSystem = FileSystem.get(configuration);

        FsPermission fsPermission = new FsPermission(FsAction.ALL, FsAction.ALL, FsAction.READ);

        fileSystem.mkdirs(new Path("/chen3"),fsPermission);
        fileSystem.close();
    }

    //上传文件
    @Test

    public void uploadFile() throws IOException, URISyntaxException, InterruptedException {
        //操作hdfs集群核心类FileSystem
        Configuration configuration = new Configuration();
        configuration.set("fs.defaultFS","hdfs://hadoop002:9000");
        FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop002:9000"),configuration,"hadoop");
        //FileSystem fileSystem = FileSystem.get(configuration);


        fileSystem.copyFromLocalFile(new Path("C:\\Users\\Msxt186\\Desktop\\1\\a.txt"),new Path("/chen"));

        fileSystem.close();
    }

    //下载文件
    @Test

    public void downloadFile() throws IOException, URISyntaxException, InterruptedException {
        //操作hdfs集群核心类FileSystem
        Configuration configuration = new Configuration();
        configuration.set("fs.defaultFS","hdfs://hadoop002:9000");
        FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop002:9000"),configuration,"hadoop");
        //FileSystem fileSystem = FileSystem.get(configuration);

        fileSystem.copyToLocalFile(new Path("hdfs://hadoop002:9000/chen/a.txt"),new Path("file:///C:\\Users\\Msxt186\\Desktop\\2.txt"));
       // fileSystem.copyFromLocalFile(new Path("C:\\Users\\Msxt186\\Desktop\\1\\a.txt"),new Path("/chen"));

        fileSystem.close();
    }

    //删除文件
    @Test

    public void removeFile() throws IOException, URISyntaxException, InterruptedException {
        //操作hdfs集群核心类FileSystem
        Configuration configuration = new Configuration();
        configuration.set("fs.defaultFS","hdfs://hadoop002:9000");
        FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop002:9000"),configuration,"hadoop");
        //FileSystem fileSystem = FileSystem.get(configuration);

       fileSystem.delete(new Path("/ming"));

        fileSystem.close();
    }

    //移动文件到本地
    @Test

    public void moveFileToLocal() throws IOException, URISyntaxException, InterruptedException {
        //操作hdfs集群核心类FileSystem
        Configuration configuration = new Configuration();
        configuration.set("fs.defaultFS","hdfs://hadoop002:9000");
        FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop002:9000"),configuration,"hadoop");
        //FileSystem fileSystem = FileSystem.get(configuration);

        fileSystem.moveToLocalFile(new Path("hdfs://hadoop002:9000/chen"),new Path("file:///C:\\Users\\Msxt186\\Desktop"));
        fileSystem.close();
    }

    //移动文件HDFS
    @Test

    public void moveFileFromLocal() throws IOException, URISyntaxException, InterruptedException {
        //操作hdfs集群核心类FileSystem
        Configuration configuration = new Configuration();
        configuration.set("fs.defaultFS","hdfs://hadoop002:9000");
        FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop002:9000"),configuration,"hadoop");
        //FileSystem fileSystem = FileSystem.get(configuration);

        fileSystem.moveFromLocalFile(new Path("file:///C:\\Users\\Msxt186\\Desktop\\chen\\ming"),new Path("hdfs://hadoop002:9000/"));
        fileSystem.close();
    }

    //查看文件描述信息
    @Test

    public void fileDescription() throws IOException, URISyntaxException, InterruptedException {
        //操作hdfs集群核心类FileSystem
        Configuration configuration = new Configuration();
        configuration.set("fs.defaultFS","hdfs://hadoop002:9000");
        FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop002:9000"),configuration,"hadoop");
        //FileSystem fileSystem = FileSystem.get(configuration);

        RemoteIterator<LocatedFileStatus> locatedFileStatusRemoteIterator = fileSystem.listFiles(new Path("hdfs://hadoop002:9000/chen"),true);
        while(locatedFileStatusRemoteIterator.hasNext()){
            LocatedFileStatus status = locatedFileStatusRemoteIterator.next();
           String name = status.getPath().getName();
            System.out.println(name);              //名称

            long len = status.getLen();
            System.out.println(len);        //大小

            String group = status.getGroup();
            System.out.println(group);      //属组

            BlockLocation[] blockLocations = status.getBlockLocations();
            for (BlockLocation blockLocation : blockLocations) {
                String[] hosts = blockLocation.getHosts();
                for (String host : hosts) {
                    System.out.println(host); //块存在的主机
                }

/*                String[] names = blockLocation.getNames();
                for (String na:names){
                    System.out.println(na);
                }*/
            }

        }
        fileSystem.close();
    }

八.DataNode工作机制及存储

\\是一个转义字符,将特殊字符进行转义,转义成字符串
//是路径的作用

1、DataNode工作机制

⼀个数据块在datanode上以⽂件形式存储在磁盘上,包括两个⽂件

1.⼀个是数据本⾝
2.⼀个是元数据包括数据块的长度,块数据的校验和,以及时间戳

hdfs-site.xml中指定了数据存储的路径

<property>
<name>dfs.datanode.data.dir</name>
<value>file:///opt/install/hadoop-3.1.4/hadoopDatas/datanodeDatas</value>
</property>
3.NameNode主节点如何知道DataNode有多少块?

datanode回定时给NameNode上报心跳信息,比如块的数量、大小等,NameNode返回结果给该DataNode的命令,比如复制、删除等

心跳是每3秒一次,超过10分钟没有收到某个DataNode的心跳,则认为该节点不可用

4.集群运行中可以安全加入和退出一些机器

2、数据完整性

1.当客户端向hdfs写数据时

会计算数据的校验和,以保证数据通过网络传输到达DataNode时,没有丢失数据

2.当DataNode读取block时

会计算checksum,如果计算的checksum与创建block时的值不一样,说明block已经损坏

客户端读取其他DataNode上的block

3.DataNode在文件创建后周期验证checksum

3、掉线时限参数设置

1.datanode进程死亡或者⽹络故障造成datanode⽆法与namenode通信,namenode不会⽴即把该节点判定为死亡

2.要经过⼀段时间,这段时间暂称作超时时长。HDFS默认的超时时长为==10分钟+30秒 ==。如果定义超时时间为timeout,则超时时长的计算公式为:

3.以下属性,可以查看官⽹的hdfs-default.xml⽂件

timeout = 2 * dfs.namenode.heartbeat.recheck-interval + 10 * dfs.heartbeat.interval

4.⽽默认的dfs.namenode.heartbeat.recheck-interval ⼤⼩为5分钟, dfs.heartbeat.interval默认为3秒
5.需要注意的是hdfs-site.xml 配置⽂件中的heartbeat.recheck.interval的单位为毫秒,dfs.heartbeat.interval的单位为

<property>
   <name>dfs.namenode.heartbeat.recheck-interval</name> 
   <value>300000</value>
</property> 
<property>
   <name> dfs.heartbeat.interval </name> 
   <value>3</value>
</property>

4、DataNode的⽬录结构

1.和namenode不同的是,datanode的存储⽬录是初始阶段⾃动创建的,不需要额外格式化。
2.在主节点bigdata01的⽬录/opt/install/hadoop-3.1.4/hadoopDatas/datanodeDatas/current下查看版本号

[root@bigdata01 current]# cat VERSION 
#Thu Mar 14 07:58:46 CST 2019
storageID=DS-47bcc6d5-c9b7-4c88-9cc8-6154b8a2bf39 
clusterID=CID-dac2e9fa-65d2-4963-a7b5-bb4d0280d3f4 
cTime=0
datanodeUuid=c44514a0-9ed6-4642-b3a8-5af79f03d7a4 
storageType=DATA_NODE
layoutVersion=-5

具体解释
(1)storageID:存储id号
(2)clusterID集群id,全局唯⼀
(3)cTime属性标记了datanode存储系统的创建时间,对于刚刚格式化的存储系统,这个属性为0;但是在⽂件系统升级之后,该值会更新到新的时间戳
(4)datanodeUuid:datanode的唯⼀识别码
(5)storageType:存储类型

(6)layoutVersion是⼀个负整数。通常只有HDFS增加新特性时才会更新这个版本号

5、Datanode多⽬录配置

1.datanode也可以配置成多个⽬录,每个⽬录存储的数据不⼀样。即:数据不是副本

具体配置如下vim hdfs-site.xml

<!-- 定义dataNode数据存储的节点位置,实际⼯作中,⼀般先确定磁盘的挂载⽬录,然后多个 
⽬录⽤,进⾏分割  -->
<property>
  <name>dfs.datanode.data.dir</name> 
  <value>
    /home/hadoop/develop/data/data1/hdfs, 
    /home/hadoop/develop/data/data2/hdfs 
 </value>
</property>

九.hdfs读写流程

1、写入流程

1.client发起请求上传数据到NameNode

2.NameNode进行检验路径、文件是否存在,是否可以上传,返回结果

3.确定能够上传,继续与NameNode通信,请求第一个block块上传位置

4.NameNode根据DataNode返回的心跳,返回三个比较空闲的机器地址给客户端

5.客户端与第一台机器进行通信,请求上传第一个block块

6.第一台DataNode接收客户端上传的数据,进行完整性ack校验,每个packet64KB,如果没有接收成功会通知client重新上传

2、读取流程

1.NameNode查找元数据,查找文件所有block位置,返回给client

2.客户端得到block地址之后,挨个读取位于DataNode中的block并拼接

十.NameNode和secondaryNameNode功能剖析

1、NameNode和secondaryNameNode解析

hdfs是一个分布式文件存储系统

1.NameNode:主节点,主要用于集群管理和元数据存储

2.DataNode:从节点,主要用于数据存储

3.元数据:描述数据的数据,比如文件名称、位置、大小、属性权限、创建时间、修改时间等。元数据信息非常重要

如hdfs存储了1000万个文件,就有1000万个元数据信息

4.为了快速检索元数据将元数据保存在内存中

5.为了保证内存的数据安全性,同步一份元数据信息到fsimage文件持久化保存

6.hdfs元数据保存在fsimage中,fsimage文件操作不方便,使用了edits编辑日志来每次记录用户操作的元数据

7.edits文件越来越大,设置大小,进行滚动生成新的edits文件,新的edits与fsimage进行合并

8.secondaryNameNode负责合并edits文件和fsimage,生成新的fsimage发送给NameNode,替换旧的fsimage

2、FSImage与edits详解

所有元数据信息都记录在FSImage和edits文件中,元数据信息保存目录配置在hdfs-site.xml文件中:

<!-- fsimage⽬录 -->
<property>
 <name>dfs.namenode.name.dir</name>
 <value>file:///opt/install/hadoop-2.6.0-cdh5.14.2/hadoopDatas/namenodeDatas</value> 
</property>

<!-- edit⽂件⽬录 -->
<property>
  <name>dfs.namenode.edits.dir</name>
  <value>file:///opt/install/hadoop-2.6.0-cdh5.14.2/hadoopDatas/dfs/nn/edits</value> 
</property>

3、查看那FSImage和edit文件信息

使用命令hdfs oiv和hdfs oev

hdfs oiv    #查看帮助信息
hdfs oiv -i fsimage_0000000000000000864 -p XML -o /home/hadoop/fsimage1.xml



hdfs oev     #查看帮助信息
hdfs oev -i edits_0000000000000000865-0000000000000000866 -o /home/hadoop/myedit.xml -p XML

4、NameNode配置元数据信息多路径保存

为了保证元数据的安全性,可以配置多个目录

hdfs-site.xml
<property>
  <name>dfs.namenode.name.dir</name>
  <value>file:///opt/install/hadoop-2.6.0-cdh5.14.2/hadoopDatas/namenodeDatas,file:///path/to/another/</value> 
</property>

十一.hdfs小文件治理

1、hdfs存储太多小文件会造成产生太多元数据信息给NameNode内存压力

尽量避免大量小文件

2、HAR方案

本质启动MapReduce程序,需要启动yarn,多个小文件做成HAR归档文件

第⼀步:创建归档⽂件
注意:归档⽂件⼀定要保证yarn集群启动

cd /opt/install/hadoop-3.1.4
bin/hadoop archive -archiveName myhar.har -p /testhar -r 3 th1 th2 /user

第⼆步:查看归档⽂件内容

hdfs dfs -ls -R /user/myhar.har
hdfs dfs -ls -R har:///user/myhar.har

第三步:解压归档⽂件

hdfs dfs -mkdir -p /user/har
hdfs dfs -cp har:///user/myhar.har/* /user/har/
hdfs dfs -ls -R /user/har

3、Sequence Files⽅案

把小文件压缩打包

1.向SequenceFile写⼊数据
package com.opt.hadoop.sequencefile;
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 org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.SequenceFile;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.compress.BZip2Codec;
import java.io.IOException;
import java.net.URI;
public class SequenceFileWriteNewVersion { 
   //模拟数据源;数组中⼀个元素表示⼀个⽂件的内容 
   private static final String[] DATA = {
           "The Apache Hadoop software library is a framework that 
allows for the distributed processing of large data sets across clusters 
of computers using simple programming models.", "It is designed to scale up from single servers to thousands 
of machines, each offering local computation and storage.",
           "Rather than rely on hardware to deliver high-availability, 
the library itself is designed to detect and handle failures at the 
application layer",
           "o delivering a highly-available service on top of a cluster 
of computers, each of which may be prone to failures.",
           "Hadoop Common: The common utilities that support the other 
Hadoop modules."
   };
  public static void main(String[] args) throws IOException {
       //输出路径:要⽣成的SequenceFile⽂件名
       String uri = "hdfs://bigdata01:8020/writeSequenceFile";
       Configuration conf = new Configuration();
       FileSystem fs = FileSystem.get(URI.create(uri), conf);
       //向HDFS上的此SequenceFile⽂件写数据
       Path path = new Path(uri);
       //因为SequenceFile每个record是键值对的
       //指定key类型
       IntWritable key = new IntWritable(); //key数字 -> int ->
IntWritable
       //指定value类型
       Text value = new Text();//value -> String -> Text 
       //创建向SequenceFile⽂件写⼊数据时的⼀些选项
       //要写⼊的SequenceFile的路径
       SequenceFile.Writer.Option pathOption       = 
SequenceFile.Writer.file(path);
       //record的key类型选项
       SequenceFile.Writer.Option keyOption        = 
SequenceFile.Writer.keyClass(IntWritable.class);
       //record的value类型选项
       SequenceFile.Writer.Option valueOption      = 
SequenceFile.Writer.valueClass(Text.class);
       //SequenceFile压缩⽅式:NONE | RECORD | BLOCK三选⼀ 
       //⽅案⼀:RECORD、不指定压缩算法
//        SequenceFile.Writer.Option compressOption   =
SequenceFile.Writer.compression(SequenceFile.CompressionType.RECORD); 
//        SequenceFile.Writer writer = SequenceFile.createWriter(conf, 
pathOption, keyOption, valueOption, compressOption);
       //⽅案⼆:BLOCK、不指定压缩算法
    //        SequenceFile.Writer.Option compressOption   =
SequenceFile.Writer.compression(SequenceFile.CompressionType.BLOCK); 
//        SequenceFile.Writer writer = SequenceFile.createWriter(conf, 
pathOption, keyOption, valueOption, compressOption);
       //⽅案三:使⽤BLOCK、压缩算法BZip2Codec;压缩耗时间 
       //再加压缩算法
       BZip2Codec codec = new BZip2Codec(); 
       codec.setConf(conf);
       SequenceFile.Writer.Option compressAlgorithm =
SequenceFile.Writer.compression(SequenceFile.CompressionType.RECORD, 
codec);
       //创建写数据的Writer实例
       SequenceFile.Writer writer = SequenceFile.createWriter(conf, 
pathOption, keyOption, valueOption, compressAlgorithm);
       for (int i = 0; i < 100000; i++) { 
           //分别设置key、value值
           key.set(100000 - i);
           value.set(DATA[i % DATA.length]); //%取模 3 % 3 = 0;
           System.out.printf("[%s]\t%s\t%s\n", writer.getLength(), key, 
value);
           //在SequenceFile末尾追加内容 
           writer.append(key, value); 
       }
       //关闭流
       IOUtils.closeStream(writer); 
   }
}
2.查看sequence file内容
hadoop fs -text /writeSequenceFile
3.读取SequenceFile⽂件
package com.opt.hadoop.sequencefile;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.SequenceFile;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.util.ReflectionUtils;
import java.io.IOException;
public class SequenceFileReadNewVersion {
   public static void main(String[] args) throws IOException {
       //要读的SequenceFile
       String uri = "hdfs://bigdata01:8020/writeSequenceFile";
       Configuration conf = new Configuration();
       Path path = new Path(uri);
       //Reader对象
       SequenceFile.Reader reader = null;
       try {
           //读取SequenceFile的Reader的路径选项
           SequenceFile.Reader.Option pathOption = 
SequenceFile.Reader.file(path);
           //实例化Reader对象
           reader = new SequenceFile.Reader(conf, pathOption); 
           //根据反射,求出key类型对象
           Writable key = (Writable)
                   ReflectionUtils.newInstance(reader.getKeyClass(), 
conf);
           //根据反射,求出value类型对象 
           Writable value = (Writable)
                   ReflectionUtils.newInstance(reader.getValueClass(), 
conf);
           long position = reader.getPosition(); 
           System.out.println(position);
           while (reader.next(key, value)) {
               String syncSeen = reader.syncSeen() ? "*" : ""; 
               System.out.printf("[%s%s]\t%s\t%s\n", position, 
syncSeen, key, value);
               //移动到下⼀个record开头的位置
               position = reader.getPosition(); // beginning of next 
record
           }
       } finally {
           IOUtils.closeStream(reader); 
       }
   }
 }

十一.HDFS其他功能介绍

1、多个集群之间的拷贝

在我们实际⼯作当中,极有可能会遇到将测试集群的数据拷贝到⽣产环境集群,或者将⽣产环境集群的数据拷贝到测试集群,那么就需要我们在多个集群之间进⾏数据的远程拷贝,hadoop⾃带也有命令可以帮我们实现这个功能

1.本地⽂件拷贝scp
cd /opt/soft
scp -r jdk-8u141-linux-x64.tar.gz hadoop@bigdata02:/opt/soft
2. 集群之间的数据拷贝distcp
bin/hadoop distcp hdfs://bigdata01:8020/jdk-8u141-linux-x64.tar.gz hdfs://cluster2:8020/path/to/dir

2、hdfs快照snapShot管理

快照顾名思义,就是相当于对我们的hdfs⽂件系统做⼀个备份,我们可以通过快照对我们指定的⽂件夹设置备份,但是添加快照之后,不会⽴即复制所有⽂件,⽽是指向同⼀个⽂件。当写⼊发⽣时,才会产⽣新⽂件

1.快照使⽤基本语法
1、开启指定⽬录的快照功能
 hdfs dfsadmin -allowSnapshot 路径
 
2、禁⽤指定⽬录的快照功能(默认就是禁⽤状态) 
 hdfs dfsadmin -disallowSnapshot 路径
 
3、给某个路径创建快照snapshot 
 hdfs dfs -createSnapshot 路径
 
4、指定快照名称进⾏创建快照snapshot
 hdfs dfs -createSanpshot 路径 名称   
 
5、给快照重新命名
hdfs dfs -renameSnapshot 路径    旧名称    新名称

6、列出当前⽤户所有可快照⽬录 
 hdfs lsSnapshottableDir  
 
7、⽐较两个快照的⽬录不同之处 
 hdfs snapshotDiff 路径1 路径2
 
8、删除快照snapshot
 hdfs dfs -deleteSnapshot <path> <snapshotName>

3、HDFS回收站

任何⼀个⽂件系统,基本上都会有垃圾桶机制,也就是删除的⽂件,不会直接彻底清掉,我们⼀把都是将⽂件放置到垃圾桶当中去,过⼀段时间之后,⾃动清空垃圾桶当中的⽂件,这样对于⽂件的安全删除⽐较有保证,避免我们⼀些误操作,导致误删除⽂件或者数据

1.回收站配置两个参数
默认值fs.trash.interval=0,0表示禁⽤回收站,可以设置删除⽂件的存活时间
默认值fs.trash.checkpoint.interval=0,检查回收站的间隔时间
要求fs.trash.checkpoint.interval <= fs.trash.interval
2.启⽤回收站

修改所有服务器的core-site.xml配置⽂件

<!-- 开启hdfs的垃圾桶机制,删除掉的数据可以从垃圾桶中回收,单位分钟 -->
<property>
<name>fs.trash.interval</name> 
<value>10080</value>
</property>
3.查看回收站

回收站在集群的/user/hadoop/.Trash/ 这个路径下

4.通过javaAPI删除的数据,不会进⼊回收站,需要调⽤moveToTrash()才会进⼊回收站
Trash trash = New Trash(conf); 
trash.moveToTrash(path);
5.恢复回收站数据
hdfs dfs -mv trashFileDir  hdfsdir 
trashFileDir :回收站的⽂件路径 
hdfsdir :将⽂件移动到hdfs的哪个路径下
6.清空回收站
# 跳过回收站,彻底删除⽂件
hdfs dfs -rm -r -skipTrash /wc06 
Deleted /wc06

# 清空回收站
hdfs dfs -expunge

十二.总结

1、hdfs的特性

2、hdfs的架构设计

3、NameNode作用

4、DataNode作用

5、hdfs的shell操作

6、hdfs优缺点

7、hdfs的java api

8、hdfs读写流程

9、hdfs元数据管理与secondaryNameNode

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值