1)安全模式:文件系统只接受读数据请求,而不接受删除、修改等变更请求
2)进入安全模式场景
NameNode在加载镜像文件和编辑日志期间处于安全模式
NameNode再接收DataNode注册时,处于安全模式
3)退出安全模式条件
dfs.namenode.safemode.min.datanodes:最小可用datanode数量,默认0;
dfs.namenode.safemode.threshold-pct:副本数达到最小要求的block占系统总block数的百分比,默认0.999f。
dfs.namenode.safemode.extension:稳定时间,默认值30000毫秒,即30秒
4)基本语法
集群处于安全模式,不能执行重要操作(写操作)。集群启动完成后,自动退出安全模式。
bin/hdfs dfsadmin -safemode get #(功能描述:查看安全模式状态)
bin/hdfs dfsadmin -safemode enter #(功能描述:进入安全模式状态)
bin/hdfs dfsadmin -safemode leave #(功能描述:离开安全模式状态)
bin/hdfs dfsadmin -safemode wait #(功能描述:等待安全模式状态)
1)需求:
NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode
2)故障模拟
(1)kill -9 NameNode进程
[atguigu@hadoop102 current]$ kill -9 NameNode的进程号
(2)删除NameNode存储的数据(/opt/module/hadoop-3.1.3/data/tmp/dfs/name)
[atguigu@hadoop102 hadoop-3.1.3]$ rm -rf /opt/module/hadoop-3.1.3/data/dfs/name/*
3)问题解决
(1)拷贝SecondaryNameNode中数据到原NameNode存储数据目录
[atguigu@hadoop102 dfs]$ scp -r atguigu@hadoop104:/opt/module/hadoop-3.1.3/data/dfs/namesecondary/* ./name/
(2)重新启动NameNode
[atguigu@hadoop102 hadoop-3.1.3]$ hdfs --daemon start namenode
(3)向集群上传一个文件
将NN中的元数据全部删除(edits,edits_inprogress,fsimage)
停掉NN后再重启NN发现启动不起来
紧急恢复(生产环境中不会发生此事因为会用HA)将2NN中的edits和fsimage拷贝到NN中
只能恢复一部分数据。还会停留在安全模式中。
如果不在乎那部分数据集群想恢复正常:
hdfs dfsadmin -safemode forceExit
当我们把三台节点中的两个块删除后重启NameNode会进入安全模式
想正常操作要退出安全模式
再重启NameNode仍然会进入安全模式(除非把丢失块的元数据(通 过命令或者在页面上删除)就不会再停留在安全模式)
1)DataNode可以配置成多个目录,每个目录存储的数据不一样(数据不是副本)
2)具体配置如下
在hdfs-site.xml文件中添加如下内容。
dfs.datanode.data.dir
file://${hadoop.tmp.dir}/dfs/data,
file://${hadoop.tmp.dir}/dfs/data2
3)查看结果
[atguigu@hadoop102 dfs]$ ll
总用量 12
drwx------. 3 atguigu atguigu 4096 4月 4 14:22 data
drwx------. 3 atguigu atguigu 4096 4月 4 14:22 data2
drwxrwxr-x. 3 atguigu atguigu 4096 12月 11 08:03 name1
drwxrwxr-x. 3 atguigu atguigu 4096 12月 11 08:03 name2
4)向集群上传一个文件,再次观察两个文件夹里面的内容发现不一致(一个有数一个没有)
[atguigu@hadoop102 hadoop-3.1.3]$ hadoop fs -put wcinput/word.txt /
产环境,由于硬盘空间不足,往往需要增加一块硬盘。刚加载的硬盘没有数据时,可以执行磁盘数据均衡命令。(Hadoop3.x新特性)。
(1)生成均衡计划(我们只有一块磁盘,不会生成计划)
hdfs diskbalancer -plan hadoop102
(2)执行均衡计划
hdfs diskbalancer -execute hadoop102.plan.json
(3)查看当前均衡任务的执行情况
hdfs diskbalancer -query hadoop102
(4)取消均衡任务
hdfs diskbalancer -cancel hadoop102.plan.json
1)需求
随着公司业务的增长,数据量越来越大,原有的数据节点的容量已经不能满足存储数据的需求,需要在原有集群基础上动态添加新的数据节点。
2)环境准备
(1)在hadoop100主机上再克隆一台hadoop105主机
(2)修改IP地址和主机名称
[root@hadoop105 ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33
[root@hadoop105 ~]# vim /etc/hostname
(3)拷贝hadoop102的/opt/module目录和/etc/profile.d/my_env.sh到hadoop105
[atguigu@hadoop102 opt]$ scp -r module/*atguigu@hadoop105:/opt/module/
[atguigu@hadoop102 opt]$ sudo scp /etc/profile.d/my_env.shroot@hadoop105:/etc/profile.d/my_env.sh
[atguigu@hadoop105 hadoop-3.1.3]$ source /etc/profile
(4)删除hadoop105上Hadoop的历史数据,data和log数据
[atguigu@hadoop105 hadoop-3.1.3]$ rm -rf data/ logs/
(5)配置hadoop102和hadoop103到hadoop105的ssh无密登录
[atguigu@hadoop102 .ssh]$ ssh-copy-id hadoop105
[atguigu@hadoop103 .ssh]$ ssh-copy-id hadoop105
3)服役新节点具体步骤
直接启动DataNode,即可关联到集群
[atguigu@hadoop105 hadoop-3.1.3]$ hdfs --daemon start datanode
[atguigu@hadoop105 hadoop-3.1.3]$ yarn --daemon start nodemanager
1)企业经验:
在企业开发中,如果经常在hadoop102和hadoop104上提交任务,且副本数为2,由于数据本地性原则,就会导致hadoop102和hadoop104数据过多,hadoop103存储的数据量小。
另一种情况,就是新服役的服务器数据量比较少,需要执行集群均衡命令。
2)开启数据均衡命令
[atguigu@hadoop105 hadoop-3.1.3]$ sbin/start-balancer.sh -threshold 10
对于参数10,代表的是集群中各个节点的磁盘空间利用率相差不超过10%,可根据实际情况进行调整。
3)停止数据均衡命令
[atguigu@hadoop105 hadoop-3.1.3]$ sbin/stop-balancer.sh
注意:由于HDFS需要启动单独的RebalanceServer来执行Rebalance操作,所以尽量不要在NameNode上执行start-balancer.sh,而是找一台比较空闲的机器。
白名单:表示在白名单的主机IP地址可以,用来存储数据。
企业中:配置白名单,可以尽量防止黑客恶意访问攻击。
配置白名单步骤如下:
1)在NameNode节点的/opt/module/hadoop-3.1.3/etc/hadoop目录下分别创建whitelist 和blacklist文件
(1)创建白名单
[atguigu@hadoop102 hadoop]$ vim whitelist
# 在whitelist中添加如下主机名称,假如集群正常工作的节点为102 103 :
hadoop102
hadoop103
(2)创建黑名单
[atguigu@hadoop102 hadoop]$ touch blacklist
保持空的就可以。
2)在hdfs-site.xml配置文件中增加dfs.hosts配置参数
dfs.hosts
/opt/module/hadoop-3.1.3/etc/hadoop/whitelist
dfs.hosts.exclude
/opt/module/hadoop-3.1.3/etc/hadoop/blacklist
3)分发配置文件whitelist,hdfs-site.xml
[atguigu@hadoop104 hadoop]$ xsync hdfs-site.xml whitelist
4)第一次添加白名单必须重启集群,不是第一次,只需要刷新NameNode节点即可
[atguigu@hadoop102 hadoop-3.1.3]$ myhadoop.sh stop
[atguigu@hadoop102 hadoop-3.1.3]$ myhadoop.sh start
5)在web浏览器上查看DN,http://hadoop102:9870/dfshealth.html#tab-datanode
6)二次修改白名单,增加hadoop104
[atguigu@hadoop102 hadoop]$ vim whitelist
修改为如下内容
hadoop102
hadoop103
hadoop104
hadoop105
7)刷新NameNode
[atguigu@hadoop102 hadoop-3.1.3]$ hdfs dfsadmin -refreshNodes
Refresh nodes successful
8)在web浏览器上查看DN,http://hadoop102:9870/dfshealth.html#tab-datanode
黑名单:表示在黑名单的主机IP地址不可以,用来存储数据。
企业中:配置黑名单,用来退役服务器。
黑名单配置步骤如下:
1)编辑/opt/module/hadoop-3.1.3/etc/hadoop目录下的blacklist文件
[atguigu@hadoop102 hadoop] vim blacklist
添加如下主机名称(要退役的节点)
hadoop105
注意:如果白名单中没有配置,需要在hdfs-site.xml配置文件中增加dfs.hosts配置参数
dfs.hosts.exclude
/opt/module/hadoop-3.1.3/etc/hadoop/blacklist
2)分发配置文件blacklist,hdfs-site.xml
[atguigu@hadoop104 hadoop]$ xsync hdfs-site.xml blacklist
3)第一次添加黑名单必须重启集群,不是第一次,只需要刷新NameNode节点即可
[atguigu@hadoop102 hadoop-3.1.3]$ hdfs dfsadmin -refreshNodes
Refresh nodes successful
4)检查Web浏览器,退役节点的状态为decommission in progress(退役中),说明数据节点正在复制块到其他节点
5)等待退役节点状态为decommissioned(所有块已经复制完成),停止该节点及节点资源管理器。注意:如果副本数是3,服役的节点小于等于3,是不能退役成功的,需要修改副本数后才能退役
[atguigu@hadoop105 hadoop-3.1.3]$ hdfs --daemon stop datanode
stopping datanode
[atguigu@hadoop105 hadoop-3.1.3]$ yarn --daemon stop nodemanager
stopping nodemanager
6)如果数据不均衡,可以用命令实现集群的再平衡
[atguigu@hadoop102 hadoop-3.1.3]$ sbin/start-balancer.sh -threshold10
MapReduce优化方法主要从六个方面考虑:数据输入、Map阶段、Reduce阶段、IO传输、数据倾斜问题和常用的调优参数。
合并小文件:在执行MR任务前将小文件进行合并,大量的小文件会产生大量的MapTask,增大MapTask装载次数,而Task的装载比较耗时,从而导致MR运行较慢。
采用 CombineTextInputFormat来作为输入,解决输入端大量小文件场景。
减少溢写(Spill)次数:通过调整mapreduce.task.io.sort.mb及mapreduce.map.sort.spill.percent参数值,增大触发Spill的内存上限,减少Spill次数,从而减少磁盘IO。
减少合并(Merge)次数:通过调整mapreduce.task.io.sort.factor参数,增大Merge的文件数目,减少Merge的次数,从而缩短MR处理时间。
在Map之后,不影响业务逻辑前提下,先进行Combime处理,减少 IO。
合理设置Map和Reduce数: 两个都不能设置太少,也不能设置太多。太少,会导致Task等待,延长处理时间;太多,会导致Map、Reduce任务间竞争资源,造成处理超时等错误。
设置Map、Reduce共存:调整mapreducejob.reduce.slowstart.completedmaps参数,使Map运行到一定程度后,Reduce也开始运行,减少Reduce的等待时间。
规避使用Reduce: 因为Reduce在用于连接数据集的时候将会产生大量的网络消耗。
合理设置Reduce端的Bufer: 默认情况下,数据达到一个阈值的时候,Buffer中的数据就会写入磁盘,然后Reduce会从磁盘中获得所有的数据。也就是说,Buffer和Reduce是没有直接关联的,中间多次写磁盘->读磁盘的过程,既然有这个弊端,那么就可以通过参数来配置,使得Buffer中的一部分数据可以直接输送到Reduce,从而减少IO开销: mapreduce.reduce.input.buffer.percent,默认为0.0。当值大于0的时候,会保留指定比例的内存读Buffer中的数据直接拿给Reduce使用。这样一来,设置Buffer需要内存,读取数据需要内存,Reduce计算也要内存,所以要根据作业的运行情况进行调整。
采用数据压缩的方式:减少网络IO的的时间。安装Sappy和LZO压缩编码器。
使用SequenceFile二进制文件。
数据倾斜问题
数据倾斜现象:
数据频率倾斜-某一个区域的数据量要远远大于其他区域;
数据大小倾斜--部分记录的大小远远大于平均值。
减少数据倾斜的方法
抽样和范围分区:可以通过对原始数据进行抽样得到的结果集来预设分区边界值。
自定义分区:基于输出键的背景知识进行自定义分区。例如,如果Map输出键的单词来源于一本书。且其中某几个专业词汇较多。那么就可以自定义分区将这这些专业词汇发送给固定的一部分Reduce实例。而将其他的都发送给剩余的Reduce实例。
Combiner:使用Combiner可以大量地减小数据倾斜。在可能的情况下,Combimner的目的就是聚合并精简数据。
采用Map Join,尽量避免Reduce Join。
1)资源相关参数
(1)以下参数是在用户自己的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 |
每个Reduce去Map中取数据的并行数。默认值是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 |
(2)应该在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 |
(3)Shuffle性能优化的关键参数,应在YARN启动之前就配置好(mapred-default.xml)
配置参数 |
参数说明 |
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.”。 |
HDFS上每个文件都要在NameNode上创建对应的元数据,这个元数据的大小约为150byte,这样当小文件比较多的时候,就会产生很多的元数据文件,一方面会大量占用NameNode的内存空间,另一方面就是元数据文件过多,使得寻址索引速度变慢。
小文件过多,在进行MR计算时,会生成过多切片,需要启动过多的MapTask。每个MapTask处理的数据量小,导致MapTask的处理时间比启动时间还小,白白消耗资源。
1)小文件优化的方向:
(1)在数据采集的时候,就将小文件或小批数据合成大文件再上传HDFS。
(2)在业务处理之前,在HDFS上使用MapReduce程序对小文件进行合并。
(3)在MapReduce处理时,可采用CombineTextInputFormat提高效率。
(4)开启uber模式,实现jvm重用
2)Hadoop Archive
是一个高效的将小文件放入HDFS块中的文件存档工具,能够将多个小文件打包成一个HAR文件,从而达到减少NameNode的内存使用
3)CombineTextInputFormat
CombineTextInputFormat用于将多个小文件在切片过程中生成一个单独的切片或者少量的切片。
4)开启uber模式,实现JVM重用。
默认情况下,每个Task任务都需要启动一个JVM来运行,如果Task任务计算的数据量很小,我们可以让同一个Job的多个Task运行在一个JVM中,不必为每个Task都开启一个JVM。
开启uber模式,在mapred-site.xml中添加如下配置:
mapreduce.job.ubertask.enable
true
mapreduce.job.ubertask.maxmaps
9
mapreduce.job.ubertask.maxreduces
1
mapreduce.job.ubertask.maxbytes
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.txtroot@hadoop104:/user/atguigu #是过本地主机中转实现两个远程主机的文件复制;如果在两个远程主机之间ssh没有配置的情况下可以使用该方式。
采用distcp命令实现两个Hadoop集群之间的递归数据复制
hadoop distcp [在集群1中的文件路径] [在集群2中的文件路径]
[atguigu@hadoop102 hadoop-3.1.3]$
hadoop distcp hdfs://hadoop102:8020/user/atguigu/hello.txt hdfs://hadoop105:8020/user/atguigu/hello.txt
1)案例实操
(1)需要启动YARN进程
[atguigu@hadoop102 hadoop-3.1.3]$ start-yarn.sh
(2)归档文件
把/user/atguigu/input目录里面的所有文件归档成一个叫input.har的归档文件,并把归档后文件存储到/user/atguigu/output路径下。
[atguigu@hadoop102 hadoop-3.1.3]$ hadoop archive -archiveName input.har-p /user/atguigu/input /user/atguigu/output
(3)查看归档
[atguigu@hadoop102 hadoop-3.1.3]$ hadoop fs -ls har:///user/atguigu/output/input.har
(4)解归档文件
[atguigu@hadoop102 hadoop-3.1.3]$ hadoop fs -cp har:/// user/atguigu/output/input.har/* /user/atguigu
开启回收站功能,可以将删除的文件在不超时的情况下,恢复原数据,起到防止误删除、备份等作用。
1)回收站参数设置及工作机制
2)启用回收站
修改core-site.xml,配置垃圾回收时间为1分钟。
fs.trash.interval
1
3)查看回收站
回收站目录在hdfs集群中的路径:/user/atguigu/.Trash/….
4)通过程序删除的文件不会经过回收站,需要调用moveToTrash()才进入回收站
Configuration conf = new Configuration();
//设置HDFS的地址
conf.set("fs.defaultFS","hdfs://hadoop102:8020");
//因为本地的客户端拿不到集群的配置信息 所以需要自己手动设置一下回收站
conf.set("fs.trash.interval","1");
conf.set("fs.trash.checkpoint.interval","1");
//创建一个回收站对象
Trash trash = new Trash(conf);
//将HDFS上的/input/wc.txt移动到回收站
trash.moveToTrash(new Path("/input/wc.txt"));
5)通过网页上直接删除的文件也不会走回收站。
6)只有在命令行利用hadoop fs -rm命令删除的文件才会走回收站。
[atguigu@hadoop102 hadoop-3.1.3]$ hadoop fs -rm -r /user/atguigu/input
7)恢复回收站数据
[atguigu@hadoop102 hadoop-3.1.3]$ hadoop fs -mv /user/atguigu/.Trash/Current/user/atguigu/input /user/atguigu/input