Hadoop学习笔记(三)HDFS部分上

Hadoop——HDFS部分上

一、HDFS概述

1.1 HDFS定义

​ HDFS(Hadoop Distributed File System),它是一个文件系统,用于存储文件,通过目录树来定位文件;其次,它是分布式的,由很多服务器联合起来实现其功能,集群中的服务器有各自的角色。

​ HDFS的使用场景:适合一次性写入,多次读出的场景,且不支持文件的修改。适合用来做数据分析,并不适合用来做网盘应用。

1.2 HDFS优缺点

优点:

​ 1、高容错性。数据自动保存多个副本。它通过增加副本的形式,提高容错率。某个副本丢失后可以自动恢复。

​ 2、适合处理大数据。能够处理数据规模达到GB、TB,甚至PB级别的数据。能够处理百万规模以上的文件数量,数量相当之大。

​ 3、可构建在廉价机器上,通过多副本机制,提高可靠性。

缺点:

​ 1、不适合低延时的数据访问,比如毫秒级的存储数据,是做不到的。

​ 2、无法高效地对大量小文件进行存储。存储大量小文件的话,会占用NameNode大量的内存来存储文件目录和块信息。这样是不可取的,因为NameNode的内存是有限的。而且小文件存储的寻址时间会超过读取时间,这违背了HDFS设计目标。

​ 3、不支持并发写入,文件随机修改,一个文件只能有一个写,不允许多个进程同时写。同时仅支持数据追加(append),不支持文件的随机修改。

1.3 HDFS组成架构

在这里插入图片描述

在这里插入图片描述

二、HDFS的Shell操作

2.1基本语法

hadoop fs [具体命令] 或者 hdfs dfs [具体命令]。

2.2 命令大全

[-appendToFile <localsrc> ... <dst>]
        [-cat [-ignoreCrc] <src> ...]
        [-checksum <src> ...]
        [-chgrp [-R] GROUP PATH...]
        [-chmod [-R] <MODE[,MODE]... | OCTALMODE> PATH...]
        [-chown [-R] [OWNER][:[GROUP]] PATH...]
        [-copyFromLocal [-f] [-p] <localsrc> ... <dst>]
        [-copyToLocal [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
        [-count [-q] <path> ...]
        [-cp [-f] [-p] <src> ... <dst>]
        [-createSnapshot <snapshotDir> [<snapshotName>]]
        [-deleteSnapshot <snapshotDir> <snapshotName>]
        [-df [-h] [<path> ...]]
        [-du [-s] [-h] <path> ...]
        [-expunge]
        [-get [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
        [-getfacl [-R] <path>]
        [-getmerge [-nl] <src> <localdst>]
        [-help [cmd ...]]
        [-ls [-d] [-h] [-R] [<path> ...]]
        [-mkdir [-p] <path> ...]
        [-moveFromLocal <localsrc> ... <dst>]
        [-moveToLocal <src> <localdst>]
        [-mv <src> ... <dst>]
        [-put [-f] [-p] <localsrc> ... <dst>]
        [-renameSnapshot <snapshotDir> <oldName> <newName>]
        [-rm [-f] [-r|-R] [-skipTrash] <src> ...]
        [-rmdir [--ignore-fail-on-non-empty] <dir> ...]
        [-setfacl [-R] [{-b|-k} {-m|-x <acl_spec>} <path>]|[--set <acl_spec> <path>]]
        [-setrep [-R] [-w] <rep> <path> ...]
        [-stat [format] <path> ...]
        [-tail [-f] <file>]
        [-test -[defsz] <path>]
        [-text [-ignoreCrc] <src> ...]
        [-touchz <path> ...]
        [-usage [cmd ...]]

其中的 -setrep:设置HDFS中文件的副本数量

hadoop fs -setrep 10 /sanguo/shuguo/kongming.txt        

这里设置的副本数只是记录在 NameNode 的元数据中,是否真的会有这么多副本,还得看 DataNode 的数量。因为目前只有 3 台设备,最多也就 3 个副本,只有节点数的增加到 10 台时,副本数才能达到 10 。

三、HDFS客户端操作

3.1 HDFS客户端环境准备

3.1.1 下载Hadoop3.1.0的windows依赖,并配置环境变量。

在这里插入图片描述

在这里插入图片描述

可以将bin目录下hadoop.dll和winutils.exe放到C:/windows/system32目录下。

windows本地运行mr程序时(不提交到yarn,运行在jvm靠线程执行),很容易报错,所以将两个文件添加到bin目录下。
hadoop.dll防止报nativeio异常winutils.exe没有的话可能报空指针异常

在这里插入图片描述

3.1.2 在IDEA中创建maven工程,并导入相应的依赖坐标和日志添加。
<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-slf4j-impl</artifactId>
        <version>2.12.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-client</artifactId>
        <version>3.1.3</version>
    </dependency>
</dependencies>

在项目的src/main/resources目录下,新建一个文件,命名为“log4j2.xml”,在文件中填入

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error" strict="true" name="XMLConfig">
    <Appenders>
        <!-- 类型名为Console,名称为必须属性 -->
        <Appender type="Console" name="STDOUT">
            <!-- 布局为PatternLayout的方式,
            输出样式为[INFO] [2018-01-22 17:34:01][org.test.Console]I'm here -->
            <Layout type="PatternLayout"
                    pattern="[%p] [%d{yyyy-MM-dd HH:mm:ss}][%c{10}]%m%n" />
        </Appender>
    </Appenders>
    <Loggers>
        <!-- 可加性为false -->
        <Logger name="test" level="info" additivity="false">
            <AppenderRef ref="STDOUT" />
        </Logger>
        <!-- root loggerConfig设置 -->
        <Root level="info">
            <AppenderRef ref="STDOUT" />
        </Root>
    </Loggers>
</Configuration>

3.2 HDFS的API操作

3.2.1 用户名的传递和获得HDFS的操作

客户端去操作HDFS时,是有一个用户身份的。

默认情况下,HDFS客户端API会从JVM中获取一个参数来作为自己的用户身份:

-DHADOOP_USER_NAME=[HDFS文件系统的用户名]

如果不设置的话就会默认以Windows的用户名来作为自己的身份。

在这里插入图片描述

用户名也可以在代码中进行配置

以下代码为执行业务前的必须操作,将其提取放在@Before注解的before()方法中。

public class HDFSDemo {
    private  FileSystem fs;

    @Before
    public void before() throws URISyntaxException, IOException, InterruptedException {
        /**
         * 1、创建客户端对象
         *
         * get(final URI uri, final Configuration conf, final String user)
         *
         * uri:HDFS的地址
         * conf:配置的参数
         * user:用来操作HDFS的用户名
         */
        URI uri = new URI("hdfs://hadoop102:8020");
        Configuration conf = new Configuration();
        fs=FileSystem.get(uri, conf,"[用户名]");
    }
}

业务结束后关闭资源,将其放在@After注解的after()方法中。

 @After
    public void after()   {
        //关闭资源
        try{
            if(fs!=null){
                fs.close();
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try{
                if(fs!=null) {
                    fs.close();
                }
                }catch (IOException e){
                    e.printStackTrace();
            }
        }
    }
3.2.2 下载操作

第4个参数是查看校验和的

/**
     * 从HDFS下载文件到本地
     * @throws IOException
     */
    @Test
    public void testDownLoad() throws IOException {
        fs.copyToLocalFile(false,
                new Path("/input/log4j2.xml"),
                new Path("D:\\Study_Code\\HdfsClientDemo\\src\\main\\resources\\download"),
                true);
    }
3.2.3 将HDFS上的文件删除

第一个参数是文件在HDFS上的路径。

第二个参数,如果删文件的话,true或false都可以,删除目录需要成true。

/**
     * 将HDFS上的文件删除
     * @throws IOException
     */
    @Test
    public void testDel() throws IOException {
        fs.delete(new Path("/input/log4j2.xml"),true);
    }
3.2.4 将HDFS上的文件移动或改名

此方法既可以改名也可以剪切文件。

/**
     * 将HDFS上的文件移动或改名
     */
    @Test
    public void testMoveAndRename() throws IOException {
//        fs.rename(new Path("/input/log4j2.xml"),new Path("/log4j2.xml"));
//        fs.rename(new Path("/log4j2.xml"),new Path("/input/log4j2.xml"));
        fs.rename(new Path("/input/log4j2.xml"),new Path("/input/log.xml"));
    }
3.2.5 HDFS文件和文件夹判断
 /**
     * HDFS文件和文件夹判断
     */
    @Test
    public void testListStatus() throws IOException {
        FileStatus[] fileStatus = fs.listStatus(new Path("/"));
        for (FileStatus status : fileStatus) {
            if(status.isFile()) System.out.println("f: "+status.getPath().getName());
            else if(status.isDirectory()) System.out.println("d: "+status.getPath().getName());
            else System.out.println("ERROR!!!");
        }
    }
}
3.2.6 从HDFS中获取文件的细节信息
/**
     * 从HDFS中获取文件的细节信息
     * @throws IOException
     */
    @Test
    public void testFileDetails() throws IOException {
       RemoteIterator<LocatedFileStatus> fileList = fs.listFiles(new Path("/input"),true);
        while(fileList.hasNext()){
            LocatedFileStatus fileStatus = fileList.next();
            System.out.println("==="+fileStatus.getPath().getName()+"===");
            System.out.println("副本数: "+fileStatus.getReplication());
            System.out.println("块大小: "+fileStatus.getBlockSize());
            System.out.println("文件大小: "+fileStatus.getLen());
            BlockLocation[] blockLocations=fileStatus.getBlockLocations();
            System.out.println("块信息 :"+Arrays.toString(blockLocations));

        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值