0%

Hadoop-13-Hadoop优化

HDFS故障排除

集群安全模式

什么是安全模式

安全模式是Hadoop集群的一种状态,集群一旦处于安全模式,此时文件系统只接收读取数据请求,不接受删除、修改等变更请求。

进入安全模式场景

  • NameNode在加载镜像文件和编辑日志期间处于安全模式。

  • NameNode再接收DataNode注册时,处于安全模式。

退出安全模式的条件

  • dfs.namenode.safemode.min.datanodes:最小可用datanode数量,默认0
  • dfs.namenode.safemode.threshold-pct:副本数达到最小要求的block占系统总block数的百分比,默认0.999f
  • dfs.namenode.safemode.extension:稳定时间,默认值30000毫秒,即30秒。

使用命令控制安全模式

集群处于安全模式,不能执行重要操作(写操作)。

集群刚启动时是处于安全模式,当集群正常启动完成后,自动退出安全模式。

  • 查看安全模式状态

    1
    hdfs dfsadmin -safemode get
  • 进入安全模式状态

    1
    hdfs dfsadmin -safemode enter
  • 离开安全模式状态

    1
    hdfs dfsadmin -safemode leave
  • 等待安全模式状态

    1
    hdfs dfsadmin -safemode wait

    等待安全模式的使用场景:

    我们都知道,集群再刚刚启动时会处于安全模式,此时无法向HDFS中上传文件。那么能够再上传前做一个校验呢?当集群不处于安全模式时才执行上传操作。

    这个时候就需要使用到等待安全模式状态

    首先,手动时集群进入安全模式。

    1
    hdfs dfsadmin -safemode enter

    image-20230728160458761

    使用以下命令执行文件上传操作。

    1
    hdfs dfs -put 1.txt /

    image-20230728160638477

    无法上传。

    然后编写以下shell脚本。

    1
    2
    3
    4
    5
    6
    7
    #!/etc/bash

    # 等待安全模式
    hdfs dfsadmin -safemode wait

    # 执行上传操作
    hdfs dfs -put 1.txt /

    执行脚本后,会去校验集群的状态,如果处于安全模式会阻塞程序。

    image-20230728160846209

    然后再次开启一个窗口,执行关闭安全模式命令。

    1
    hdfs dfsadmin -safemode leave

    image-20230728160955265

    此时阻塞的程序会自动运行。

    image-20230728161040006

    文件上传成功

    image-20230728161101849

故障处理一:NameNode元数据丢失

为了模拟这个故障,我们会将NameNode下的元数据文件直接删除,为了不影响后续集群的正常功能,需要提前将所有虚拟机拍个快照,方便演示完毕后恢复集群状态。

首先查看HDFS中现有文件情况,将其文件全部删除只保留一个input文件夹。

image-20230728141509763

接下来从本地上传5个文件,文件内容不限,但是不允许为空。

image-20230728141611076

接下来在Hadoop102中找到NameNode的元数据,然后删除所有元数据。

1
2
3
4
5
# 进入NameNode元数据文件夹
cd /opt/module/hadoop-3.1.3/data/dfs/name/current

# 删除所有元数据
rm -rf ./*

删除完毕后重启NameNode

1
2
hdfs --daemon stop namenode
hdfs --daemon start namenode

此时查看当前集群中服务的运行状态。

1
jpsall

image-20230728142000919

可以看到NameNode未启动成功。

查看NameNode日志。

1
tail -n 100 /opt/module/hadoop-3.1.3/logs/hadoop-minglog-namenode-hadoop102.log

由日志可以看出,此时无法加载元数据文件,NameNode初始化失败。

image-20230728142249515

解决办法,将SecondNameNode中的元数据文件拷贝过来。

进入Hadoop104节点,然后执行以下命令将文件拷贝到Hadoop102节点下的NameNode元数据文件夹。

1
2
3
4
5
# 进入2NN元数据文件夹
cd /opt/module/hadoop-3.1.3/data/dfs/namesecondary/current

# 将2NN下的元数据拷贝到NN
scp ./* hadoop102:/opt/module/hadoop-3.1.3/data/dfs/name/current

拷贝完毕后再次重启NameNode

image-20230728143151930

此时再次查看集群服务,发现NameNode已启动成功,在Web页面中也可以成功看到页面。

但是此时打开HDFS文件系统页面时,发现两个问题:

  1. 之前上传的5个文件不见了
  2. 删除的outputtmp文件夹在文件系统中又出现了。

image-20230728143411083

并且此时我们执行文件上传操作时,也会失败。

image-20230728143437303

点击首页后我们发现此时HDFS属于安全模式。

image-20230728143517636

并且提示我们可以使用以下命令退出安全模式。

1
hdfs dfsadmin -safemode forceExit

尝试执行以上命令退出安全模式,安全模式退出成功。

image-20230728143653298

再次点击首页,可以看到集群提示我们有5个块缺失了。

image-20230728143743128

从提示可以看出来,出现问题的是outputtmp这两个文件,原因是因为这两个文件夹在前面已经被我们删除了,删除的时候是会连着DataNode中的块数据一起删除的。而在这里又出现了这两个文件夹的元数据是因为,我们NameNode中的元数据是从2NN下恢复过来的,在2NN中的元数据不是最新的,只有执行了CheckPoint操作后,才会将NameNode中的元数据拷贝过来。所以,2NN中只有NameNode中的部分元数据,一旦NameNode中数据产生丢失,是无法从2NN中完整恢复的。

在后续的课程中,为了解决这个问题,我们会讲到一个新的框架叫HA,它不再采用2NN服务,而是使用多个NameNode,每一个NameNode都有完整的元数据,这个时候就不担心元数据丢失了。

然后再回到文件目录界面,重新上传文件。

image-20230728144524938

文件上传成功。

是不是现在文件就修复成功了呢?不要开心得太早,此时再次回到Hadoop102节点重启NameNode

1
2
hdfs --daemon stop namenode
hdfs --daemon start namenode

image-20230728150035043

发现此时又回到了安全模式。这个时候每次重启集群都需要手动退出安全模式,集群的稳定性已经被破坏掉。

性能不高的电脑甚至连集群都无法再进入了,这也是原始的Hadoop结构的缺陷之一,对于元数据的保护程序不够高。有的机器可能在这里会恢复正常,但是集群中仍然会有一部分块数据占用了存储空间,并且由于元数据的丢失永远也无法访问到。

故障处理二:DataNode块数据丢失

首先恢复快照。

然后再次上传5个文件。

image-20230728151638923

上传完后,将所有节点的块数据删除。

1
2
3
4
5
# 进入datanode块数据存储目录
cd /opt/module/hadoop-3.1.3/data/dfs/data/current/BP-1367581874-192.168.128.102-1689068313438/current/finalized/subdir0/subdir0

# 删除所有的块数据
rm -rf ./*

然后回到HDFS文件系统页面。

image-20230728152103641

看起来没什么问题,这个时候我们点击其中一个文件1.txt

image-20230728152142137

发生报错Couldn't find datanode to read file from. Forbidden

有的时候报错:Couldn't preview the file.

此时将NameNode重启,点击Web页面中的Startup Progress

image-20230728152912078

可以看到此时NameNode等待DataNode报告自己的块数据信息,块数据信息不到99.9%,无法成功退出安全模式。

image-20230728153407351

由于安全模式是开启的,此时无法对集群进行上传操作。

image-20230728153543531

使用以下命令手动退出安全模式

1
hdfs dfsadmin -safemode forceExit

此时可以成功上传文件。

image-20230728153711580

但是再次重启NameNode后,会重新进入安全模式。

image-20230728155654934

进入到StartupProgress,可以发现DataNodeNameNode汇报的块信息也无法匹配。

image-20230728155757762

解决办法,退出安全模式后,删除元数据。

1
hdfs dfsadmin -safemode forceExit

image-20230728155914731

然后再次重启NameNode

image-20230728155953392

HDFS成功自动退出安全模式,集群恢复成功。

此时虽然可以恢复集群的正常功能,但是这个恢复的代价太大了,集群中所有的数据都需要删除,因为并不知道丢失的是哪些文件的块信息。

HDFS多目录

DataNode多目录配置

DataNode可以配置成多个目录,每个目录存储的数据不一样(数据不是副本)。

类似于windows电脑中,会把一个磁盘分为C、D、E等等盘符。

配置操作如下:

修改hdfs-site.xml文件,在文件中添加如下内容。

1
2
3
4
<property>
<name>dfs.datanode.data.dir</name>
<value>file://${hadoop.tmp.dir}/dfs/data,file://${hadoop.tmp.dir}/dfs/data2</value>
</property>

然后重启datanode

1
2
hdfs --daemon stop datanode
hdfs --daemon start datanode

此时再次进入到/opt/module/hadoop-3.1.3/data/dfs目录,并查看该文件夹下文件情况。

1
2
cd /opt/module/hadoop-3.1.3/data/dfs
ll

image-20230728161858697

可以看到此时文件夹下就多出了一个data2文件夹。

此时再向HDFS中上传文件,块数据就有可能放入到data2目录下。

磁盘数据均衡

磁盘数据均衡是为了应对在生产环境,由于硬盘空间不足,往往需要增加一块硬盘。刚加载的硬盘没有数据时,可以执行磁盘数据均衡命令(Hadoop3.x新特性),使得原来硬盘中的数据被均匀分不到两块硬盘下。

操作步骤如下所示:

  1. 生成均衡计划(我们只有一块磁盘,不会生成计划

    1
    hdfs diskbalancer -plan hadoop102

    image-20230728174010087

  2. 执行均衡计划

    1
    hdfs diskbalancer -execute /system/diskbalancer/2023-七月-28-17-26-40/hadoop102.plan.json  # 需要将文件修改为指定完整目录
  3. 查看当前均衡任务的执行情况

    1
    hdfs diskbalancer -query hadoop102
  4. 取消均衡任务

    1
    hdfs diskbalancer -cancel hadoop102.plan.json

HDFS扩容及缩容

服役新服务器

随着公司业务的增长,数据量越来越大,原有的数据节点的容量已经不能满足存储数据的需求,需要在原有集群基础上动态添加新的数据节点。

为了演示效果需要在VMware中再次克隆一个虚拟机,这里我们对Hadoop102节点进行克隆。

克隆操作见此文章,克隆后的节点名称为Hadoop105,克隆按照教程将IP地址修改为192.168.128.105hostname修改为hadoop105

image-20230729133145086

然后删除hadoop105Hadoop的历史数据data目录、logs目录和/tmp/下的所有文件。

然后在hadoop105节点下直接执行以下命令,启动datanode即可直接生效。

1
hdfs --daemon start datanode

image-20230729134203544

直接使用hadoop105向集群中上传文件。

1
hdfs dfs -put hello.txt /

image-20230729134537665

文件上传成功,点击hello.txt查看该数据的存储块。

image-20230729134607493

可以看到此时该数据的存储副本为hadoop102hadoop104hadoop105这三个节点。

hadoop105节点成功服役。

但是还有一个问题,此时我们使用脚本去关闭HDFS

1
stop-dfs.sh

hadoop102-104节点中的DataNode服务可以关闭,但是hadoop105节点中的DataNode无法关闭。

image-20230729134844200

image-20230729134854411

出现这个文件的原因是因为,我们没有在Hadoop中的工作节点配置文件中添加hadoop105,添加即可。

为了演示效果,在添加之前首先恢复HDFS服务。

1
start-dfs.sh

添加工作节点。

1
vim /opt/module/hadoop-3.1.3/etc/hadoop/workers

image-20230729135136913

分发配置文件。

1
xsync /opt/module/hadoop-3.1.3/etc/hadoop/workers

image-20230729135215022

注意此时分发只对hadoop102-104生效,因为在编写xsync脚本时只针对hadoop102-104节点。

image-20230729135410353所以需要在hadoop105节点下也修改works文件内容。

此时hadoop中的脚本就可以操作hadoop105节点了。再次使用以下命令关闭集群中的HDFS

1
stop-dfs.sh

image-20230729135622665

image-20230729135631535

此时,所有节点的DataNode就全部关闭成功。

然后再执行恢复HDFS

1
start-dfs.sh

image-20230729135807367

image-20230729135814665

启动成功。

服务器间数据均衡

在企业开发中,如果经常在hadoop102hadoop104上提交任务,且副本数为2,由于数据本地性原则,就会导致hadoop102hadoop104数据过多,hadoop103存储的数据量小。

另一种情况,就是新服役的服务器数据量比较少,需要执行集群均衡命令。这里我的数据量较少,就不演示了,但是相关命令操作需要了解。

  1. 开启数据均衡命令

    1
    start-balancer.sh -threshold 10

    对于参数10,代表的是集群中各个节点的磁盘空间利用率相差不超过10%,可根据实际情况进行调整。

  2. 停止数据均衡命令

    1
    stop-balancer.sh

    注意:由于HDFS需要启动单独的Rebalance Server来执行Rebalance操作,所以尽量不要在NameNode上执行start-balancer.sh,而是找一台比较空闲的机器。

添加白名单

在前面添加新的服役服务器时,我们只是简单的将服务器和集群配置到同一个网段,然后开启服务器的DataNode即可加入到集群中充当存储节点。这样做固然很方便、高效,但是同样很容易操作攻击,如果其他人也在网段中创建一个新的节点,开启DataNode此时NameNode也会扫描到该DataNode,就会向其中去存储数据,这个时候数据就被盗走了。

为了解决这个问题,就需要使用到白名单。白名单,表示在白名单的主机IP地址可以用来存储数据。

添加白名单的步骤如下所示:

  1. 创建白名单

    1
    2
    3
    4
    5
    # 进入到hadoop目录下的etc/hadoop目录
    cd $HADOOP_HOME/etc/hadoop

    # 添加白名单
    vim whitelist

    添加以下内容

    1
    2
    3
    hadoop102
    hadoop103
    hadoop104
  2. 在配置文件hdfs-site.xml中配置白名单地址。

    1
    2
    3
    4
    5
    <!-- 白名单 -->
    <property>
    <name>dfs.hosts</name>
    <value>/opt/module/hadoop-3.1.3/etc/hadoop/whitelist</value>
    </property>
  3. 分发配置文件hdfs-site.xml和白名单whitelist

    1
    xsync hdfs-site.xml whitelist
  4. 然后重启集群

    1
    2
    myhadoop stop
    myhadoop start

    image-20230729141203242

    此时在Web界面去查看集群状态,可以看到只有hadoop102-104没有hadoop105

    image-20230729141245750

    但是到hadoop105节点下查看,其DataNode服务已经启动了,但是无法在集群中生效。

    image-20230729141327800

    这个就是白名单的作用,不在白名单中的节点是无法被集群使用的。

  5. 这个时候再次编辑白名单,添加hadoop105并分发。

  6. 然后重启集群,再次在Web界面中查看集群状态。

    1
    2
    myhadoop stop
    myhadoop start

    image-20230729141611992

    此时hadoop105节点就又被纳入集群了。

    新服役的服务器此时可能没有数据,和其他服务器数据之间数据就不均衡了,此时就可以使用前面提到了集群间数据均衡操作,对数据进行均衡化,让新服务器承担数据存储服务。

添加黑名单

首先,要搞清楚一个点,黑名单的作用不是为了去禁止某个节点纳入到集群,而且用来退役服务器的。

它在生效的时候会做两个事情:

  1. 将退役服务器中的数据拷贝到其他节点。
  2. 退出集群。

黑名单的配置步骤如下:

  1. 创建黑名单

    1
    2
    cd /opt/module/hadoop-3.1.3/etc/hadoop
    vim blacklist

    添加退役节点hostname

    1
    hadoop105
  2. hdfs-site.xml添加以下内容,配置黑名单文件路径。

    1
    2
    3
    4
    5
    <!-- 黑名单 -->
    <property>
    <name>dfs.hosts.exclude</name>
    <value>/opt/module/hadoop-3.1.3/etc/hadoop/blacklist</value>
    </property>
  3. 分发配置文件。

    1
    xsync blacklist hdfs-site.xml
  4. 重启集群

    1
    2
    myhadoop stop
    myhadoop start
  5. Web界面中,观察退役过程。

    image-20230729142922730

    首先可以看到在hadoop105节点中前面显示的图标发生了变化,表示此时hadoop105节点正在退役。还可以观察到此时hadoop103节点中是没有块数据的。

    过了一段时候后刷新页面。

    image-20230729143055158

    此时hadoop105节点的图标颜色变成了橙色,表示该节点已退役。并且在hadoop103节点中多了一个块数据,该数据其实就是之前在hadoop105中的数据,被拷贝到了hadoop103节点。

    此时就可以将hadoop105节点从集群中移除。

Hadoop企业优化

MapReduce优化方法

MapReduce优化方法主要从六个方面考虑:数据输入、Map阶段、Reduce阶段、IO传输、数据倾斜问题和常用的调优参数。

数据输入

  1. 合并小文件:在执行MR任务前将小文件进行合并,大量的小文件会产生大量的Map任务,增大Map任务装载次数,而任务的装载比较耗时,从而导致MR运行较慢。

  2. 采用CombineTextInputFormat来作为输入,解决输入端大量小文件场景。

    这个输入方式在前面将MR阶段的源码操作时讲过,点击此处查看,第2.5节讲的就是CombineTextInputFormat

Map阶段

  1. 减少溢写次数:通过调整mapreduce.task.io.sort.mbmapreduce.map.sort.spill.percent参数值,增大触发Spill的内存上限,减少Spill次数,从而减少磁盘IO

    这个内容对应在Shuffer阶段第一部分,Mapper的输出结果会进入到环形缓冲区,前面我们提到过环形缓冲区的默认内存大小为100M,当超过80%后就会写入磁盘。这里的两个值就是有上述的参数控制。官网截图如下所示。

    image-20230729151642559

  2. 减少合并次数:通过调整mapreduce.task.io.sort.factor参数,增大Merge的文件数目,减少Merge的次数,从而缩短MR处理时间。

    这里的合并次数就是指,上一步当环形缓冲区的文件超过设定的内存大小时会将内存中的数据写入磁盘,写入磁盘后的所有文件后续还需要进行一次归并排序,这个存储多少个文件才进行归并排序呢?就是由这个参数控制。官网截图见上一步。

  3. Map之后,不影响业务逻辑前提下,先进行Combine处理,减少I/O

    注意:不是所有任务都可以使用Combine

Reduce阶段

  1. 合理设置MapReduce数:两个都不能设置太少,也不能设置太多。太少,会导致Task等待,延长处理时间;太多,会导致Map、Reduce任务间竞争资源,造成处理超时等错误。

  2. 设置MapReduce共存:调整mapreduce.job.reduce.slowstart.completedmaps参数,使Map运行到一定程度后,Reduce也开始运行,减少Reduce的等待时间。

    默认的情况下,MR任务中ReduceTask任务必须等待所有的MapTask任务执行完毕后再开始,这样其实是优点浪费资源的,我们完全可以在某个MapTask任务执行完后就先将数据文件传输到ReduceTask,这样缓解Redece阶段ReduceTask对网络资源的竞争。

  3. 规避使用Reduce:因为Reduce在用于连接数据集的时候将会产生大量的网络消耗。

    数据需要从MapTask传输到ReduceTask,这两个Task不一定是在同一个节点上。

  4. 合理设置Reduce端的Buffer:默认情况下,数据达到一个阈值的时候,Buffer中的数据就会写入磁盘,然后Reduce会从磁盘中获得所有的数据。也就是说,BufferReduce是没有直接关联的,中间多次写磁盘->读磁盘的过程,既然有这个弊端,那么就可以通过参数来配置,使得Buffer中的一部分数据可以直接输送到Reduce,从而减少IO开销。

    mapreduce.reduce.input.buffer.percent,默认为0.0。当值大于0的时候,会保留指定比例的内存读Buffer中的数据直接拿给Reduce使用。这样一来,设置Buffer需要内存,读取数据需要内存,Reduce计算也要内存,所以要根据作业的运行情况进行调整。

IO传输

  1. 采用数据压缩的方式,减少网络IO的时间。安装SnappyLZO压缩编码器。

  2. 使用SequenceFile二进制文件。

    这种方式的使用场景为,一个MR任务的输出是另外一个MR任务的输入。

    这里可以演示一下,只需要在Driver文件中加入简单配置即可。

    image-20230729152844047

    执行任务。同样会在output文件夹下生成输出结果,但是此时使用文本查看器打开输出结果,是无法查看正常内容的。

    image-20230729153024733

    只有在作为另外一个MR任务的输入时才会有作用。

数据倾斜问题

  1. 数据倾斜现象

    • 数据频率倾斜:某一个区域的数据量要远远大于其他区域。
    • 数据大小倾斜:部分记录的大小远远大于平均值。
  2. 减少数据倾斜的方法

    • 方法1:抽样和范围分区

      可以通过对原始数据进行抽样得到的结果集来预设分区边界值。

    • 方法2:自定义分区

      基于输出键的背景知识进行自定义分区。例如,如果Map输出键的单词来源于一本书。且其中某几个专业词汇较多。那么就可以自定义分区将这这些专业词汇发送给固定的一部分Reduce实例。而将其他的都发送给剩余的Reduce实例。

    • 方法3:Combiner

      使用Combiner可以大量地减小数据倾斜。在可能的情况下,Combine的目的就是聚合并精简数据。

    • 方法4:采用Map Join,尽量避免使用Reduce Join。

常用的调优参数

  • 以下参数是在用户自己的MR应用程序中配置就可以生效(mapred-default.xml)
配置参数 参数说明
mapreduce.map.memory.mb 一个MapTask可使用的资源上限(单位:MB),默认为1024。如果MapTask实际使用的资源量超过该值,则会被强制杀死。
mapreduce.reduce.memory.mb 一个ReduceTask可使用的资源上限(单位:MB),默认为1024。如果ReduceTask实际使用的资源量超过该值,则会被强制杀死。
mapreduce.map.cpu.vcores 每个MapTask可使用的最多cpu core数目,默认值:1
mapreduce.reduce.cpu.vcores 每个ReduceTask可使用的最多cpu core数目,默认值: 1
mapreduce.reduce.shuffle
.parallelcopies
每个ReduceMap中取数据的并行数。默认值是5
mapreduce.reduce.shuffle
.merge.percent
Buffer中的数据达到多少比例开始写入磁盘。默认值0.66
mapreduce.reduce.shuffle
.input.buffer.percent
Buffer大小占Reduce可用内存的比例。默认值0.7
mapreduce.reduce.input
.buffer.percent
指定多少比例的内存用来存放Buffer中的数据,默认值是0.0
  • 应该在YARN启动之前就配置在服务器的配置文件中才能生效(yarn-default.xml
配置参数 参数说明
yarn.scheduler.minimum-allocation-mb 给应用程序Container分配的最小内存,默认值:1024
yarn.scheduler.maximum-allocation-mb 给应用程序Container分配的最大内存,默认值:8192
yarn.scheduler.minimum-allocation-vcores 每个Container申请的最小CPU核数,默认值:1
yarn.scheduler.maximum-allocation-vcores 每个Container申请的最大CPU核数,默认值:32
yarn.nodemanager.resource.memory-mb Containers分配的最大物理内存,默认值:8192
  • Shuffle性能优化的关键参数,应在YARN启动之前就配置好(mapred-default.xml
配置参数 参数说明
mapreduce.task.io.sort.mb Shuffle的环形缓冲区大小,默认100m
mapreduce.map.sort.spill.percent 环形缓冲区溢出的阈值,默认80%
  • 容错相关参数(MapReduce性能优化)
配置参数 参数说明
mapreduce.map.maxattempts 每个Map Task最大重试次数,一旦重试次数超过该值,则认为Map Task运行失败,默认值:4
mapreduce.reduce.maxattempts 每个Reduce Task最大重试次数,一旦重试次数超过该值,则认为Map Task运行失败,默认值:4
mapreduce.task.timeout Task超时时间,经常需要设置的一个参数。该参数表达的意思为:如果一个Task在一定时间内没有任何进入,即不会读取新的数据,也没有输出数据,则认为该Task处于Block状态,可能是卡住了,也许永远会卡住,为了防止因为用户程序永远Block住不退出,则强制设置了一个该超时时间(单位毫秒),默认是600000(10分钟)。如果你的程序对每条输入数据的处理时间过长(比如会访问数据库,通过网络拉取数据等)。建议将该参数调大,该参数过小常出现的错误提示是:“AttemptID:attempt_14267829456721_``123456_m_000224_0 Timed out after 300 secsContainer killed by the ApplicationMaster.”。

Hadoop小文件优化方法

Hadoop小文件弊端

HDFS上每个文件都要在NameNode上创建对应的元数据,这个元数据的大小约为150byte,这样当小文件比较多的时候,就会产生很多的元数据文件,一方面会大量占用NameNode的内存空间,另一方面就是元数据文件过多,使得寻址索引速度变慢。

小文件过多,在进行MR计算时,会生成过多切片,需要启动过多的MapTask。每个MapTask处理的数据量小,导致MapTask的处理时间比启动时间还小,白白消耗资源。

Hadoop小文件解决方案

  1. 小文件优化的方向:

    • 在数据采集的时候,就将小文件或小批数据合成大文件再上传HDFS
    • 在业务处理之前,在HDFS上使用MapReduce程序对小文件进行合并。
    • MapReduce处理时,可采用CombineTextInputFormat提高效率。
    • 开启uber模式,实现jvm重用。
  2. Hadoop Archive

    是一个高效的将小文件放入HDFS块中的文件存档工具,能够将多个小文件打包成一个HAR文件,从而达到减少NameNode的内存使用。

  3. CombineTextInputFormat

    CombineTextInputFormat用于将多个小文件在切片过程中生成一个单独的切片或者少量的切片。

  4. 开启uber模式,实现JVM重用

    默认情况下,每个Task任务都需要启动一个JVM来运行,如果Task任务计算的数据量很小,我们可以让同一个Job的多个Task运行在一个JVM中,不必为每个Task都开启一个JVM

    首先运行一下wordcount任务,查看未设置uber模式时,yarn中生成的Containers4个。

    1
    hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount /input /output2

    image-20230729154859857

    然后开启uber模式,在mapred-site.xml中添加如下配置:

    1
    2
    3
    4
    5
    <!--  开启uber模式 -->
    <property>
    <name>mapreduce.job.ubertask.enable</name>
    <value>true</value>
    </property>

    重启集群,并再次运行wordcount任务。

    1
    2
    3
    myhadoop stop
    myhadoop start
    hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount /input /output2

    image-20230729155120476

    此时在执行MR任务时就只生成了1Containers

Hadoop扩展

集群间数据拷贝

采用distcp命令实现两个Hadoop集群之间的递归数据复制。

集群1 NameNode节点:hadoop102

集群2 NameNode节点:hadoop105

那么将数据从集群1拷贝到集群2使用以下命令:

1
hadoop distcp hdfs://hadoop102:8020/user/atguigu/hello.txt hdfs://hadoop105:8020/user/atguigu/hello.txt

小文件存档

解决存储小文件办法之一,HDFS存档文件或HAR文件,是一个更高效的文件存档工具,它将文件存入HDFS块,在减少NameNode内存使用的同时,允许文件进行透明的访问。具体说来,HDFS存档文件对内还是一个一个独立文件,对NameNode而言却是一个整体,这样就可以减少NameNode中存储元数据消耗的内存。

效果演示:

首先在HDFSinput目录下上传4个文件,如图所示。

image-20230729160224241

注意文件不能为空。

然后使用以下命令,将/input目录进行归档。

1
hadoop archive -archiveName input.har -p  /input /output

注意:此时输出文件/output必须存在。

image-20230729160443066

从运行过程可以看出其实该操作就是执行了一个MR任务。

image-20230729160523198

从输出结果可以看出,在/output目录下生成了一个input.har目录,在该目录下存在相关文件。

image-20230729160611699

使用以下命令,查看归档内容。

1
hdfs dfs -ls har:///output/input.har

image-20230729160706708

使用以下命令进行解归档。

1
hadoop fs -cp har:///output/input.har/1.txt /

回到根目录即可看到解归档的1.txt文件。

image-20230729160828598

要想解压所有归档文件可以使用以下命令。

1
hadoop fs -cp har:///output/input.har/* /

回收站

开启回收站功能,可以将删除的文件在不超时的情况下,恢复原数据,起到防止误删除、备份等作用。

回收站的原理其实就是将使用命令删除的文件放入到一个临时目录下保存,在一定的时间后会对临时文件夹下所有的文件进行清空。

开启回收站配置如下所示。

在配置文件core-site.xml中添加以下内容:

1
2
3
4
5
# 配置垃圾回收时间为1分钟
<property>
<name>fs.trash.interval</name>
<value>1</value>
</property>

然后重启集群。

1
2
myhadoop stop
myhadoop start

使用以下命令删除集群中的文件/1.txt

1
hdfs dfs -rm /1.txt

执行删除文件操作后,在HDFS的根目录下就会生成一个/usr目录,在/usr目录下就会存放回收站文件。

如图所示。

image-20230729161625691

想要从回收站中恢复文件,使用的操作就是hdfs中的移动命令。

1
hdfs dfs -mv /user/minglog/.Trash/230729161600/1.txt /

注意这个操作必须在前面设定的时间范围内执行,超过时间后会永久删除文件。

至此,原生的Hadoop内容结束,学到这你已经很厉害了。加油~~~~

-------------本文结束感谢您的阅读-------------