优化技巧汇总_通用优化+Linux 优化+HDFS 优化+MapReduce 优化+HBase 优化+内存优化+JVM 优化+Zookeeper 优化

Posted huanghanyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了优化技巧汇总_通用优化+Linux 优化+HDFS 优化+MapReduce 优化+HBase 优化+内存优化+JVM 优化+Zookeeper 优化相关的知识,希望对你有一定的参考价值。


一、通用优化

1.1、NameNode 的元数据备份使用 SSD

1.2、定时备份 NameNode 上的元数据

  建议每小时或者每天备份,如果数据极其重要,可以5~10分钟备份一次。备份可以通过定时任务复制元数据目录即可。

1.3、为 NameNode 指定多个元数据目录

  使用 dfs.name.dir 或者 dfs.namenode.name.dir 指定。一个指定本地磁盘,一个指定网络磁盘。这样可以提供元数据的冗余和健壮性,以免发生故障。

1.4、设置 dfs.namenode.name.dir.restore 为 true

  即允许尝试恢复之前失败的 dfs.namenode.name.dir 目录,在创建 checkpoint 时做此尝试,如果设置了多个磁盘,建议允许。

1.5、NameNode 节点必须配置为 Raid1(镜像盘)结构

1.6、补充:什么是Raid0、Raid0+1、Raid1、Raid5

技术图片

  Standalone:最普遍的单磁盘储存方式。

  Cluster:集群储存是通过将数据分布到集群中各节点的存储方式,提供单一的使用接口与界面,使用户可以方便地对所有数据进行统一使用与管理。

  Hot swap:用户可以再不关闭系统,不切断电源的情况下取出和更换硬盘,提高系统的恢复能力、拓展性和灵活性。

  Raid0:是所有 raid 中存储性能最强的阵列形式。其工作原理就是在多个磁盘上分散存取连续的数据,这样,当需要存取数据是多个磁盘可以并排执行,每个磁盘执行属于它自己的那部分数据请求,显著提高磁盘整体存取性能。但是不具备容错能力,适用于低成本、低可靠性的台式系统。

  Raid1:又称镜像盘,把一个磁盘的数据镜像到另一个磁盘上,采用镜像容错来提高可靠性,具有 raid 中最高的数据冗余能力。存数据时会将数据同时写入镜像盘内,读取数据则只从工作盘读出。发生故障时,系统将从镜像盘读取数据,然后再恢复工作盘正确数据。这种阵列方式可靠性极高,但是其容量会减去一半。广泛用于数据要求极严的应用场合,如商业金融、档案管理等领域。只允许一个硬盘出故障。

  Raid0+1:将 Raid0 和 Raid1 技术结合在一起,兼顾两者的优势。在数据得到保障的同时,还能提供较强的存储性能。不过至少要求4个或以上的硬盘,但也只允许一个磁盘出错。是一种三高技术

  Raid5:Raid5 可以看成是 Raid0+1 的低成本方案。采用循环偶校验独立存取的阵列方式。将数据和相对应的奇偶校验信息分布存储到组成 Raid5 的各个磁盘上。当其中一个磁盘数据发生损坏后,利用剩下的磁盘和相应的奇偶校验信息重新恢复/生成丢失的数据而不影响数据的可用性。至少需要3个或以上的硬盘。适用于大数据量的操作。成本稍高、储存新强、可靠性强的阵列方式。

Raid还有其他方式,请自行查阅。

1.7、保持 NameNode 日志目录有足够的空间,这些日志有助于帮助你发现问题

1.8、因为 Hadoop 是 IO 密集型框架,所以尽量提升存储的速度和吞吐量(类似位宽)

二、Linux 优化

2.1、开启文件系统的预读缓存可以提高读取速度

$ sudo blockdev --setra 32768 /dev/sda

(尖叫提示:ra 是 readahead 的缩写)

2.2、关闭进程睡眠池

$ sudo sysctl -w vm.swappiness=0

2.3 修改系统能够打开的文件句柄数

  即调整 ulimit 上限,默认值为比较小的数字(CentOS 6.8 默认是 1024)。做高并发服务器或者像聊天这种长连接服务时,需要修改系统能够打开的文件句柄数。否则会出现 too many open files 的错误。socket 句柄和文件句柄是相同的,像聊天这种长链接服务,此时 too many open files 指的就是 socket 句柄数超出了系统的限制。

$ ulimit -n     查看允许最大进程数
$ ulimit -u     查看进程允许打开最大文件数

单进程文件句柄限制
  句柄数限制又分为系统总限制单进程限制。使用命令 ulimit -n 可以看到系统对于单个进程的限制,即 open files。执行命令 ulimit -a 如下:

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 7334
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1024
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

  如果 open files 1024 表示我当前登录的用户(atguigu),每个进程可以打开 1024 个句柄,当然总和不能超过 file-max 限制。
  如果 open files 65535 表示我当前登录的用户(root),每个进程可以打开 65535 个句柄,当然总和不能超过 file-max 限制。

  修改 open files 的值,有两种方法,临时的和永久的。
临时修改 open files

ulimit -HSn 1000    将 open-files 修改为 1000,退出当前 shell 后即失效。H 和 S 选项表示硬限制和软限制,下面有解释,省略的话表示同时修改。

永久修改 open files
若希望永久生效的话就得修改配置文件,/etc/security/limits.conf,修改后需要重启系统,该文件内容为:

$ sudo vim /etc/security/limits.conf    修改单个进程打开文件数限制
在末尾添加以下内容:

*                soft    nofile          1024000
*                hard    nofile          1024000
hive             -       nofile          1024000
hive             -       nproc           1024000 

第一列:表示对哪些用户进程进行限制,* 表示所有用户。
第二列:
  soft:表示软限制,当进程打开的句柄数超过该限制后,只是进行警告。
  hard:表示硬限制,进程最多打开这么多句柄。
第三列:nofile 表示进程能够打开的最大文件数,nproc 表示允许最大进程数(其他配置值可以参考文件中的注释,与 ulimit -a 列出的值一一对应)。
第四列:是具体的值,这个值也是有上限的,这个上限的值设置在 /proc/sys/fs/nr_open,默认值为 1048576,完全够用了。

修改后需要重启系统生效。

nr_open 表示一个进程最多能分配的文件句柄数

cat /proc/sys/fs/nr_open
1048576

系统总打开文件句柄限制
  上面的 open files 是对单个进程的限制,属于线程级别的。系统级的限制在这个文件中 /proc/sys/fs/file-max

cat /proc/sys/fs/file-max
185890

file-max 指定了系统范围内所有进程可以打开的文件句柄限制。
同样,修改上面那个文件也是临时生效的,重启后会失效。如果要永久生效,则要修改这个文件, /etc/sysctl.conf

fs.file-max  = 185890

如果没有这一项,则新加这一项就行。运行 sysctl -p 或重启后才能生效。


lsof -p 进程pid 查看单个进程打开的文件句柄

lsof -p 4512

/proc/sys/fs/file-nr 记录当前系统打开的句柄数

cat /proc/sys/fs/file-nr
2240    0   185890

第一列:表示已打开的句柄数
第二列:表示已分配但是未使用的句柄数
第三列:表示系统总的句柄数,即 file-max

总结
  所有进程能够打开的文件句柄总数不能超过 file-max
  单个进程打开的句柄数不能超过nofile soft limit
  nofile soft limit 的设置不能超过nofile hard limit
  nofile hard limit 的设置不能超过 no_open
  no_open 的设置不能超过 file-max

修改用户打开进程数限制

$ sudo vim /etc/security/limits.d/90-nproc.conf     修改用户打开进程数限制
修改为:

*          soft    nproc     40960
root       soft    nproc     unlimited

修改后需要重启系统生效。

2.4、开启集群的时间同步 NTP,请参看一下链接

  https://www.cnblogs.com/chenmingjun/p/10545638.html

2.5、更新系统补丁(尖叫提示:更新补丁前,请先测试新版本补丁对集群节点的兼容性)

三、HDFS 优化(hdfs-site.xml)

3.1、保证 RPC 调用会有较多的线程数

属性:dfs.namenode.handler.count**
解释:该属性是 NameNode 服务默认线程数,的默认值是 10,根据机器的可用内存可以调整为 50~100 。

属性:dfs.datanode.handler.count
解释:该属性默认值为 10,是 DataNode 的处理线程数,如果 HDFS 客户端程序读写请求比较多,可以调高到 15~20,设置的值越大,内存消耗越多,不要调整的过高,一般业务中,5~10 即可。

3.2、副本数的调整

属性:dfs.replication
解释:如果数据量巨大,且不是非常之重要,可以调整为 2~3,如果数据非常之重要,可以调整为 3~5。

3.3.、文件块大小的调整

属性:dfs.blocksize
解释:块大小定义,该属性应该根据存储的大量的单个文件大小来设置,如果大量的单个文件都小于 100M,建议设置成 64M 块大小,对于大于 100M 或者达到 GB 的这种情况,建议设置成 256M,一般设置范围波动在 64M~256M 之间。

四、MapReduce 优化(mapred-site.xml)

4.1、Job 任务服务线程数调整

属性:mapreduce.jobtracker.handler.count
解释:该属性是 Job 任务线程数,默认值是 10,根据机器的可用内存可以调整为 50~100。

4.2、Http 服务器工作线程数

属性:mapreduce.tasktracker.http.threads
解释:定义 HTTP 服务器工作线程数,默认值为 40,对于大集群可以调整到 80~100。

4.3、文件排序合并优化

属性:mapreduce.task.io.sort.factor
解释:文件排序时同时合并的数据流的数量,这也定义了同时打开文件的个数,默认值为 10,如果调高该参数,可以明显减少磁盘 IO,即减少文件读取的次数。

4.5、设置任务并发

属性:mapreduce.map.speculative
解释:该属性可以设置任务是否可以并发执行,如果任务多而小,该属性设置为 true 可以明显加快任务执行效率,但是对于延迟非常高的任务,建议改为 false,这就类似于迅雷下载。

4.6、MR 输出数据的压缩

属性:mapreduce.map.output.compress、mapreduce.output.fileoutputformat.compress
解释:对于大集群而言,建议设置 Map-Reduce 的输出为压缩的数据,而对于小集群,则不需要。

4.7、优化 Mapper 和 Reducer 的个数

属性:
  mapreduce.tasktracker.map.tasks.maximum
  mapreduce.tasktracker.reduce.tasks.maximum
解释:
  以上两个属性分别为一个单独的 Job 任务可以同时运行的 Map 和 Reduce 的数量。
设置上面两个参数时,需要考虑 CPU 核数、磁盘和内存容量。假设一个 8 核的 CPU,业务内容非常消耗 CPU,那么可以设置 map 数量为 4,如果该业务不是特别消耗 CPU 类型的,那么可以设置 map 数量为 40,reduce 数量为 20。这些参数的值修改完成之后,一定要观察是否有较长等待的任务,如果有的话,可以减少数量以加快任务执行,如果设置一个很大的值,会引起大量的上下文切换,以及内存与磁盘之间的数据交换,这里没有标准的配置数值,需要根据业务和硬件配置以及经验来做出选择。

  在同一时刻,不要同时运行太多的 MapReduce,这样会消耗过多的内存,任务会执行的非常缓慢,我们需要根据 CPU 核数,内存容量设置一个 MR 任务并发的最大值,使固定数据量的任务完全加载到内存中,避免频繁的内存和磁盘数据交换,从而降低磁盘 IO,提高性能。

  大概配比:

CPU COREMEM(GB)MapReduce
1 1 1 1
1 5 1 1
4 5 1~4 2
16 32 16 8
16 64 16 8
24 64 24 12
24 128 24 12

大概估算公式:
  map = 2 + ?cpu_core
  reduce = 2 + ?cpu_core

五、HBase 优化

5.1、在 HDFS 的文件中追加内容

不是不允许追加内容么?没错,请看背景故事:

技术图片

属性:dfs.support.append
文件:hdfs-site.xml、hbase-site.xml
解释:开启 HDFS 追加同步,可以优秀的配合 HBase 的数据同步和持久化。默认值为 true。

5.2、优化 DataNode 允许的最大文件打开数

属性:dfs.datanode.max.transfer.threads
文件:hdfs-site.xml
解释:HBase 一般都会同一时间操作大量的文件,根据集群的数量和规模以及数据动作,设置为 4096 或者更高。默认值:4096。

5.3、优化延迟高的数据操作的等待时间

属性:dfs.image.transfer.timeout
文件:hdfs-site.xml
解释:如果对于某一次数据操作来讲,延迟非常高,socket 需要等待更长的时间,建议把该值设置为更大的值(默认 60000 毫秒),以确保 socket 不会被 timeout 掉。

5.4、优化数据的写入效率

属性:
  mapreduce.map.output.compress
  mapreduce.map.output.compress.codec
文件:mapred-site.xml
解释:开启这两个数据可以大大提高文件的写入效率,减少写入时间。第一个属性值修改为 true,第二个属性值修改为:org.apache.hadoop.io.compress.GzipCodec。

5.5、优化 DataNode 存储

属性:dfs.datanode.failed.volumes.tolerated
文件:hdfs-site.xml
解释:默认为 0,意思是当 DataNode 中有一个磁盘出现故障,则会认为该 DataNode shutdown 了。如果修改为 1,则一个磁盘出现故障时,数据会被复制到其他正常的 DataNode 上,当前的 DataNode 继续工作。

5.6、设置 RPC 监听数量

属性:hbase.regionserver.handler.count
文件:hbase-site.xml
解释:默认值为 30,用于指定 RPC 监听的数量,可以根据客户端的请求数进行调整,读写请求较多时,增加此值。

5.7、优化 HStore 文件大小

属性:hbase.hregion.max.filesize
文件:hbase-site.xml
解释:默认值 10737418240(10GB),如果需要运行 HBase 的 MR 任务,可以减小此值,因为一个 region 对应一个 map 任务,如果单个 region 过大,会导致 map 任务执行时间过长。该值的意思就是,如果 HFile 的大小达到这个数值,则这个 region 会被切分为两个 Hfile。

5.8、优化 hbase 客户端缓存

属性:hbase.client.write.buffer
文件:hbase-site.xml
解释:用于指定 HBase 客户端缓存,增大该值可以减少 RPC 调用次数,但是会消耗更多内存,反之则反之。一般我们需要设定一定的缓存大小,以达到减少 RPC 次数的目的。

5.9、指定 scan.next 扫描 HBase 所获取的行数

属性:hbase.client.scanner.caching
文件:hbase-site.xml
解释:用于指定 scan.next 方法获取的默认行数,值越大,消耗内存越大。

六、内存优化

  HBase 操作过程中需要大量的内存开销,毕竟 Table 是可以缓存在内存中的,一般会分配整个可用内存的 70% 给 HBase 的 Java 堆。但是不建议分配非常大的堆内存,因为 GC 过程持续太久会导致 RegionServer 处于长期不可用状态,一般 16~48G 内存就可以了,如果因为框架占用内存过高导致系统内存不足,框架一样会被系统服务拖死。

七、JVM 优化

  涉及文件:hbase-env.sh

7.1、并行 GC

参数:-XX:+UseParallelGC
解释:开启并行GC。

7.2、同时处理垃圾回收的线程数

参数:-XX:ParallelGCThreads=cpu_core – 1
解释:该属性设置了同时处理垃圾回收的线程数。

7.3、禁用手动 GC

参数:-XX:DisableExplicitGC
解释:防止开发人员手动调用 GC。

八、Zookeeper 优化

8.1、优化 Zookeeper 会话超时时间

参数:zookeeper.session.timeout
文件:hbase-site.xml
解释:In hbase-site.xml, set zookeeper.session.timeout to 30 seconds or less to bound failure detection (20-30 seconds is a good start) 该值会直接关系到 master 发现服务器宕机的最大周期,默认值为 30 秒,如果该值过小,会在 HBase 在写入大量数据发生而 GC 时,导致 RegionServer 短暂的不可用,从而没有向 ZK 发送心跳包,最终导致认为从节点 shutdown。一般 20 台左右的集群需要配置 5 台 zookeeper。
注意:不同的 HBase 版本,它的 zookeeper 会话超时时间默认是不一样的!

以上是关于优化技巧汇总_通用优化+Linux 优化+HDFS 优化+MapReduce 优化+HBase 优化+内存优化+JVM 优化+Zookeeper 优化的主要内容,如果未能解决你的问题,请参考以下文章

运行Sqoop任务的通用脚本Python2实现(待优化)

运行Sqoop任务的通用模板:Python2脚本实现(待优化)

Java性能优化技巧集锦

SEO优化教程汇总

HDFS优化

大数据技术之_05_Hadoop学习_04_MapReduce_Hadoop企业优化(重中之重)+HDFS小文件优化方法+MapReduce扩展案例+倒排索引案例(多job串联)+TopN案例+找博客