欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Hadoop分布式文件系统-HDFS

程序员文章站 2022-07-14 15:19:47
...

Hadoop自带一个称为HDFS的分布式文件系统,即Hadoop Distributed FileSystem。管理网络中跨多台计算机存储的文件系统称为分布式文件系统(distributed filesystem)。

参考资料

  1. 《Hadoop权威指南(第4版)》

目录

  1. HDFS的设计
  2. HDFS的概念
  3. 命令行接口
  4. Hadoop文件系统
  5. Java接口
  6. 数据流
  7. 通过distcp并行复制

HDFS的设计

支持超大文件

超大文件是指几百MB,几百GB,甚至是几百TB大小的文件。

2008年的时候yahoo将hadoop应用扩展到4000个节点,存储PB级别的数据

支持流式数据访问

HDFS构建思路:一次写入,多次读取是最高效的访问模式。

TODO 一次写入,多次读取和流式数据访问有什么关系?

支持商用硬件

并不需要昂贵且可靠的专用硬件,普通商用硬件即可。

不建议大量的小文件

HDFS所能存储的文件总数受限于namenode的内存大小。根据经验,每个文件,目录和数据块的存储信息大约占150个字节。

假设有一百万个文件,且每个文件占一个数据块,那至少需要300M内存。如果文件数量达十亿个时,那需要的就是高达300G内存。

不支持低时间延迟的数据访问

HDFS是为高吞吐量应用优化的,所以会以提高时间延迟来作为代价。

如果需要低延迟的访问需求,可以选择HBase。

不支持多用户写入,任意修改文件

HDFS中的文件写入只支持单个写入者,而且写操作总是以“只添加”方式在文件末尾写数据。

HDFS的概念

数据块

HDFS中块(block)的默认大小为128M,一般磁盘块大小为512字节,HDFS的块设置为这么大的原因主要是为了最小化寻址开销,块的大小设置还要考虑到对MapReduce中map任务的影响,因为map任务一般一次只处理一个块中的数据,所以块如果过大会导致任务数太少,影响性能。

与单一磁盘的文件系统不同的是,HDFS中小于一个块大小的文件不会占据整个块的空间。例如:一个1MB文件存储在一个128M块中时,文件只使用1MB的磁盘空间,而不是128M.

数据块概念带来的好处:

  1. 简化了存储子系统的设计。namenode和datanode的设计。
  2. 允许一个文件的大小大于网络中任意一个磁盘的容易

namenode和datanode

  • namenode为管理节点,维护着文件系统树及整棵树内所有的文件和目录。记录每个文件中各个块所在的数据节点信息,但是不永久保存块的位置信息,因为系统启动时块的位置信息会根据数据节点信息重建。
  • datanode为工作节点(也称数据节点),受客户端和namenode调度,根据需要存储并检索数据块,并且定期向namenode发送它们所存储的块的列表。

块缓存

datanode从磁盘中读取块,但对于访问频繁的文件,其对应的块可能被显式地缓存在datanode的内存中,以堆外块缓存的形式存在。

联邦HDFS

在hadoop2.X发行版本系列中引入的联邦HDFS允许系统通过添加namenode实现扩展,其中每个namenode管理文件系统命名空间的一部分。

例如,一个namenode管理/user目录下的所有文件,而另一个namenode管理/share目录下的所有文件

在联邦环境下,每个namenode维护一个命名空间卷(namespace volume),由命名空间的元数据和一个数据块池(block pool)组成,数据块池包含该命名空间下文件的所有数据块。

命名空间卷是互相独立的,两两之间并不互相通信。

HDFS的高可用

TODO

命令行接口

// 新建文件夹
hadoop fs -mkdir books

// 将文件复制到HDFS
hadoop fs -copyFromLocal /hgy/test.txt hdfs://xmasq223:9000/hgy/test.txt

// 将文件复制到本地
hadoop fs -copyToLocal hdfs://xmasq223:9000/hgy/test.txt /hgy/test1.txt
 
// 查看指定列表
hadoop fs -ls /hgy

提供三类权限:r-只读权限,w-写入权限,x-可执行权限,可执行权限可以忽略。

Hadoop文件系统

抽象类:FileSystem,实现类如下:

文件系统 URI方案 Java实现(都在org.apache.hadoop包中) 描述
Local file fs.LocalFileSystem 使用客户端校验和的本地磁盘文件系统
HDFS hdfs hdfs.DistributedFileSystem Hadoop的分布式文件系统。将HDFS设计成与MapReduce结合使用,可以实现高性能
WebHDFS Webhadfs
Secure WebHDFS swebhadfs
HAR har
View viewfs
FTP ftp
S3 S3a
Azure wasb
Swift swift

Java接口

package com.xmasq.demo;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.io.IOUtils;

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

/**
 * @author guoyu.huang
 * @version 1.0.0
 */
public class Demo {

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

        Properties properties = System.getProperties();
        properties.setProperty("HADOOP_USER_NAME", "root");

        try {
            String fileUrl = "hdfs://xmasq223:9000/hgy/newTest.txt";
            addFile(fileUrl);
            getByFileSystem(fileUrl);
            delete(fileUrl);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 添加文件及内容
     *
     * @param fileUrl
     * @throws IOException
     */
    public static void addFile(String fileUrl) throws IOException {

        // 因为我使用阿里云内网,所以一定使用hostname进行访问
        Configuration configuration = new Configuration();
        configuration.set("dfs.client.use.datanode.hostname", "true");
        FileSystem fileSystem = FileSystem.get(URI.create(fileUrl), configuration);

        FSDataOutputStream out = fileSystem.create(new Path(fileUrl));
        out.write("This is new test file.".getBytes());
        out.close();
    }

    /**
     * 删除文件
     *
     * @param fileUrl
     * @throws IOException
     */
    public static void delete(String fileUrl) throws IOException {
        // 因为我使用阿里云内网,所以一定使用hostname进行访问
        Configuration configuration = new Configuration();
        configuration.set("dfs.client.use.datanode.hostname", "true");
        FileSystem fileSystem = FileSystem.get(URI.create(fileUrl), configuration);

        fileSystem.delete(new Path(fileUrl), true);
    }

    /**
     * 读取数据
     *
     * @param fileUrl
     * @throws IOException
     */
    public static void getByFileSystem(String fileUrl) throws IOException {

        // 因为我使用阿里云内网,所以一定使用hostname进行访问
        Configuration configuration = new Configuration();
        configuration.set("dfs.client.use.datanode.hostname", "true");

        FileSystem fileSystem = FileSystem.get(URI.create(fileUrl), configuration);
        FSDataInputStream in = fileSystem.open(new Path(fileUrl));
        IOUtils.copyBytes(in, System.out, 4096, false);
    }
}


数据流

文件读取

通过以上代码获得流程图

Hadoop分布式文件系统-HDFS

文件写入

通过以上代码获得流程图
Hadoop分布式文件系统-HDFS

一致模型

TODO

通过distcp并行复制

TODO