大数据高级开发工程师——Hadoop学习笔记(3)

Hadoop进阶篇

HDFS:Hadoop分布式文件系统

NameNode和SecondaryNameNode功能剖析

1. NameNode和SecondaryNameNode解析
  • NameNode主要负责集群当中的元数据信息管理,而且元数据信息需要经常随机访问,因为元数据信息必须高效的检索。
    • 元数据信息保存在哪里能够快速检索呢?
    • 如何保证元数据的持久安全呢?
  • 为了保证元数据信息的快速检索,那么我们就必须将元数据存放在内存当中,因为在内存当中元数据信息能够最快速的检索,那么随着元数据信息的增多(每个block块大概占用150字节的元数据信息),内存的消耗也会越来越多。
  • 如果所有的元数据信息都存放内存,服务器断电,内存当中所有数据都消失,为了保证元数据的安全持久,元数据信息必须做可靠的持久化。
  • 在hadoop当中为了持久化存储元数据信息,将所有的元数据信息保存在了FSImage文件当中,那么FSImage随着时间推移,必然越来越膨胀,FSImage的操作变得越来越难,为了解决元数据信息的增删改,hadoop当中还引入了元数据操作日志edits文件,edits文件记录了客户端操作元数据的信息,随着时间的推移,edits信息也会越来越大,为了解决edits文件膨胀的问题,hadoop当中引入了 SecondaryNameNode来专门做fsimage与edits文件的合并。

在这里插入图片描述

  • NameNode 工作机制
    • 第一次启动namenode格式化后,创建fsimage和edits文件。如果不是第一次启动,直接加载编辑日志和镜像文件到内存;
    • 客户端对元数据进行增删改的请求;
    • namenode记录操作日志,更新滚动日志;
    • namenode在内存中对数据进行增删改查。
  • SecondaryNameNode工作机制
    • Secondary NameNode询问namenode是否需要checkpoint,直接带回namenode是否检查结果;
    • Secondary NameNode请求执行checkpoint;
    • namenode滚动正在写的edits日志;
    • 将滚动前的编辑日志和镜像文件拷贝到Secondary NameNode;
    • Secondary NameNode加载编辑日志和镜像文件到内存,并合并;
    • 生成新的镜像文件fsimage.chkpoint;
    • 拷贝fsimage.chkpoint到namenode;
    • namenode将fsimage.chkpoint重新命名成fsimage。
属性解释
dfs.namenode.checkpoint.period3600秒(即1小时)The number of seconds between two periodic checkpoints.
dfs.namenode.checkpoint.txns1000000The Secondary NameNode or CheckpointNode will create a checkpoint of the namespace every ‘dfs.namenode.checkpoint.txns’ transactions, regardless of whether ‘dfs.namenode.checkpoint.period’ has expired.
dfs.namenode.checkpoint.check.period60秒(1分钟)The SecondaryNameNode and CheckpointNode will poll the NameNode every ‘dfs.namenode.checkpoint.check.period’ seconds to query the number of uncheckpointed transactions.
2. FSImage与edits详解
  • 所有的元数据信息都保存在了FsImage与eidts文件当中,这两个文件就记录了所有的数据的元数据信息,元数据信息的保存目录配置在了hdfs-site.xml当中
<!-- namenode保存fsimage的路径 -->
<property>
    <name>dfs.namenode.name.dir</name>
    <value>file:///bigdata/install/hadoop-3.1.4/hadoopDatas/namenodeDatas</value>
</property>
<!-- namenode保存editslog的目录 -->
<property>
    <name>dfs.namenode.edits.dir</name>
    <value>file:///bigdata/install/hadoop-3.1.4/hadoopDatas/dfs/nn/edits</value>
</property>

在这里插入图片描述

  • 客户端对hdfs进行写文件时会首先被记录在edits文件中,edits修改时元数据也会更新。每次hdfs更新时edits先更新后,客户端才会看到最新信息。
  • fsimage 是namenode中关于元数据的镜像,一般称为检查点。

一般开始时对namenode的操作都放在edits中,为什么不放在fsimage中呢?
因为fsimage是namenode的完整的镜像,内容很大,如果每次都加载到内存的话生成树状拓扑结构,这是非常耗内存和CPU。

  • fsimage内容包含了namenode管理下的所有datanode中文件及文件block及block所在的datanode的元数据信息。随着edits内容增大,就需要在一定时间点和fsimage合并。
3. 文件信息查看
cd /bigdata/install/hadoop-3.1.4/hadoopDatas/namenodeDatas/current
hdfs oev     #查看帮助信息
hdfs oiv -i fsimage_0000000000000000390 -p XML -o /home/hadoop/fsimage.xml
  • 使用命令 hdfs oiv 查看edits文件
cd /bigdata/install/hadoop-3.1.4/hadoopDatas/dfs/nn/edits/current
hdfs oev -i edits_0000000000000000389-0000000000000000390 -o /home/hadoop/myedit.xml -p XML
4. namenode元数据信息多目录配置
  • 为了保证元数据的安全性
    • 我们一般都是先确定好我们的磁盘挂载目录,将元数据的磁盘做RAID1 namenode的本地目录可以配置成多个,且每个目录存放内容相同,增加了可靠性。
    • 多个目录间逗号分隔
  • 具体配置如下:hdfs-site.xml
<property>
   <name>dfs.namenode.name.dir</name>
   <value>file:///bigdata/install/hadoop-3.1.4/hadoopDatas/namenodeDatas,file:///path/to/another/</value>
</property>

hdfs的小文件治理

1. 存储大量小文件有没有问题
  • NameNode存储着文件系统的元数据,每个文件、目录、块大概有150字节的元数据;
  • 因此文件数量的限制也由 NameNode 内存大小决定,如果小文件过多则会造成 NameNode 的压力过大;
  • 且HDFS能存储的数据总量也会变小
2. HAR文件方案
  • 本质是启动 MR 程序,所以需要启动 YARN

在这里插入图片描述

  • archive 用法:
# hadoop archive
archive <-archiveName <NAME>.har> <-p <parent path>> [-r <replication factor>] <src>* <dest>
  • /yw 目录下的文件进行归档处理
[root@centos128 ~]# hdfs dfs -ls -R /yw
drwxr-xr-x   - yangwei supergroup          0 2021-11-26 20:25 /yw/dir1
-rw-r--r--   3 yangwei supergroup         13 2021-11-26 20:25 /yw/dir1/hello.txt
drwxr-xr-x   - test    supergroup          0 2021-11-26 20:43 /yw/dir2
-rw-r--r--   3 yangwei supergroup         13 2021-11-26 20:43 /yw/dir2/hello.txt
drwxr--r--   - yangwei supergroup          0 2021-11-26 20:55 /yw/dir3
-rw-r--r--   3 hadoop  supergroup         35 2021-11-26 20:55 /yw/dir3/big.txt
  • 第一步:创建归档文件,注意归档文件一定要保证yarn集群启动
# 将 /yw 下的 dir1 dir2 dir3 下的目录及文件归档到 /user 目录下
hadoop archive -archiveName myhar.har -p /yw -r 3 dir1 dir2 dir3 /user
  • 第二步:查看归档文件内容
hdfs dfs -ls -R /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方案
  • SequenceFile文件,主要由一条条record记录组成,具体结构如下图:
    • 一个SequenceFile首先有一个4字节的header(文件版本号);
    • 接着是若干record记录;
    • 每个record是键值对形式的,键值类型是可序列化类型,如IntWritable、Text;
    • 录间会随机的插入一些同步点sync marker,用于方便定位到记录边界。

在这里插入图片描述

  • SequenceFile文件可以作为小文件的存储容器:
    • 每条record保存一个小文件的内容;
    • 小文件名作为当前record的键,小文件的内容作为当前record的值;
    • 如10000个100KB的小文件,可以编写程序将这些文件放到一个SequenceFile文件。
  • 一个SequenceFile是可分割的,所以MapReduce可将文件切分成块,每一块独立操作。
  • 不像HAR,SequenceFile支持压缩。记录的结构取决于是否启动压缩:
    • 支持两类压缩
      • 不压缩NONE,压缩RECORD,如上图
      • 压缩BLOCK,如下图,①一次性压缩多条记录;②每一个新块Block开始处都需要插入同步点
    • 在大多数情况下,以block(注意:指的是SequenceFile中的block)为单位进行压缩是最好的选择;
    • 因为一个block包含多条记录,利用record间的相似性进行压缩,压缩效率更高;
    • 把已有的数据转存为SequenceFile比较慢。比起先写小文件,再将小文件写入SequenceFile,一个更好的选择是直接将数据写入一个SequenceFile文件,省去小文件作为中间媒介。

在这里插入图片描述

  • 向SequenceFile写入数据:
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 {
        // 输出路径:要生成的 Sequence 文件名
        String uri = "hdfs://node01:8020/writeSequenceFile";

        Configuration conf = new Configuration();
        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.Writer.Option pathOption = SequenceFile.Writer.file(path);
        SequenceFile.Writer.Option keyOption = SequenceFile.Writer.keyClass(IntWritable.class);
        SequenceFile.Writer.Option valueOption = SequenceFile.Writer.valueClass(Text.class);

        // SequenceFile压缩方式:NONE | RECORD | BLOCK三选一
        // 方案一:RECORD、不指定压缩算法
//        SequenceFile.Writer.Option compressionOption = SequenceFile.Writer.compression(SequenceFile.CompressionType.RECORD);
//        SequenceFile.Writer writer = SequenceFile.createWriter(conf, pathOption, keyOption, valueOption, compressionOption);

        // 方案二:BLOCK、不指定压缩算法
//        SequenceFile.Writer.Option compressionOption = SequenceFile.Writer.compression(SequenceFile.CompressionType.BLOCK);
//        SequenceFile.Writer writer = SequenceFile.createWriter(conf, pathOption, keyOption, valueOption, compressionOption);

        // 方案三:使用BLOCK、压缩算法BZip2Codec; 压缩时间;再加压缩算法
        BZip2Codec codec = new BZip2Codec();
        SequenceFile.Writer.Option compressionAlgorithm = SequenceFile.Writer.compression(SequenceFile.CompressionType.RECORD, codec);
        SequenceFile.Writer writer = SequenceFile.createWriter(conf, pathOption, keyOption, valueOption, compressionAlgorithm);

        for (int i = 0; i < 1000; i++) {
            // 分别设置 key、value 值
            key.set(1000 - 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);
    }
}
  • 命令查看 SequenceFile 内容:
hadoop fs -text /writeSequenceFile
  • 读取SequenceFile文件:
public class SequenceFileReadNewVersion {
    public static void main(String[] args) throws IOException {
        // 要读的 SequenceFile
        String uri = "hdfs://node01:8020/writeSequenceFile";
        Configuration conf = new Configuration();
        Path path = new Path(uri);

        SequenceFile.Reader.Option pathOption = SequenceFile.Reader.file(path);
        // 创建Reader对象
        SequenceFile.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();
        }

        IOUtils.closeStream(reader);
    }
}

hdfs的其它功能介绍

1. 多个集群之间的数据拷贝
  • 在我们实际工作当中,极有可能会遇到将测试集群的数据拷贝到生产环境集群,或者将生产环境集群的数据拷贝到测试集群,那么就需要我们在多个集群之间进行数据的远程拷贝,hadoop 也自带有命令可以帮我们实现这个功能。
  • ① 本地文件拷贝scp
cd /bigdata/soft
scp -r jdk-8u141-linux-x64.tar.gz hadoop@node02:/bigdata/soft
  • ② 集群之间的数据拷贝distcp
cd /bigdata/install/hadoop-3.1.4
bin/hadoop distcp hdfs://node01:8020/jdk-8u141-linux-x64.tar.gz hdfs://cluster2:8020/path/to/dir
2. hdfs快照snapShot管理
  • 快照顾名思义,就是相当于对我们的hdfs文件系统做一个备份,我们可以通过快照对我们指定的文件夹设置备份,但是添加快照之后,并不会立即复制所有文件,而是指向同一个文件。当写入发生时,才会产生新文件
快照使用基本语法
# 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> 
快照操作实际案例
  • 开启与禁用指定目录的快照
hdfs dfsadmin -allowSnapshot /user
hdfs dfsadmin -disallowSnapshot /user

在这里插入图片描述

  • 对指定目录创建快照

注意:创建快照之前,先要允许该目录创建快照

hdfs dfsadmin -allowSnapshot /user
hdfs dfs -createSnapshot /user

在这里插入图片描述

  • 通过web浏览器访问快照:http://node01:9870/explorer.html#/user/.snapshot/s20211128-152238.090

在这里插入图片描述

  • 指定名称创建快照
hdfs dfs -createSnapshot /user mysnap1
  • 重命名快照
hdfs  dfs -renameSnapshot /user mysnap1 mysnap2
  • 列出当前用户所有可以快照的目录
hdfs lsSnapshottableDir
  • 比较两个快照不同之处
hdfs dfs -createSnapshot /user snap1
hdfs dfs -createSnapshot /user snap2
hdfs snapshotDiff /user snap1 snap2
  • 删除快照
hdfs dfs -deleteSnapshot /user snap1
3. hdfs回收站
  • 任何一个文件系统,基本上都会有垃圾桶机制,也就是删除的文件,不会直接彻底清掉,我们一把都是将文件放置到垃圾桶当中去,过一段时间之后,自动清空垃圾桶当中的文件,这样对于文件的安全删除比较有保证,避免我们一些误操作,导致误删除文件或者数据。
  • 回收站配置两个参数
fs.trash.interval=0 # 默认值0表示禁用回收站,可以设置删除文件的存活时间。
fs.trash.checkpoint.interval=0 # 检查回收站的间隔时间。
# 要求fs.trash.checkpoint.interval <= fs.trash.interval。
  • 启用回收站:修改所有服务器的core-site.xml配置文件
<!-- 开启hdfs的垃圾桶机制,删除掉的数据可以从垃圾桶中回收,单位分钟 -->
<property>
	<name>fs.trash.interval</name>
	<value>10080</value>
</property>
  • 查看回收站:回收站在集群的/user/hadoop/.Trash/ 这个路径下
  • 通过javaAPI删除的数据,不会进入回收站,需要调用moveToTrash()才会进入回收站
Trash trash = New Trash(conf);
trash.moveToTrash(path);
  • 恢复回收站数据
hdfs dfs -mv trashFileDir  hdfsdir
# trashFileDir :回收站的文件路径
# hdfsdir  :将文件移动到hdfs的哪个路径下
  • 清空回收站
# 跳过回收站,彻底删除文件
hdfs dfs -rm -r -skipTrash /wc06
# 清空回收站
hdfs dfs -expunge
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

讲文明的喜羊羊拒绝pua

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值