HDFS核心参数
NameNode,DataNode内存配置
-
查看NameNode,DataNode占用内存
1jps 2jmap -heap 2611 3jmap -heap 2744 -
经验
1# NameNode最小值1G,每增加100w个block,增加1G内存 2# DataNode最小值4G,副本总数超过400w时,每增加100w,增加1G内存 -
具体修改:
hadoop-env.sh1export HDFS_NAMENODE_OPTS="-Dhadoop.security.logger=INFO,RFAS -Xmx1024m" 2export HDFS_DATANODE_OPTS="-Dhadoop.security.logger=ERROR,RFAS -Xmx1024m"
NameNode准备多少线程合适
-
经验:20*log(Cluster Size)
-
具体修改:
hdfs-site.xml1<!-- 默认值为10,如果集群有3台机器,根据公式20*log(3)=21 --> 2<property> 3 <name>dfs.namenode.handler.count</name> 4 <value>21</value> 5</property>
开启回收站配置(防止误删)
-
具体修改:
core-site.xml1<!-- 默认值为0,表示禁用回收站,设置为1表示垃圾回收时间为1分钟 --> 2<property> 3 <name>fs.trash.interval</name> 4 <value>1</value> 5</property> -
注意事项
1# 网页上直接删除的文件不会走回收站 2# 通过java代码,如果没调用moveToTrash(),也不会走回收站 3# 只有通过hadoop fs -rm命令删除的文件才会走回收站 4# 回收站目录:/user/lixuan/.Trash/...
HDFS多目录
NameNode多目录配置
-
NameNode的本地目录可以配置多个,而且每个目录存放的内容
相同,增加了可靠性 -
具体配置:
hdfs-site.xml1<property> 2 <name>dfs.namenode.name.dir</name> <value>file://${hadoop.tmp.dir}/dfs/name1,file://${hadoop.tmp.dir}/dfs/name2</value> 3</property>
DataNode多目录
-
DataNode可以配置成多个目录,每个目录存储的数据
不一样(不是副本) -
具体配置:
hdfs-site.xml1<property> 2 <name>dfs.datanode.data.dir</name> <value>file://${hadoop.tmp.dir}/dfs/data1,file://${hadoop.tmp.dir}/dfs/data2</value> 3</property>
数据均衡
磁盘间数据均衡
-
生成均衡计划(只有一块磁盘时不会生成计划)
1hdfs diskbalancer -plan node01 -
执行均衡计划
1hdfs diskbalancer -execute node01.plan.json -
查看计划执行情况
1hdfs diskbalancer -query node01 -
取消均衡任务
1hdfs diskbalancer -cancel node01.plan.json
服务器间数据均衡
-
开启数据均衡(集群中各节点的磁盘利用率相差不超过10%)
1sbin/start-balancer.sh -threshold 10 -
停止数据均衡
1sbin/stop-balancer.sh -
注意:找一台比较闲的机器执行start-banacer,不要再NameNode上执行
集群扩容和减配
添加白名单
-
在NameNode节点下的
/opt/module/hadoop-3.1.3/etc/hadoop目录下分别创建whitelist文件和blacklist文件 -
在whitelist中添加集群的主机名,blacklist保存为空
-
修改配置文件:
hdfs-site.xml1<!-- 白名单 --> 2<property> 3 <name>dfs.hosts</name> 4 <value>/opt/module/hadoop-3.1.3/etc/hadoop/whitelist</value> 5</property> 6 7<!-- 黑名单 --> 8<property> 9 <name>dfs.hosts.exclude</name> 10 <value>/opt/module/hadoop-3.1.3/etc/hadoop/blacklist</value> 11</property> -
分发配置文件并重启集群
-
向白名单中间增加机器后要刷新NameNode
1hdfs dfsadmin -refreshNodes
服役新服务器
- 从原先的集群中克隆一台机器
- 修改ip地址和主机名
- 删除新机器的Hadoop的data和log数据
- 配置免密登录
- 向白名单中添加新节点
- 分发白名单
- 刷新NameNode
黑名单退役服务器
- 在blacklist中加入要退役的主机名
- 分发黑名单
- 刷新NameNode
- 注意:如果服役的节点数小于副本数,需要修改副本数后才能成功退役
- 如果退役后数据不均衡,需要重新均衡
HDFS异构存储(冷热数据分离)
存储策略
| 策略ID | 策略名称 | 副本分布 |
|---|---|---|
| 15 | Lazy_Persist | RAM_DISK:1, DISK:n-1 |
| 12 | ALL_SSD | SSD:n |
| 10 | One_SSD | SSD:1, DISK:n-1 |
| 7 | Hot(default) | DISK:n |
| 5 | Warm | DISK:1, ARCHIVE:n-1 |
| 2 | Cold | ARCHIVE:n |
异构存储Shell操作
-
查看当前有哪些存储策略可以用
1hdfs storagepolicies -listPolicies -
为指定路径设置指定的存储策略
1hdfs storagepolicies -setStoragePolicy -path xxx -policy xxx -
获取指定路径的存储策略
1hdfs storagepolicies -getStoragePolicy -path xxx -
取消存储策略
1hdfs storagepolicies -unsetStoragePolicy -path xxx -
查看文件块的分布
1bin/hdfs fsck xxx -files -blocks -locations -
查看集群节点
1hadoop dfsadmin -report
HDFS故障处理
NameNode故障处理
- 将SecondaryNameNode中的数据拷贝到原NameNode存储数据目录
- 重启NameNode
慢磁盘监控
-
通过心跳未联系时间,超过3秒说明有异常
-
通过fio命令,测试磁盘读写性能
1sudo yum install -y fio 2 3# 顺序读测试 4sudo fio -filename=/home/atguigu/test.log -direct=1 -iodepth 1 -thread -rw=read -ioengine=psync -bs=16k -size=2G -numjobs=10 -runtime=60 -group_reporting -name=test_r 5 6# 顺序写测试 7sudo fio -filename=/home/atguigu/test.log -direct=1 -iodepth 1 -thread -rw=write -ioengine=psync -bs=16k -size=2G -numjobs=10 -runtime=60 -group_reporting -name=test_w 8 9# 随机写测试 10sudo fio -filename=/home/atguigu/test.log -direct=1 -iodepth 1 -thread -rw=randwrite -ioengine=psync -bs=16k -size=2G -numjobs=10 -runtime=60 -group_reporting -name=test_randw 11 12# 混合随机读写 13sudo fio -filename=/home/atguigu/test.log -direct=1 -iodepth 1 -thread -rw=randrw -rwmixread=70 -ioengine=psync -bs=16k -size=2G -numjobs=10 -runtime=60 -group_reporting -name=test_r_w -ioscheduler=noop
小文件归档
1# 启动yarn进程 2 3# 把/input目录里面的所有文件归档成一个叫input.har的归档文件,并把归档后文件存储到/output路径下 4hadoop archive -archiveName input.har -p /input /output 5 6# 查看归档 7hadoop fs -ls har:///output/input.har 8 9# 解归档文件 10hadoop fs -cp har:///output/input.har/* /
MapReduce经验
MapReduce跑的慢的原因
- 计算机性能
- 数据倾斜
- Map和Reduce数设置不合理
- Map运行时间太长,导致Reduce等待过久
- 小文件过多
- 大量的不可切片的超大压缩文件
- Spill次数过多
- Merge次数过多
MapReduce优化方法
数据输入
- 合并小文件
- 采用CombineTextInputFormat来作为输出
Map阶段
- 减少溢写(Spill)次数
- 通过调整
mapreduce.task.io.sort.mb及mapreduce.map.sort.percent参数值,增大触发Spill的内存上限,减少Spill次数,从而减少磁盘IO
- 通过调整
- 减少合并(Merge)次数
- 通过调整
mapreduce.task.io.sort.factor参数,增大Merge的文件数目,减少Merge的次数
- 通过调整
- 在Map之后,不影响业务逻辑的前提下,先进行Combine处理
Reduce阶段
- 合理设Map和Reduce数
- 设置Map、Reduce共存
- 调整
mapreduce.job.reduce.slowstart.completedmaps参数 - 使Map运行到一定程度后,Reduce也开始运行,减少Reduce的等待时间
- 调整
- 规避使用Reduce
- Reduce在用于连接数据集的时候会产生大量分网络消耗
- 合理设置Reduce端的Buffer
- 默认情况下,数据达到一个阈值的时候,Buffer中的数据就会写入磁盘,然后Reduce会从磁盘中获得所有数据,消耗了IO
mapreduce.reduce.input.buffer.percent默认为0,设置大于0的值,会保存指定比例的内存将数据直接从Buffer中拿给Reduce使用
IO传输
- 采用数据压缩的方式,snappy、LZO
数据倾斜问题
-
过滤空值
-
抽样个范围分区
-
自定义分区
-
Combiner
-
采用Map Join,尽量避免Reduce Join
小文件优化
-
数据采集的时候,将小文件合成大文件再上传HDFS
-
将多个小文件打包成Har文件,从而减少NameNode内存的使用
-
使用
CombineTextInputFormat再切片中将小文件转化为更少的切片 -
开启uber模式,实现JVM重用
mapred-site.xml1<!-- 开启uber模式,默认关闭 --> 2<property> 3 <name>mapreduce.job.ubertask.enable</name> 4 <value>true</value> 5</property> 6 7<!-- uber模式中最大的mapTask数量,可向下修改 --> 8<property> 9 <name>mapreduce.job.ubertask.maxmaps</name> 10 <value>9</value> 11</property> 12<!-- uber模式中最大的reduce数量,可向下修改 --> 13<property> 14 <name>mapreduce.job.ubertask.maxreduces</name> 15 <value>1</value> 16</property> 17<!-- uber模式中最大的输入数据量,默认使用dfs.blocksize 的值,可向下修改 --> 18<property> 19 <name>mapreduce.job.ubertask.maxbytes</name> 20 <value></value> 21</property>
Yarn经验
常用调优参数
-
ResourceManager相关
1# ResourceManager处理调度器请求的线程数量 2yarn.resourcemanager.scheduler.client.thread-count 3# 配置调度器 4yarn.resourcemanager.scheduler.class -
NodeManager相关
1# NodeManager使用内存数 2yarn.nodemanager.resource.memory-mb 3# NodeManager为系统保留多少内存,和上一个参数二者取一即可 4yarn.nodemanager.resource.system-reserved-memory-mb 5# NodeManager使用CPU核数 6yarn.nodemanager.resource.cpu-vcores 7# 是否将虚拟核数当作CPU核数 8yarn.nodemanager.resource.count-logical-processors-as-cores 9# 虚拟核数和物理核数乘数,例如:4核8线程,该参数就应设为2 10yarn.nodemanager.resource.pcores-vcores-multiplier 11# 是否让yarn自己检测硬件进行配置 12yarn.nodemanager.resource.detect-hardware-capabilities 13# 是否开启物理内存检查限制container 14yarn.nodemanager.pmem-check-enabled 15# 是否开启虚拟内存检查限制container 16yarn.nodemanager.vmem-check-enabled 17# 虚拟内存物理内存比例 18yarn.nodemanager.vmem-pmem-ratio -
Container相关
1# 容器最小内存 2yarn.scheduler.minimum-allocation-mb 3# 容器最大内存 4yarn.scheduler.maximum-allocation-mb 5# 容器最小核数 6yarn.scheduler.minimum-allocation-vcores 7# 容器最大核数 8yarn.scheduler.maximum-allocation-vcores
容量调度器的使用
1<!-- 指定多队列,增加hive队列 --> 2<property> 3 <name>yarn.scheduler.capacity.root.queues</name> 4 <value>default,hive</value> 5 <description> 6 The queues at the this level (root is the root queue). 7 </description> 8</property> 9 10<!-- 降低default队列资源额定容量为40%,默认100% --> 11<property> 12 <name>yarn.scheduler.capacity.root.default.capacity</name> 13 <value>40</value> 14</property> 15 16<!-- 降低default队列资源最大容量为60%,默认100% --> 17<property> 18 <name>yarn.scheduler.capacity.root.default.maximum-capacity</name> 19 <value>60</value> 20</property>
1<!-- 指定hive队列的资源额定容量 --> 2<property> 3 <name>yarn.scheduler.capacity.root.hive.capacity</name> 4 <value>60</value> 5</property> 6 7<property> 8 <name>yarn.scheduler.capacity.root.hive.user-limit-factor</name> 9 <value>1</value> 10</property> 11 12<!-- 指定hive队列的资源最大容量 --> 13<property> 14 <name>yarn.scheduler.capacity.root.hive.maximum-capacity</name> 15 <value></value> 16</property> 17 18<property> 19 <name>yarn.scheduler.capacity.root.hive.state</name> 20 <value>RUNNING</value> 21</property> 22 23<property> 24 <name>yarn.scheduler.capacity.root.hive.acl_submit_applications</name> 25 <value>*</value> 26</property> 27 28<property> 29 <name>yarn.scheduler.capacity.root.hive.acl_administer_queue</name> 30 <value>*</value> 31</property> 32 33<property> 34 <name>yarn.scheduler.capacity.root.hive.acl_application_max_priority</name> 35 <value>*</value> 36</property> 37 38<property> 39 <name>yarn.scheduler.capacity.root.hive.maximum-application-lifetime</name> 40 <value>-1</value> 41</property> 42 43<property> 44 <name>yarn.scheduler.capacity.root.hive.default-application-lifetime</name> 45 <value>-1</value> 46</property>
1# 配置完成后,刷新队列 2yarn rmadmin -refreshQueues 3 4# 通过API向Hive队列提交任务 5configuration.set("mapreduce.job.queuename","hive");
调优案例
需求
- 从1G数据中,统计每个单词出现次数
- 服务器3台,每台配置4G内存,4核CPU,4线程
需求分析
-
1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster
-
平均每个节点运行10个 / 3台 ≈ 3个任务(4 3 3)
HDFS调优
-
hadoop-env.sh1export HDFS_NAMENODE_OPTS="-Dhadoop.security.logger=INFO,RFAS -Xmx1024m" 2export HDFS_DATANODE_OPTS="-Dhadoop.security.logger=ERROR,RFAS -Xmx1024m" -
hdfs-site.xml1<!-- NameNode有一个工作线程池,默认值是10 --> 2<property> 3 <name>dfs.namenode.handler.count</name> 4 <value>21</value> 5</property> -
core-site.xml1<!-- 配置垃圾回收时间为60分钟 --> 2<property> 3 <name>fs.trash.interval</name> 4 <value>60</value> 5</property>
MapReduce调优Mapred-site.xml
1<!-- 环形缓冲区大小,默认100m --> 2<property> 3 <name>mapreduce.task.io.sort.mb</name> 4 <value>100</value> 5</property> 6 7<!-- 环形缓冲区溢写阈值,默认0.8 --> 8<property> 9 <name>mapreduce.map.sort.spill.percent</name> 10 <value>0.80</value> 11</property> 12 13<!-- merge合并次数,默认10个 --> 14<property> 15 <name>mapreduce.task.io.sort.factor</name> 16 <value>10</value> 17</property> 18 19<!-- maptask内存,默认1g; maptask堆内存大小默认和该值大小一致mapreduce.map.java.opts --> 20<property> 21 <name>mapreduce.map.memory.mb</name> 22 <value>-1</value> 23</property> 24 25<!-- matask的CPU核数,默认1个 --> 26<property> 27 <name>mapreduce.map.cpu.vcores</name> 28 <value>1</value> 29</property> 30 31<!-- matask异常重试次数,默认4次 --> 32<property> 33 <name>mapreduce.map.maxattempts</name> 34 <value>4</value> 35</property> 36 37<!-- 每个Reduce去Map中拉取数据的并行数。默认值是5 --> 38<property> 39 <name>mapreduce.reduce.shuffle.parallelcopies</name> 40 <value>5</value> 41</property> 42 43<!-- Buffer大小占Reduce可用内存的比例,默认值0.7 --> 44<property> 45 <name>mapreduce.reduce.shuffle.input.buffer.percent</name> 46 <value>0.70</value> 47</property> 48 49<!-- Buffer中的数据达到多少比例开始写入磁盘,默认值0.66。 --> 50<property> 51 <name>mapreduce.reduce.shuffle.merge.percent</name> 52 <value>0.66</value> 53</property> 54 55<!-- reducetask内存,默认1g;reducetask堆内存大小默认和该值大小一致mapreduce.reduce.java.opts --> 56<property> 57 <name>mapreduce.reduce.memory.mb</name> 58 <value>-1</value> 59</property> 60 61<!-- reducetask的CPU核数,默认1个 --> 62<property> 63 <name>mapreduce.reduce.cpu.vcores</name> 64 <value>2</value> 65</property> 66 67<!-- reducetask失败重试次数,默认4次 --> 68<property> 69 <name>mapreduce.reduce.maxattempts</name> 70 <value>4</value> 71</property> 72 73<!-- 当MapTask完成的比例达到该值后才会为ReduceTask申请资源。默认是0.05 --> 74<property> 75 <name>mapreduce.job.reduce.slowstart.completedmaps</name> 76 <value>0.05</value> 77</property> 78 79<!-- 如果程序在规定的默认10分钟内没有读到数据,将强制超时退出 --> 80<property> 81 <name>mapreduce.task.timeout</name> 82 <value>600000</value> 83</property>
Yarn调优yarn-site.xml
1<!-- 选择调度器,默认容量 --> 2<property> 3 <name>yarn.resourcemanager.scheduler.class</name> 4 <value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler</value> 5</property> 6 7<!-- ResourceManager处理调度器请求的线程数量,默认50;如果提交的任务数大于50,可以增加该值,但是不能超过3台 * 4线程 = 12线程(去除其他应用程序实际不能超过8) --> 8<property> 9 <name>yarn.resourcemanager.scheduler.client.thread-count</name> 10 <value>8</value> 11</property> 12 13<!-- 是否让yarn自动检测硬件进行配置,默认是false,如果该节点有很多其他应用程序,建议手动配置。如果该节点没有其他应用程序,可以采用自动 --> 14<property> 15 <name>yarn.nodemanager.resource.detect-hardware-capabilities</name> 16 <value>false</value> 17</property> 18 19<!-- 是否将虚拟核数当作CPU核数,默认是false,采用物理CPU核数 --> 20<property> 21 <name>yarn.nodemanager.resource.count-logical-processors-as-cores</name> 22 <value>false</value> 23</property> 24 25<!-- 虚拟核数和物理核数乘数,默认是1.0 --> 26<property> 27 <name>yarn.nodemanager.resource.pcores-vcores-multiplier</name> 28 <value>1.0</value> 29</property> 30 31<!-- NodeManager使用内存数,默认8G,修改为4G内存 --> 32<property> 33 <name>yarn.nodemanager.resource.memory-mb</name> 34 <value>4096</value> 35</property> 36 37<!-- nodemanager的CPU核数,不按照硬件环境自动设定时默认是8个,修改为4个 --> 38<property> 39 <name>yarn.nodemanager.resource.cpu-vcores</name> 40 <value>4</value> 41</property> 42 43<!-- 容器最小内存,默认1G --> 44<property> 45 <name>yarn.scheduler.minimum-allocation-mb</name> 46 <value>1024</value> 47</property> 48 49<!-- 容器最大内存,默认8G,修改为2G --> 50<property> 51 <name>yarn.scheduler.maximum-allocation-mb</name> 52 <value>2048</value> 53</property> 54 55<!-- 容器最小CPU核数,默认1个 --> 56<property> 57 <name>yarn.scheduler.minimum-allocation-vcores</name> 58 <value>1</value> 59</property> 60 61<!-- 容器最大CPU核数,默认4个,修改为2个 --> 62<property> 63 <name>yarn.scheduler.maximum-allocation-vcores</name> 64 <value>2</value> 65</property> 66 67<!-- 虚拟内存检查,默认打开,修改为关闭 --> 68<property> 69 <description>Whether virtual memory limits will be enforced for 70 containers.</description> 71 <name>yarn.nodemanager.vmem-check-enabled</name> 72 <value>false</value> 73</property> 74 75<!-- 虚拟内存和物理内存设置比例,默认2.1 --> 76<property> 77 <name>yarn.nodemanager.vmem-pmem-ratio</name> 78 <value>2.1</value> 79</property>
