写点什么

Hadoop 优化|全面调优攻略 | HDFS、MapReduce、YARN 性能提升秘诀 | 专家实战分享!

  • 2024-11-07
    四川
  • 本文字数:6219 字

    阅读完需:约 20 分钟

Hadoop优化|全面调优攻略 | HDFS、MapReduce、YARN性能提升秘诀 | 专家实战分享!

HDFS 调优  

NameNode 内存

Hadoop2.x 系列,NN 内存默认 2000M,根据服务器(以 4G 为例)的 3/4 来配:

hadoop-env.sh 文件中配置:HADOOP_NAMENODE_OPTS=-Xmx3072m
复制代码

Hadoop3.x 系列,hadoop-env.sh 文件中说明了内存自动分配。通过命令 jmap -heap < jps 查看到的进程的 PID >可知 NameNode 和 DataNode 占用内存都是自动分配的,且相等。不是很合理。


手动配置: hadoop-env.sh

export HDFS_NAMENODE_OPTS="-Dhadoop.security.logger=INFO,RFAS -Xmx1024m"export HDFS_DATANODE_OPTS="-Dhadoop.security.logger=ERROR,RFAS -Xmx1024m"
复制代码


NameNode 心跳并发    

NameNode 有一个工作线程池,用来处理不同 DataNode 的并发心跳以及客户端并发的元数据操作。

线程数 dfs.namenode.handler.count 默认是 10,按企业经验 hdfs-site.xml 中该值设为



开启回收站

将删除的文件在不超时的情况下恢复,防止误删:

  1. 修改 core-site.xml 中回收时间 fs.trash.interval 值为 60,以及检查间隔 fs.trash.checkpoint.interval 值为小于回收时间

  2. 查看回收站:HDFS 中路径:/user/用户名/.Trash/…

  3. web 端删除不经过回收站,或者通过程序删除只有使用 moveToTrash() 才走回收站,此外 shell 操作命令使用 hadoop fs -rm 才走回收站

  4. 恢复数据的话将回收站路径下文件移动即可

集群压测

考虑到 Java 后台拉取的数据用多久能上传到集群,以及从 HDFS 上拉取数据的时间,因此对集群压测以测出 HDFS 的读写性能


说明:HDFS 的读写性能主要受限于网络和磁盘.


写性能测试  


前提:设置集群网速为 100Mbps 单位是 bit;换算后为 12.5M/s


测试步骤:

1.yarn-site.xml 中设置关闭虚拟内存检测(避免 centos 和 jdk 的不兼容),分发

2.向 HDFS 10 个 128M 的文件(文件数>两个节点总核数就行,保证每个节点都有任务)

3.命令:

hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-3.1.3-tests.jar TestDFSIO -write -nrFiles 10 -fileSize 128MB    
复制代码


结果分析:

  1. 忽略客户端所在节点的本地副本,参与测试的一共 20 个文件写入集群

  2. 压测后的速度(单个文件的写速度):1.61

  3. 实测速度:1.61*20=32M/s

  4. 三台服务器带宽:12.5*3 略大于实测速度


结论:说明所有网络资源已用满,因此写速度主要受限于网络传输速度

读性能测试  


  • 将上面 10 个文件读取:

  • hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-3.1.3-tests.jar TestDFSIO -read -nrFiles 10 -fileSize 128MB

  • 测试完毕,收尾,删除测试数据

  • hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-3.1.3-tests.jar TestDFSIO -clean


结论:测试节点存在文件副本,就近读取,读的本地磁盘,没经过网络,读速度不受网络限制,只受磁盘读写速度限制。

多目录  

NameNode 多目录配置

NN 本地目录配置为多个,每个目录存放内容相同

说明:备份了 nn,提高了可靠性,但不是高可用,nn 所在节点挂掉集群仍无法工作


步骤:

  1. hdfs-site.xml 中添加内容,将 dfs.namenode.name.dir 修改为两个目录

  2. 停止集群,删除所有节点的 date logs 中数据

  3. 格式化 nn 后启动集群


DataNode 多目录配置

DN 可以配置成多目录,不同于 nn 的备份,dn 多目录存放不同数据,解决磁盘空间不足问题。


步骤:

  1. hdfs-site.xml 中添加内容,将 dfs.datanode.data.dir 修改为两个目录

  2. 将该配置文件适量分发,因每个服务器配置可能不同,分发请慎重


磁盘间数据均衡

增加一块硬盘。刚加载的硬盘没有数据时,可以执行磁盘数据均衡命令。


说明:这是 Hadoop3.x 新特性,单节点内部磁盘均衡。


步骤:

  1. 生成均衡计划:

    hdfs diskbalancer -plan hadoop103

  2. 执行均衡计划:

    hdfs diskbalancer -execute hadoop103.plan.json

  3. 查看当前均衡任务的执行情况:

    hdfs diskbalancer -query hadoop103    

  4. 取消均衡任务:

    hdfs diskbalancer -cancel hadoop103.plan.json

集群扩容及缩容  


添加白名单

在白名单的主机 IP 地址才可以用来存储数据。可以尽量防止黑客恶意访问攻击。


步骤:

  1. hadoop 软件包下的 etc/hadoop 目录下创建 whitelist blacklist 文件

  2. whitelist 文件中加入集群节点的 ip 或主机名(映射)

  3. hdfs-site.xml 中增加 dfs.hosts 配置参数为 whitelist 路径并分发

  4. 第一次创白名单得重启集群,否则只需刷新 nn 节点(hdfs dfsadmin -refreshNodes)


服役新服务器 

动态增加服务器,不重启集群即可实现服役新服务器,主要解决数据节点容量不足。


步骤:

  1. 环境准备:修改新主机的 ip、主机名;将软件包目录和环境变量脚本拷贝过来;清空,data log 目录下的数据;配置和其他节点的无密登录

  2. 服役新节点:启动该节点的 datanode nodemanager 的后台进程

  3. 白名单中增加待加入的节点并分发

  4. 刷新 nn


服务器间数据均衡  


如果常在某个节点提交任务,由于数据本地性原则,该节点数据量过多,造成数据节点间量的 差距,或者,新服役的服务器数据量比较少,需要执行集群均衡命令。   


  • 开启数据均衡命令:start-balancer.sh -threshold 10(10 代表的是集群中各个节点的磁盘空间利用率相差不超过 10%,可根据实际情况进行调整)

  • 停止数据均衡命令:stop-balancer.sh


黑名单退役服务器 


步骤:

  1. hadoop 软件包目录的 etc/hadoop 目录下编辑 blacklist 文件:添加要退役的节点

  2. hdfs-site.xml 配置文件中增加 dfs.hosts.exclude 配置参数,分发

  3. 同白名单一样,第一次创黑名单需重启集群,否则刷新 nn 节点


说明:

  1. 节点退役时,web 界面可以看到,退役节点的状态为 decommission in progress(退役中),说明数据节点正在复制块到其他节点

  2. 此操作是保证副本数满足要求, 如果副本数是 3,服役的节点小于等于 3,是不能退役成功的,需要修改副本数后才能退役

  3. 如果节点间数据不均衡,可以用命令再平衡

存储优化  


纠删码

Hadoop3.x 引入了纠删码,采用计算的方式,可以节省约 50%左右的存储空间。

确切的说:给 hdfs 的一个路径设置单副本存储策略    



纠删码策略:

  1. RS-3-2-1024k

  2. RS-10-4-1024k

  3. RS-6-3-1024k

  4. RS-LEGACY-6-3-1024k

  5. XOR-2-1-1024k


说明(以第一种为例):

使用 RS 编码,每 3 个数据单元,生成 2 个校验单元,共 5 个单元,也就是说:这 5 个单元中,只要有任意的 3 个单元存在(不管是数据单元还是校验单元,只要总数=3),就可以得到原始数据。


每个单元的大小 1024k=1024*1024=1048576


步骤:

  1. 开启对该策略的支持:hdfs ec -enablePolicy -policy < 策略 >

  2. hdfs 上对某个路径的目录设置该策略:hdfs ec -setPolicy -path < 目录 path > -policy < 策略 >    

  3. 以该策略 rs-3-2 为例,上传的文件需大于等于 3 个单元才看出效果


易构存储  


异构存储,又叫冷热数据分离,它不同于纠删码的单副本,它是给 hdfs 的一个路径设置多副本存储策略,手段:不同的数据,存储在不同类型的硬盘中,达到最佳性能



存储类型:

  1. RAM_DISK:内存镜像文件系统(内存)

  2. SSD:SSD 固态硬盘(固态)

  3. DISK:普通磁盘,HDFS 默认的存储类型(机械)

  4. ARCHIVE:归档


policy 存储策略(上–>下:快–>慢):


shell 操作命令:

  1. 查看存储策略:

    hdfs storagepolicies -listPolicies

  2. 设置指定的存储策略:

    hdfs storagepolicies -setStoragePolicy -path xxx -policy xxx

  3. 获取指定路径的存储策略:

    hdfs storagepolicies -getStoragePolicy -path xxx

  4. 取消存储策略:

    hdfs storagepolicies -unsetStoragePolicy -path xxx    

  5. 查看文件块的分布:

    bin/hdfs fsck xxx -files -blocks -locations

  6. 查看集群节点:

    hadoop dfsadmin -report

          

具体实施步骤:

  • 在需修改的节点修改 hdfs-site.xml 配置文件的参数

  • 统一副本数:dfs.replication

  • 开启异构存储:dfs.storage.policy.enabled

  • 修改该节点磁盘存储类型:dfs.datanode.data.dir

  • 格式化 nn,重启集群

  • 未设置存储策略,所有文件块都存储在 DISK 下。所以,默认存储策略为 HOT

  • 修改存储策略,给数据升温/降温:set 命令(可以看到文件块依然放在原处)

  • hdfs mover xxx:让 HDFS 按照存储策略自行移动文件块,可以看到副本移动到策略里指定的类型的磁盘 


补充:

关于 LAZY_PERSIST 策略的说明:文件就不会按该策略如期出现在指定类型的磁盘,即一个副本存储在 RAM_DISK,其他副本存储在 DISK 中,因为:

  1. dfs.datanode.max.locked.memory 该参数未配置默认是 0,即不允许放在内存中

  2. 虽然可调,但默认上限为 64kb

  3. 上限就是 max locked memory,虽然它也可调,但是易出错,不推荐,所以别使用该策略最好    

故障排除 


NameNode 故障

前置工作:

  1. 模拟 nn 进程挂了,存储的数据也丢了,如何恢复

  2. 杀死进程(kill -9 PID),删除 nn 目录下的数据(/opt/module/hadoop-3.1.3/data/tmp/dfs/name)


问题解决:

  1. (在 nn 节点的 dfs 目录下操作)拷贝 2NN 中的数据到 nn 存储数据目录:scp -r 用户 @主机名:/opt/module/hadoop-3.1.3/data/dfs/namesecondary/* ./name/

  2. 重启 nn 后台进程

          

说明:

前面 HDFS 架构中可以了解到:nn 比 2nn 目录下多了一个正在追加写的 Edits 文件,里面写了集群最新的操作内容,所以这种故障的排除有个前提,就是近期的追加写文件里没有操作,才算完全恢复,因此该方式不算高可用(后期使用 HA 解决)

集群安全模式 &磁盘修复  


安全模式:文件系统只接受读数据请求,而不接受删除、修改等变更请求


进入安全模式场景:

  1. nn 在加载镜像文件和编辑日志期间处于安全模式;

  2. NameNode 再接收 DataNode 注册时,处于安全模式


退出安全模式条件(以下需全部满足):

  1. 可用数据节点>0    

  2. 最多丢失一块 block 的所有副本

  3. 满足前两个条件并稳定 30s


相关命令



案例 1:启动集群进入安全模式 


启动集群后立即(30s 以内)来到集群 web 界面删除数据,提示集群处于安全模式


案例 2:硬盘修复 


删除两个块的所有副本,重启集群–>web 界面提示块数量对不上警告–>输入命令离开安全模式–>依然警告–>不管则每次安全模式开启时都会警告–>解决办法:将警告信息中的已经丢失的文件块对应的元数据删除,或者联系磁盘厂家修复–>集群正常


案例 3:模拟等待安全模式 


先进入安全模式(不可 hdfs 写入)–>编写脚本:包含等待安全模式命令,以及 hdfs 写入命令–>使用另一个窗口执行脚本–>当安全模式退出时即可完成脚本中的 hdfs 写入


小文件归档 


问题:

hdfs 存储小文件时,按 128M 的块存储,小文件相比大文件更消耗 nn 大量内存,导致 hdfs 存储效率低下…


解决手段:    

使用文件存档工具:HAR 文件(存档文件)



步骤:

  1. 启动 yarn:因为要提交作业执行程序将小文件读取,后写入到归档文件

  2. /input 目录里面的所有文件归档成一个叫 input.har 的归档文件,并把归档后文件存储到/output 路径下:

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

  4. 查看归档:

  5. hadoop fs -ls /output/input.har

  6. hadoop fs -ls har:///output/input.har

  7. 解归档文件:

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

  8. 上两步其实就是普通的 hadoop 命令加入了 har 协议


MapReduce 调优 

MR 慢的原因(计算机性能)

  1. CPU 是否充足

  2. 内存是否够用

  3. 磁盘速度+冷热分离

  4. 网络带宽限制   


I/O 操作优化

  1. 数据倾斜:某个 ReduceTask 处理分区数据过多

  2. Map 运行时间太长,导致 Reduce 等待过久

  3. 小文件过多,MapTask 并行度过高,资源不够

核心参数  



自定义分区,将 map 的输出数据合理分担到多个 maptask 可以减少数据倾斜

减少环形缓冲区溢写次数,即减少溢写的文件个数:

mapreduce.task.io.sort.mb,缓冲区大小默认 100–>200

mapreduce.map.sort.spill.percent,开始反向溢写的阈值默认 80–>90


增加每次 Merge 合并次数(前提,系统内存充足):

mapreduce.task.io.sort.factor 默认 10–>20

合理增加预聚合 Combiner

可采用 Snappy LZO 压缩


MapTask 内存:

mapreduce.map.memory.mb 默认 1024M,前面使用压缩这里相应增加内存

同时保持 MapTask 堆内存(mapreduce.map.java.opts)和该值一致

适当增加 MapTask 的核数:mapreduce.map.cpu.vcores

异常重试:mapreduce.map.maxattempts 默认是 4 适当修改   



提高 Reduce 去 Map 中拉取数据的并行数:

mapreduce.reduce.shuffle.parallellcopies默认5–>10
复制代码


拉取数据的缓存在 Reduce 内存占比:

mapreduce.reduce.shuffle.input.buffer.percent默认0.7–>0.8
复制代码


数据在缓存占比多少开始向磁盘溢写:

mapreduce.reduce.shuffle.merge.percent默认0.66–>0.75
复制代码


ReduceTask 内存上限:

mapreduce.reduce.memory.mb默认1024适当提高
复制代码

同时修改堆内存 mapreduce.reduce.java.opts 与其一致


ReduceTask 核数:

mapreduce.reduce.cpu.vcores默认是1可提高到2-4个
复制代码


异常重试:

mapreduce.reduce.maxattempts 默认是 4 适当修改

MapTask 完成的比例达到该值后才会为 ReduceTask 申请资源:

mapreduce.job.reduce.slowstart.completedmaps:0.05


任务超时时间:

mapreduce.task.timeout默认600000(10分钟)
复制代码

Reduce 能不用就省,没有 reduce 过程就可以不经过 shuffle 过程  


Reduce 数据倾斜 


数据频率倾斜——某一个区域的数据量要远远大于其他区域。

数据大小倾斜——部分记录的大小远远大于平均值。


解决办法:

mapjoin/分区/预聚合/空值 key 打散

空值过多:要么过滤空值,要么保留就得自定义分区,将空值加随机数打散,在二次聚合 map 能先处理就先处理 Combiner 或者 MapJoin 分区并设置多个 reduce 个数

Yarn 调优


ResourceManager 相关处理调度器请求的线程数量:

yarn.resourcemanager.scheduler.client.thread-count
复制代码


配置调度器:

yarn.resourcemanager.scheduler.class
复制代码


NodeManager 相关


1.NodeManager 使用内存大小:

yarn.nodemanager.resource.memory-mb
复制代码


2.使用 CPU 核数:

yarn.nodemanager.resource.cpu-vcores
复制代码


3.是否将虚拟核数当作 CPU 核数:

yarn.nodemanager.resource.count-logical-processors-as-cores
复制代码


4.虚拟核数和物理核数乘数,例如:4 核 8 线程,该参数就应设为 2:

yarn.nodemanager.resource.pcores-vcores-multiplier
复制代码


5.是否让 yarn 自己检测硬件进行配置:

yarn.nodemanager.resource.detect-hardware-capabilities
复制代码


6.是否开启物理内存检查限制 container:

yarn.nodemanager.pmem-check-enabled
复制代码


7.是否开启虚拟内存检查限制 container:

yarn.nodemanager.vmem-check-enabled
复制代码


8.虚拟内存物理内存比例:

yarn.nodemanager.vmem-pmem-ratio
复制代码


Container 容器相关


1.容器最小内存:

yarn.scheduler.minimum-allocation-mb
复制代码

2.容器最大内存;

3.容器最小核数:

yarn.scheduler.minimum-allocation-vcores
复制代码


Hadoop 综合调优


  1. 以上参数配置和优化方法已经满足了大部分调优    

  2. 这里最终汇总一下从三个方向包括四个具体步骤 Hadoop 小文件优化

数据源头  

在数据采集的时候,就将小文件或小批数据合成大文件再上传 HDFS

数据存储  

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

计算  

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


开启 uber 模式.实现 JVM 重用:

让同一个 Job 的多个 Task 运行在一个 JVM 中,不必为每个 Task 都开启一个 JVM


开启 uber 模式:需在 mapred-site.xml 配置文件中添加以下参数:

  1. 开启 uber 模式:mapreduce.job.ubertask.enable

  2. 将最大的 mapTask 数量向下修改 mapreduce.job.ubertask.maxmaps

  3. 将最大的 reduce 数量向下修改 mapreduce.job.ubertask.maxreduces

  4. 将最大的输入数据量,默认使用 dfs.blocksize 的值向下修改 mapreduce.job.ubertask.maxbytes


该模式优势:

  1. 开启的容器数锐减:因为多个 task 共用一个容器

  2. 减少了开关 jvm 时间


以上就是今天分享的全部内容。


如果你想了解更多关于:Cloudera 系统环境准备、基础环境安装、集群部署以及应用组件安装等全方位的技术的问题。例如:从环境搭建/集群部署,内存扩容/问题排查,数据迁移等助你轻松应对数据管理的复杂性。可以联系我:15928721005

感谢你的阅读,如果喜欢我的文字,可以持续关注我,会陆续为你更新更多干货小知识。


用户头像

公众号:【TASKCTL】官方免费直接授权使用 2020-12-23 加入

一款国产免费企业级ETL调度批处理工具;支持各类脚本任务程序和扩展;具备可视化图形拖拽设计界面以及可视化任务管理、计划调度、实时监控、消息预警和日志分析;有效弥补了传统ETL工具在调度管理和监控分析方面不足

评论

发布
暂无评论
Hadoop优化|全面调优攻略 | HDFS、MapReduce、YARN性能提升秘诀 | 专家实战分享!_hadoop_敏捷调度TASKCTL_InfoQ写作社区