目录
一、HDFS—核心参数
1.Hadoop3.x系列配置NameNode内存
(1)查看NameNode占用内存
jmap -heap 节点代码
(2)修改位置:hadoop-env.sh
export HDFS_NAMENODE_OPTS="-Dhadoop.security.logger=INFO,RFAS -Xmx1024m"
export HDFS_DATANODE_OPTS="-Dhadoop.security.logger=ERROR,RFAS -Xmx1024m"
修改为1G.
2.NameNode心跳并发配置
NameNode有一个工作线程池,用来处理不同DataNode的并发心跳以及客户端并发的元数据操作。对于大集群或者有大量客户端的集群来说,通常需要增大该参数。默认值是10。
企业经验:dfs.namenode.handler.count=20*ln(Cluster size),比如集群规模(DataNode台数)为3台时,此参数设置为21。
(1)设置hdfs-site.xml
<property>
<name>dfs.namenode.handler.count</name>
<value>21</value>
</property>
3.开启回收站配置
开启回收站功能,可以将删除的文件在不超时的情况下,恢复原数据,起到防止误删除、备份等作用。
(1)回收站工作机制
开启回收站后,删除的文件会被暂存到另一个目录下,用户可以设置自动清除时间,时间以内可以恢复文件,时间过后才会真正被自动删除。
(2)开启回收站功能参数说明
a.默认值fs.trash.interval = 0,0表示禁用回收站;其他值表示设置文件的存活时间。
b.默认值fs.trash.checkpoint.interval = 0,检查回收站的间隔时间。如果该值为0,则该值设置和fs.trash.interval的参数值相等。
c.要求fs.trash.checkpoint.interval <= fs.trash.interval。
(3)启用回收站
修改core-site.xml,配置垃圾回收时间为1分钟。
<property>
<name>fs.trash.interval</name>
<value>1</value>
</property>
(4)注意
a.通过程序删除的文件不会经过回收站,需要调用moveToTrash()才进入回收站。
b.通过网页上直接删除的文件也不会走回收站。
c.只有在命令行利用hadoop fs -rm命令删除的文件才会走回收站。
d.恢复数据,只有在垃圾回收时间之前移除回收站目录。
二、HDFS—集群压测
1.HDFS—集群压测(写/读)
为了搞清楚HDFS的读写性能,生产环境上非常需要对集群进行压测。HDFS的读写性能主要受网络和磁盘影响比较大。
(1)命令
hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-3.1.3-tests.jar TestDFSIO -write(read) -nrFiles 10 -fileSize 128MB
(2)参数解析
a.Number of files:生成mapTask数量,一般是集群中(CPU核数-1),我们测试虚拟机就按照实际的物理内存-1分配即可。
b.Total MBytes processed:单个map处理的文件大小。
c.Throughput mb/sec:单个mapTak的吞吐量。
d.计算方式:处理的总文件大小/每一个mapTask写数据的时间累加。
e.集群整体吞吐量:生成mapTask数量*单个mapTak的吞吐量。
f.Average IO rate mb/sec::平均mapTak的吞吐量。
g.计算方式:每个mapTask处理文件大小/每一个mapTask写数据的时间全部相加除以task数量。
h.IO rate std deviation:方差、反映各个mapTask处理的差值,越小越均衡。
三、HDFS——多目录
1.NameNode多目录配置
NameNode的本地目录可以配置成多个,且每个目录存放内容相同,增加了可靠性。
(1)在hdfs-site.xml文件中添加如下内容
<property>
<name>dfs.namenode.name.dir</name>
<value>file://${hadoop.tmp.dir}/dfs/name1,file://${hadoop.tmp.dir}/dfs/name2</value>
</property>
(2)注意
结束后需要删除data和logs内的所有数据,并且格式化集群。
2.DataNode多目录配置
DataNode可以配置成多个目录,每个目录存储的数据不一样。
(1)在hdfs-site.xml文件中添加如下内容
<property>
<name>dfs.datanode.data.dir</name>
<value>file://${hadoop.tmp.dir}/dfs/data1,file://${hadoop.tmp.dir}/dfs/data2</value>
</property>
3.集群数据均衡之磁盘间数据均衡
(1)生成均衡计划
hdfs diskbalancer -plan hadoop103
(2)执行均衡计划
hdfs diskbalancer -execute hadoop103.plan.json
(3)查看当前均衡任务的执行情况
hdfs diskbalancer -query hadoop103
(4)取消均衡任务
hdfs diskbalancer -cancel hadoop103.plan.json
四、HDFS——集群扩容及缩容
1.添加白名单
表示在白名单的主机IP地址可以,用来存储数据。配置白名单,可以尽量防止黑客恶意访问攻击。
(1)配置白名单步骤
a.在NameNode节点的/opt/module/hadoop-3.1.3/etc/hadoop目录下分别创建whitelist 和blacklist文件。
b.在whitelist中添加主机名称。
(2)创建黑名单
[root@hadoop001 hadoop]$ touch blacklist
(3)在hdfs-site.xml配置文件中增加dfs.hosts配置参数
<!-- 白名单 -->
<property>
<name>dfs.hosts</name>
<value>/opt/module/hadoop-3.1.3/etc/hadoop/whitelist</value>
</property>
<!-- 黑名单 -->
<property>
<name>dfs.hosts.exclude</name>
<value>/opt/module/hadoop-3.1.3/etc/hadoop/blacklist</value>
</property>
(4)分发配置文件whitelist,hdfs-site.xml
2.服役新服务器
随着公司业务的增长,数据量越来越大,原有的数据节点的容量已经不能满足存储数据的需求,需要在原有集群基础上动态添加新的数据节点。
(1)配置新的服务器相关参数,如:主机名称,IP地址等。
(2)拷贝hadoop001的/opt/module目录和/etc/profile.d/my_env.sh到新hadoop节点,删除新节点上Hadoop的历史数据,data和log数据。
(3)直接启动DataNode,即可关联到集群。
(4)在白名单中增加新服役的服务器,并重启集群。
3.服务器间数据均衡
在企业开发中,如果经常在hadoop102和hadoop104上提交任务,且副本数为2,由于数据本地性原则,就会导致hadoop102和hadoop104数据过多,hadoop103存储的数据量小。另一种情况,就是新服役的服务器数据量比较少,需要执行集群均衡命令。
(1)开启数据均衡命令
[atguigu@hadoop105 hadoop-3.1.3]$ sbin/start-balancer.sh -threshold 10
参数10,代表的是集群中各个节点的磁盘空间利用率相差不超过10%,可根据实际情况进行调整。
(2)停止数据均衡命令
[atguigu@hadoop105 hadoop-3.1.3]$ sbin/stop-balancer.sh
注意:由于HDFS需要启动单独的Rebalance Server来执行Rebalance操作,所以尽量不要在NameNode上执行start-balancer.sh,而是找一台比较空闲的机器。
4.黑名单退役服务器
表示在黑名单的主机IP地址不可以,用来存储数据。配置黑名单,用来退役服务器。
(1)编辑/opt/module/hadoop-3.1.3/etc/hadoop目录下的blacklist文件
[atguigu@hadoop102 hadoop] vim blacklist
添加新主机名称。如:Hadoop005;
(2)注意
等待退役节点状态为decommissioned(所有块已经复制完成),停止该节点及节点资源管理器。注意:如果副本数是3,服役的节点小于等于3,是不能退役成功的,需要修改副本数后才能退役。
如果数据不均衡,可以用命令实现集群的再平衡。
五、HDFS——存储优化
1.纠删码
HDFS默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。Hadoop3.x引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。
使用计算资源节省存储资源。
(1)纠删码操作相关的命令
[atguigu@hadoop102 hadoop-3.1.3]$ hdfs ec
(2)纠删码策略解释
RS-3-2-1024k:使用RS编码,每3个数据单元,生成2个校验单元,共5个单元,也就是说:这5个单元中,只要有任意的3个单元存在(不管是数据单元还是校验单元,只要总数=3),就可以得到原始数据。每个单元的大小是1024k=1024*1024=1048576。
RS-10-4-1024k:使用RS编码,每10个数据单元(cell),生成4个校验单元,共14个单元,也就是说:这14个单元中,只要有任意的10个单元存在(不管是数据单元还是校验单元,只要总数=10),就可以得到原始数据。每个单元的大小是1024k=1024*1024=1048576。
RS-6-3-1024k:使用RS编码,每6个数据单元,生成3个校验单元,共9个单元,也就是说:这9个单元中,只要有任意的6个单元存在(不管是数据单元还是校验单元,只要总数=6),就可以得到原始数据。每个单元的大小是1024k=1024*1024=1048576。
RS-LEGACY-6-3-1024k:策略和上面的RS-6-3-1024k一样,只是编码的算法用的是rs-legacy。
XOR-2-1-1024k:使用XOR编码(速度比RS编码快),每2个数据单元,生成1个校验单元,共3个单元,也就是说:这3个单元中,只要有任意的2个单元存在(不管是数据单元还是校验单元,只要总数= 2),就可以得到原始数据。每个单元的大小是1024k=1024*1024=1048576。
(3)具体实现
纠删码策略是给具体一个路径设置。所有往此路径下存储的文件,都会执行此策略。默认只开启对RS-6-3-1024k策略的支持,如要使用别的策略需要提前启用。
a.开启对RS-3-2-1024k策略的支持
[atguigu@hadoop102 hadoop-3.1.3]$ hdfs ec -enablePolicy -policy RS-3-2-1024k
b.在HDFS创建目录,并设置RS-3-2-1024k策略
[atguigu@hadoop102 hadoop-3.1.3]$ hdfs dfs -mkdir /input
c.上传文件,并查看文件编码后的存储情况
[atguigu@hadoop102 hadoop-3.1.3]$ hdfs dfs -put web.log /input
2.异构存储(冷热数据分离)
异构存储主要解决,不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。
(1)存储类型和存储策略
RAM_DISK:内存镜像文件系统。
SSD:SSD固态硬盘。
DISK:普通磁盘,在HDFS中,如果没用主动声明数据目录存储类型默认都是DISK。
ARCHIVE:没有特指哪种存储介质,主要的指的是计算能力比较弱而存储密度比较高的存储介质,用来解决数据量的容量扩增问题,一般用于归档。
策略ID | 策略名称 | 副本分布 | 解释 |
15 | Lazy_Persist | RAM_DISK:1,DISK:n-1 | 一个副本保存在内存RAM_DISK中,其余副本保存在磁盘中。 |
12 | AII_SSD | SSD:n | 所有副本都保存在SSD中。 |
10 | One_SSD | SSD:1,DISK:n-1 | 一个副本保存在SSD中,其余副本保存在磁盘中。 |
7 | Hot(default) | DISK:n | 所有副本保存在磁盘中,这也是默认的存储策略。 |
5 | Warm | DISK:1,ARCHIVE:n-1 | 一个副本保存在磁盘上,其余副本保存在归档存储上。 |
2 | Cold | ARCHIVE:n | 所有副本都保存在归档存储上。 |
(2)查看当前有哪些存储策略可以用
[atguigu@hadoop102 hadoop-3.1.3]$ hdfs storagepolicies -listPolicies
(3)为指定路径(数据存储目录)设置指定的存储策略
hdfs storagepolicies -setStoragePolicy -path xxx -policy xxx
(4)获取指定路径(数据存储目录或文件)的存储策略
hdfs storagepolicies -getStoragePolicy -path xxx
(5)取消存储策略
执行改命令之后该目录或者文件,以其上级的目录为准,如果是根目录,那么就是HOT
hdfs storagepolicies -unsetStoragePolicy -path xxx
(6)查看文件块的分布
bin/hdfs fsck xxx -files -blocks -locations
(7)查看集群节点
hadoop dfsadmin -report
六、HDFS——故障排除
1.NameNode故障处理
NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode。
(1)解决办法
拷贝SecondaryNameNode中数据到原NameNode存储数据目录。
重新启动NameNode。
2.集群安全模式&磁盘修复
安全模式:文件系统只接受读数据请求,而不接受删除、修改等变更请求。
(1)进入安全模式场景
a.NameNode在加载镜像文件和编辑日志期间处于安全模式;
b.NameNode再接收DataNode注册时,处于安全模式;
(2)退出安全模式条件
a.dfs.namenode.safemode.min.datanodes:最小可用datanode数量,默认0;
b.dfs.namenode.safemode.threshold-pct:副本数达到最小要求的block占系统总block数的百分比,默认0.999f;(只允许丢一个块)
c.dfs.namenode.safemode.extension:稳定时间,默认值30000毫秒,即30秒;
(3)基本语法
集群处于安全模式,不能执行重要操作(写操作)。集群启动完成后,自动退出安全模式。
bin/hdfs dfsadmin -safemode get (功能描述:查看安全模式状态)
bin/hdfs dfsadmin -safemode enter (功能描述:进入安全模式状态)
bin/hdfs dfsadmin -safemode leave (功能描述:离开安全模式状态)
bin/hdfs dfsadmin -safemode wait (功能描述:等待安全模式状态)
(4)磁盘修复
数据块损坏,进入安全模式想要修复只能删除出问题的块或者找厂商修复。
2.慢磁盘监控
“慢磁盘”指的时写入数据非常慢的一类磁盘。其实慢性磁盘并不少见,当机器运行时间长了,上面跑的任务多了,磁盘的读写性能自然会退化,严重时就会出现写入数据延时的问题。
如何发现慢磁盘?
正常在HDFS上创建一个目录,只需要不到1s的时间。如果你发现创建目录超过1分钟及以上,而且这个现象并不是每次都有。只是偶尔慢了一下,就很有可能存在慢磁盘。可以采用如下方法找出是哪块磁盘慢。
(1)通过心跳未联系时间。
一般出现慢磁盘现象,会影响到DataNode与NameNode之间的心跳。正常情况心跳时间间隔是3s。超过3s说明有异常。
(2)fio命令,测试磁盘的读写性能
进行顺序读测试、顺序写测试、随机写测试、混合随机读写。
3.小文件归档
(1)HDFS存储小文件弊端
每个文件均按块存储,每个块的元数据存储在NameNode的内存中,因此HDFS存储小文件会非常低效。因为大量的小文件会耗尽NameNode中的大部分内存。但注意,存储小文件所需要的磁盘容量和数据块的大小无关。例如,一个1MB的文件设置为128MB的块存储,实际使用的是1MB的磁盘空间,而不是128MB。
(2)解决存储小文件办法之一
HDFS存档文件或HAR文件,是一个更高效的文件存档工具,它将文件存入HDFS块,在减少NameNode内存使用的同时,允许对文件进行透明的访问。具体说来,HDFS存档文件对内还是一个一个独立文件,对NameNode而言却是一个整体,减少了NameNode的内存。
4.HDFS——集群迁移
(1)scp实现两个远程主机之间的文件复制
scp -r hello.txt root@hadoop103:/user/atguigu/hello.txt // 推 push
scp -r root@hadoop103:/user/atguigu/hello.txt hello.txt // 拉 pull
scp -r root@hadoop103:/user/atguigu/hello.txt root@hadoop104:/user/atguigu //是通过本地主机中转实现两个远程主机的文件复制;如果在两个远程主机之间ssh没有配置的情况下可以使用该方式。
(2)采用distcp命令实现两个Hadoop集群之间的递归数据复制
[atguigu@hadoop102 hadoop-3.1.3]$ bin/hadoop distcp hdfs://hadoop102:8020/user/atguigu/hello.txt hdfs://hadoop105:8020/user/atguigu/hello.txt
七、MapReduce生产经验
1.MapReduce跑的慢的原因
(1)计算机性能
CPU、内存、磁盘、网络。
(2)I/O操作优化
数据倾斜、Map运行时间太长,导致Reduce等待过久、小文件过多等。
2.MapReduce常用调优参数
MapTask对应的shuffle
(1)自定义分区,减少数据倾斜
定义类,继承Parttitioner接口,重写getPartition方法。
(2)减小溢写次数
Shuffle的环形缓冲区大小,默认100m,可以提高到200m。
环形缓冲区溢出的阈值,默认80%,可以提高到90%。
(3)增加每次Merage合并次数
默认10,可以提高到20。
(4)在不影响业务结果的前提下可以提前采用Combiner
(5)为了减少磁盘IO,可以采用Snappy或者LZO压缩
(6)默认MapTask内存上限1024MB。可以根据128m数据对应1G内存原则提高该内存。
(7)控制MapTask堆内存大小。
(8)默认MapTask的CPU核数1。计算密集型任务可以增加CPU核数。
(9)异常重试
每个MapTask最大重试次数,一旦重试次数超过该值,则认为MapTask运行失败,默认值:4。根据机器性能适当提高。
ReduceTask对应的shuffle
(1)每个Reduce区Map中拉取数据的并行数,默认值是5,可以提高到10。
(2)Buffer大小占Reduce可用内存的比例,默认值是0.7,可以提高到0.8。
(3)Buffer中的数据达到多少比例开始写入磁盘,默认值是0.66,可以提高到0.75。
(4)默认ReduceTask内存上限1024MB,根据128m数据对应1G内存原则,适当提高内存到4-6G。
(5)控制ReduceTask堆内存大小。
(6)默认ReduceTask的CPU核数1个。可以提高到2-4个。
(7)每个Reduce Task最大重试次数,一旦重试次数超过该值,则认为MapTask运行失败,默认值:4。
(8)当MapTask完成的比例达到该值后才会为ReduceTask申请资源,默认是0.05。
(9)如果一个Task在一定时间内没有任何进入,即不会读取新的数据,也没有输出数据,则认为该Task处于Block状态,可能是卡住了,也许永远会卡住,为了防止因为用户程序永远在Block住不退出,则强制设置了一个该超时时间(ms),默认是600000(十分钟)。如果你的程序对每条输入数据的处理时间过长,建议将该参数调大。
(10)如果可以不用Reduce,尽可能不用。
八、Hadoop-Yarn生产经验
参考:https://blog.csdn.net/wq45255446/article/details/126216606?spm=1001.2014.3001.5501
九、Hadoop综合调优
1.Hadoop小文件优化方法
(1)弊端
HDFS上每个文件都要在NameNode上创建对应的元数据,这个元数据的大小约为150byte,这样当小文件比较多的时候,就会产生很多的元数据文件,一方面会大量占用NameNode的内存空间,另一方面就是元数据文件过多,使得寻址索引速度变慢。
小文件过多,在进行MR计算时,会生成过多切片,需要启动过多的MapTask。每个MapTask处理的数据量小,导致MapTask的处理时间比启动时间还小,白白消耗资源。
(2)解决方案
a.在数据采集的时候,就将小文件或小批数据合成大文件再上传HDFS(数据源头)
b.Hadoop Archive(存储方向)
是一个高效的将小文件放入HDFS块中的文件存档工具,能够将多个小文件打包成一个HAR文件,从而达到减少NameNode的内存使用
c.CombineTextInputFormat(计算方向)
CombineTextInputFormat用于将多个小文件在切片过程中生成一个单独的切片或者少量的切片。
d.开启uber模式,实现JVM重用(计算方向)
默认情况下,每个Task任务都需要启动一个JVM来运行,如果Task任务计算的数据量很小,我们可以让同一个Job的多个Task运行在一个JVM中,不必为每个Task都开启一个JVM。
(3)开启uber模式,在mapred-site.xml中添加如下配置
<!-- 开启uber模式,默认关闭 -->
<property>
<name>mapreduce.job.ubertask.enable</name>
<value>true</value>
</property>
<!-- uber模式中最大的mapTask数量,可向下修改 -->
<property>
<name>mapreduce.job.ubertask.maxmaps</name>
<value>9</value>
</property>
<!-- uber模式中最大的reduce数量,可向下修改 -->
<property>
<name>mapreduce.job.ubertask.maxreduces</name>
<value>1</value>
</property>
<!-- uber模式中最大的输入数据量,默认使用dfs.blocksize 的值,可向下修改 -->
<property>
<name>mapreduce.job.ubertask.maxbytes</name>
<value></value>
</property>