Hadoop之HDFS入门实战

Posted 女友在高考

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hadoop之HDFS入门实战相关的知识,希望对你有一定的参考价值。

一、HDFS优缺点

优点:

  1. 高容错性
    • 数据自动保存多个副本
    • 某一个副本丢失后,它可以自动恢复
  2. 适合处理大数据
    • 数据规模,可以达到PB级
    • 文件规模,能够处理百万规模的文件数量
  3. 可构建在廉价机器上,通过多副本保证可靠性

缺点:

  1. 不适合低延时数据访问
  2. 不适合对大量小文件进行存储
    • 存储大量小文件,他会占用NameNode大量内存存储目录和块信息,这样不可取,因为NameNode的内存有限
    • 小文件存储的寻址时间会超过读取时间,违反HDFS设计目标
  3. 不支持并发写入、随机修改
    • 一个文件只能一个线程写入
    • 只支持追加写入,不支持随机修改

二、HDFS组成结构

  1. NameNode
  • 管理HDFS的名称空间
  • 配置副本策略
  • 管理数据块映射信息
  • 处理客户端请求
  1. DataNode
  • 存储实际的数据库
  • 执行数据块的读/写
  1. Client
  • 文件切分,文件上传时,Client将文件切分为一个一个块
  • 与NameNode交互,获取文件位置
  • 与DataNode交互,读取或写入数据
  • 提供一些命令管理HDFS
  1. Secondary NameNode
  • 辅助NameNode
  • 紧急情况下,可以恢复NameNode

HDFS在文件上是分块存储的,2.x版本默认块大小是128M,可以通过dfs.blocksize配置。HDFS块大小取决于磁盘传输速率

三、HDFS的Shell操作

  1. 启动Hadoop
sbin/start-dfs.sh
sbin/start-yarn.sh
  1. -help :帮助命令

hadoop fs -help rm

  1. -ls :显示目录信息

hadoop fs -ls /

  1. -mkdir :创建目录
    加-p 代表创建多级目录

hadoop fs -mkdir /study
hadoop fs -mkdir -p /study/mmc

  1. -moveFromLocal :从本地剪切到HDFS

hadoop fs -moveFromLocal test.txt /usr/mmc

  1. -appendToFile :追加一个文件到已存在的文件末尾

hadoop fs -appendToFile test2.txt /usr/mmc/test.txt

  1. -cat :显示文件内容

hadoop fs -cat /usr/mmc/test.txt

  1. -chgrp、-chmod、-chown :和linux文件系统用法一样
  2. -copyFromLocal :从本地复制到HDFS中
  3. -copyToLocal :从HDFS拷贝到本地

hadoop fs -copyToLocal /usr/mmc/test.txt ./test.txt

  1. -cp :从HDFS的一个路径拷到另一个路径

hadoop fs -cp /usr/mmc/test.txt /study/mmc

  1. -mv :在HDFS中移动文件
  2. -get :等同于copyToLocal

hadoop fs -get /usr/mmc/test.txt

  1. -getmerge :合并下载多个文件

hadoop fs -getmerge /usr/mmc/* merge.txt

  1. -put :等同于copyFromLocal
  2. -tail :显示一个文件的末尾

hadoop fs -tail /usr/mmc/test.txt

  1. -rm :删除文件或文件夹

hadoop fs -rm /study/mmc/test.txt

  1. -rmdif :删除空目录
  2. -du :统计文件夹大小

hadoop fs -du -h /

  1. -setrep :设置HDFS文件的副本数

四、HDFS的客户端操作

  1. 启动虚拟机上部署的Hadoop
  2. windows本机环境变量设置(可不设置)
  • 在系统变量中新建
  • 在系统变量的PATH中增加如下:
  1. java客户端操作HDFS
  • 引入pom文件

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.8.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-common -->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>2.10.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>2.10.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>2.10.0</version>
        </dependency>
    </dependencies>
  • demo
public class HDFSClient {

    public static void main(String[] args) throws IOException, URISyntaxException, InterruptedException {
        Configuration configuration=new Configuration();
        //获取客户端连接
        FileSystem fs=FileSystem.get(new URI("hdfs://192.168.1.21:9000"),configuration,"root");

        //创建目录
        fs.mkdirs(new Path("/mmc"));

        //关闭资源
        fs.close();

        System.out.println("over");
    }
}
  1. API操作

很简单,自己看api就会用

public class HDFSClient {

    public static void main(String[] args) throws IOException, URISyntaxException, InterruptedException {

    }

    FileSystem fs;

    @Before
    public void before() throws URISyntaxException, IOException, InterruptedException {
        Configuration configuration=new Configuration();
        //获取客户端连接
        fs=FileSystem.get(new URI("hdfs://192.168.1.21:9000"),configuration,"root");
    }

    @Test
    public void testmkdir() throws URISyntaxException, IOException, InterruptedException {

        //创建目录
        fs.mkdirs(new Path("/mmc"));

        //关闭资源
        fs.close();

        System.out.println("over");
    }

    /**
     * 上传文件
     * @throws IOException
     */
    @Test
    public void testCopyFromLocalFile() throws IOException {
        fs.copyFromLocalFile(new Path("d://a.txt"),new Path("/mmc"));
    }


    /**
     * 删除文件
     * @throws IOException
     */
    @Test
    public void testDelete() throws IOException {
        fs.delete(new Path("/mmc"),true);
    }


    /**
     * 查看文件详情
     * @throws IOException
     */
    @Test
    public void testListFiles() throws IOException {
        RemoteIterator<LocatedFileStatus> iterator = fs.listFiles(new Path("/usr"), true);
        while (iterator.hasNext()){
            LocatedFileStatus fileStatus = iterator.next();
            if(fileStatus.isFile()){
                System.out.println(fileStatus.getPath().getName());
                System.out.println(fileStatus.getPermission());
                System.out.println(fileStatus.getLen());
            }

        }
    }
}
  1. 操作文件IO流

/**
 * @description: IO流操作HDFS
 * @author: mmc
 * @create: 2020-05-28 23:01
 **/

public class HDFSIO {

    /**
     * 上传文件
     * @throws URISyntaxException
     * @throws IOException
     * @throws InterruptedException
     */
    @Test
    public void putFileToHDFS() throws URISyntaxException, IOException, InterruptedException {
        Configuration configuration=new Configuration();
        //获取客户端连接
        FileSystem fs=FileSystem.get(new URI("hdfs://192.168.1.21:9000"),configuration,"root");

        //获取输入流
        FileInputStream fis=new FileInputStream("d://a.txt");


        //获取输出流
        FSDataOutputStream outputStream = fs.create(new Path("/usr/mmc/a.txt"));

        //复制流
        IOUtils.copyBytes(fis,outputStream,configuration);

        IOUtils.closeStream(fis);
        IOUtils.closeStream(outputStream);
        fs.close();

    }


    @Test
    public void getFileFromHDFS() throws URISyntaxException, IOException, InterruptedException{
        Configuration configuration=new Configuration();
        //获取客户端连接
        FileSystem fs=FileSystem.get(new URI("hdfs://192.168.1.21:9000"),configuration,"root");

        //输入流
        FSDataInputStream inputStream = fs.open(new Path("/usr/mmc/a.txt"));

        FileOutputStream outputStream=new FileOutputStream("e://b.txt");

        IOUtils.copyBytes(inputStream,outputStream,configuration);

        IOUtils.closeStream(outputStream);
        IOUtils.closeStream(inputStream);
        fs.close();
    }

    /**
     *  下载部分文件
     * @throws URISyntaxException
     * @throws IOException
     * @throws InterruptedException
     */
    public void readFileSeek1() throws URISyntaxException, IOException, InterruptedException{
        Configuration configuration=new Configuration();
        //获取客户端连接
        FileSystem fs=FileSystem.get(new URI("hdfs://192.168.1.21:9000"),configuration,"root");

        //输入流
        FSDataInputStream inputStream = fs.open(new Path("/usr/mmc/a.txt"));

        FileOutputStream outputStream=new FileOutputStream("e://b.txt.part1");

        //只拷贝部分流(128M)
        byte[] buf=new byte[1024];
        for (int i=0;i<1024*128;i++){
            inputStream.read(buf);
            outputStream.write(buf);
        }

        IOUtils.closeStream(outputStream);
        IOUtils.closeStream(inputStream);
        fs.close();

    }

    /**
     * 下载剩余部分文件
     * @throws URISyntaxException
     * @throws IOException
     * @throws InterruptedException
     */
    public void readFileSeek2() throws URISyntaxException, IOException, InterruptedException{
        Configuration configuration=new Configuration();
        //获取客户端连接
        FileSystem fs=FileSystem.get(new URI("hdfs://192.168.1.21:9000"),configuration,"root");

        //输入流
        FSDataInputStream inputStream = fs.open(new Path("/usr/mmc/a.txt"));

        //指定起点开始读取
        inputStream.seek(1024*1024*128);

        FileOutputStream outputStream=new FileOutputStream("e://b.txt.part2");

        IOUtils.copyBytes(inputStream,outputStream,configuration);

        IOUtils.closeStream(outputStream);
        IOUtils.closeStream(inputStream);
        fs.close();

    }
}
  1. HDFS读写数据流程
    写数据:

    读数据:

以上是关于Hadoop之HDFS入门实战的主要内容,如果未能解决你的问题,请参考以下文章

Hadoop HDFS编程 API入门系列之HDFS_HA

Hadoop HDFS编程 API入门系列之合并小文件到HDFS

Hadoop HDFS编程 API入门系列之从本地上传文件到HDFS

Hadoop HDFS编程 API入门系列之路径过滤上传多个文件到HDFS

Hadoop HDFS编程 API入门系列之HdfsUtil版本1

Hadoop HDFS编程 API入门系列之RPC版本2