大数据技术-Hadoop(二)HDFS的介绍与使用

目录

1、HDFS简介

[1.1 什么是HDFS](#1.1 什么是HDFS)

[1.2 HDFS的优点](#1.2 HDFS的优点)

1.3、HDFS的架构

[1.3.1、 NameNode](#1.3.1、 NameNode)

[1.3.2、 NameNode的职责](#1.3.2、 NameNode的职责)

1.3.3、DataNode

[1.3.4、 DataNode的职责](#1.3.4、 DataNode的职责)

[1.3.5、Secondary NameNode](#1.3.5、Secondary NameNode)

[1.3.6、Secondary NameNode的职责](#1.3.6、Secondary NameNode的职责)

2、HDFS的工作原理

2.1、文件存储

[2.2 、数据写入](#2.2 、数据写入)

[2.3、 数据读取](#2.3、 数据读取)

[2.4、 容错机制](#2.4、 容错机制)

2.5、元数据管理

3、HDFS的Shell操作

4、HDFS的API操作

4.1、配置客户端环境变量

4.2、客户端api的使用

5、参考

6、附录

1、window环境下的hadoop依赖

2、完整代码


1、HDFS简介

1.1 什么是HDFS

HDFS是Hadoop生态系统中的一个分布式文件系统,旨在在集群的廉价硬件上可靠地存储大数据集。HDFS设计为高容错,并为高吞吐量数据访问而优化,适用于在商用硬件上运行的大数据应用。

1.2 HDFS的优点

  • 高容错性:数据通过副本机制存储在多个节点上,确保在硬件故障时数据的高可用性。
  • 高吞吐量:通过批量处理大数据,HDFS优化了数据的读写速度。
  • 可扩展性:通过添加节点,可以轻松扩展HDFS的存储容量和计算能力。
  • 可靠性:通过分布式架构和数据冗余,确保数据在系统故障情况下的完整性和可用性。

1.3、HDFS的架构

HDFS采用主从架构,主要由NameNode和DataNode两类节点组成。

1.3.1、 NameNode

NameNode是HDFS的主节点,负责管理文件系统的命名空间和文件块的映射关系。它存储所有文件和目录的元数据(如文件名、权限、块位置等),并协调客户端对数据的访问请求。

1.3.2、 NameNode的职责

文件系统命名空间管理:管理文件和目录的结构,维护元数据。

  • 块管理:管理文件与块的映射关系,以及块在DataNode上的存储位置。
  • 集群管理:监控DataNode的健康状态,处理节点故障。

1.3.3、DataNode

DataNode是HDFS的工作节点,负责存储实际的数据块。每个DataNode定期向NameNode发送心跳信号,报告其健康状态和存储情况。

1.3.4、 DataNode的职责

  • 数据存储:存储HDFS文件的数据块。
  • 数据块报告:定期向NameNode发送数据块列表,报告其存储情况。
  • 数据块操作:执行客户端请求的读写操作,负责数据块的创建、删除和复制。

1.3.5、Secondary NameNode

Secondary NameNode并不是NameNode的热备份,而是辅助NameNode进行元数据管理的节点。它定期获取NameNode的元数据快照并合并编辑日志,以减轻NameNode的负载。

1.3.6、Secondary NameNode的职责

  • 元数据快照:定期从NameNode获取元数据快照。
  • 合并编辑日志:将元数据快照与编辑日志合并,生成新的元数据文件,减轻NameNode的内存压力。

2、HDFS的工作原理

HDFS通过分布式存储和冗余机制,实现高可靠性和高可用性。以下是HDFS的几个关键工作原理。

2.1、文件存储

HDFS将文件分割成固定大小的块(3.x默认为128MB),并将这些块存储在不同的DataNode上。每个块会被复制到多个DataNode(默认3个副本),以确保数据的可靠性。

2.2 、数据写入

当客户端向HDFS写入数据时,数据首先被分割成块,并通过Pipeline机制写入到多个DataNode。具体步骤如下:

  • 客户端请求NameNode:客户端向NameNode请求写入文件。
  • NameNode分配块和DataNode:NameNode为文件分配数据块并选择存储这些块的DataNode。
  • 客户端写入数据块:客户端将数据块写入第一个DataNode,第一个DataNode再将数据块复制到第二个DataNode,依此类推。
  • 数据块确认:当所有副本写入成功后,客户端接收到确认消息,表示数据写入完成。

2.3、 数据读取

当客户端从HDFS读取数据时,NameNode提供数据块的位置信息,客户端直接从相应的DataNode读取数据。具体步骤如下:

  • 客户端请求NameNode:客户端向NameNode请求读取文件。
  • NameNode返回块位置:NameNode返回文件块所在的DataNode列表。
  • 客户端读取数据块:客户端直接从DataNode读取数据块,并在本地合并这些数据块,恢复成完整的文件。

2.4、 容错机制

HDFS通过数据块副本机制实现容错。当DataNode发生故障时,NameNode会检测到该DataNode的心跳信号丢失,并在其他健康的DataNode上重新复制丢失的数据块。

2.5、元数据管理

NameNode负责管理文件系统的元数据,包括文件名、目录结构、权限和数据块位置等。为了保证元数据的一致性和持久性,NameNode将元数据存储在内存中,并定期写入到本地磁盘。

3、HDFS的Shell操作

hadoop fs 具体命令 OR hdfs dfs 具体命令

bash 复制代码
#从本地粘贴到HDFS
hadoop fs -copyFromLocal a.txt /demo
hadoop fs  -put a.txt /

#-rm -r:递归删除目录及目录里面内容;-rm:删除文件或文件夹
hadoop fs -rm -r /demo/a.txt

#-moveFromLocal:从本地剪切粘贴到HDFS
hadoop fs -moveFromLocal a.txt /demo

#-appendToFile:追加一个文件到已经存在的文件末尾
hadoop fs -appendToFile b.txt /demo/a.txt

#-copyToLocal:从HDFS拷贝到本地
hadoop fs -copyToLocal /demo/a.txt /usr/local/hadoop-3.4.0
hadoop fs -get /demo/a.txt /usr/local/hadoop-3.4.0

#显示目录
hadoop fs -ls /demo

#查看内容
hadoop fs -cat /demo/a.txt

#创建路径
hadoop fs -mkdir /demo

#复制
hadoop fs -cp /a.txt /demo/

#-tail:显示一个文件的末尾1kb的数据
hadoop fs -tail /demo/a.txt

#查看大小
hadoop fs -du -h /demo

#-setrep:设置HDFS中文件的副本数量,副本数超过DataNode时,并不会创建那么多副本,只有当有足够的节点数时才会创建
hadoop fs -setrep 2 /demo/a.txt

4、HDFS的API操作

4.1、配置客户端环境变量

配置环境变量

配置path变量

重启电脑使变量生效

4.2、客户端api的使用

java 复制代码
package com.xiaojie.hadoop.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.SimpleDateFormat;
import java.util.Arrays;

@Component
@Slf4j
public class HdfsClientUtil {

    @Value("${wssnail.hdfs.url}")
    private String url;

    @Value("${wssnail.hdfs.user-name}")
    private String userName;

    @Autowired
    private Configuration configuration;

    //创建文件
    public void mkDirs() throws URISyntaxException, IOException, InterruptedException {
        //获取文件系统
        FileSystem fs = FileSystem.get(new URI(url), configuration, userName);
        // 2 创建目录
        fs.mkdirs(new Path("/hello/world"));
        // 3 关闭资源
        fs.close();
        log.info("创建目录成功>>>>>>>>>>>>>>>");
    }

    //上传文件
    public void putFile() throws URISyntaxException, IOException, InterruptedException {
        //设置副本数
        configuration.set("dfs.replication", "2");
        FileSystem fs = FileSystem.get(new URI(url), configuration, userName);
        // 2 上传文件
        fs.copyFromLocalFile(new Path("d:/hello.txt"), new Path("/"));
        // 3 关闭资源
        fs.close();
    }

    //下载文件
    public void downloadFile() throws URISyntaxException, IOException, InterruptedException {
        // 1 获取文件系统
        FileSystem fs = FileSystem.get(new URI(url), configuration, userName);
        // 2 执行下载操作
        // boolean delSrc 指是否将原文件删除
        // Path src 指要下载的文件路径
        // Path dst 指将文件下载到的路径
        // boolean useRawLocalFileSystem 是否开启文件校验
        fs.copyToLocalFile(false, new Path("/hello.txt"), new Path("d:/hello1.txt"), true);

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

    }

    //移动
    public void renameFile() throws URISyntaxException, IOException, InterruptedException {
        // 1 获取文件系统
        FileSystem fs = FileSystem.get(new URI(url), configuration, userName);
        // 2 修改文件名称
        fs.rename(new Path("/hello.txt"), new Path("/hello1.txt"));
        // 3 关闭资源
        fs.close();

    }

    //删除
    public void deleteFile() throws URISyntaxException, IOException, InterruptedException {
        // 1 获取文件系统
        FileSystem fs = FileSystem.get(new URI(url), configuration, userName);
        // 2 删除
        fs.delete(new Path("/hello1.txt"), true);
        // 3 关闭资源
        fs.close();
    }

    //查看
    public void listFiles() throws URISyntaxException, IOException, InterruptedException {
        FileSystem fs = FileSystem.get(new URI(url), configuration, userName);
        RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        while (listFiles.hasNext()) {
            LocatedFileStatus fileStatus = listFiles.next();

            System.out.println("========" + fileStatus.getPath() + "=========");
            System.out.println("文件权限:" + fileStatus.getPermission());
            System.out.println("所有者:" + fileStatus.getOwner());
            System.out.println("所属分组:" + fileStatus.getGroup());
            System.out.println("文件长度:" + fileStatus.getLen());
            System.out.println("文件修改时间:" + simpleDateFormat.format(fileStatus.getModificationTime()));
            System.out.println("副本数:" + fileStatus.getReplication());
            System.out.println("blockSize: " + fileStatus.getBlockSize() / 1024 / 1024 + "M");
            System.out.println("文件名称信息:" + fileStatus.getPath().getName());

            // 获取块信息
            BlockLocation[] blockLocations = fileStatus.getBlockLocations();
            System.out.println("块信息:" + Arrays.toString(blockLocations));
        }
        // 3 关闭资源
        fs.close();

    }

    //文件文件夹判断
    public void isFile() throws URISyntaxException, IOException, InterruptedException {
        FileSystem fs = FileSystem.get(new URI(url), configuration, userName);
        // 2 判断是文件还是文件夹
        FileStatus[] listStatus = fs.listStatus(new Path("/"));

        for (FileStatus fileStatus : listStatus) {

            // 如果是文件
            if (fileStatus.isFile()) {
                System.out.println("文件名称:" + fileStatus.getPath().getName());
            } else {
                System.out.println("目录名称:" + fileStatus.getPath().getName());
            }
        }
        // 3 关闭资源
        fs.close();

    }

}

完整代码:见附录

5、参考

https://blog.csdn.net/weixin_42175752/article/details/140097992

6、附录

1、window环境下的hadoop依赖

链接: https://pan.baidu.com/s/1nFIMXRlVpOrt5ahenq_Prg?pwd=c23a

2、完整代码

https://gitee.com/whisperofjune/spring-boot.git

相关推荐
IT小哥哥呀8 小时前
电池制造行业数字化实施
大数据·制造·智能制造·数字化·mom·电池·信息化
Xi xi xi8 小时前
苏州唯理科技近期也正式发布了国内首款神经腕带产品
大数据·人工智能·经验分享·科技
yumgpkpm8 小时前
华为鲲鹏 Aarch64 环境下多 Oracle 、mysql数据库汇聚到Cloudera CDP7.3操作指南
大数据·数据库·mysql·华为·oracle·kafka·cloudera
UMI赋能企业9 小时前
制造业流程自动化提升生产力的全面分析
大数据·人工智能
TDengine (老段)10 小时前
TDengine 数学函数 FLOOR 用户手册
大数据·数据库·物联网·时序数据库·iot·tdengine·涛思数据
派可数据BI可视化12 小时前
商业智能BI 浅谈数据孤岛和数据分析的发展
大数据·数据库·数据仓库·信息可视化·数据挖掘·数据分析
jiedaodezhuti12 小时前
Flink性能调优基石:资源配置与内存优化实践
大数据·flink
Lx35213 小时前
Flink窗口机制详解:如何处理无界数据流
大数据
Lx35213 小时前
深入理解Flink的流处理模型
大数据
Lx35214 小时前
Flink vs Spark Streaming:谁更适合你的实时处理需求?
大数据