• 优化技巧汇总_通用优化+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 会话超时时间默认是不一样的!

  • 相关阅读:
    elasticsearch api
    kaili camera
    mysql create db utf8 character
    npm run-script
    d-link kvm 关闭声音
    setInterval js
    jpa datasource config
    mvn添加本地jar
    Sublime Text 2 中文包
    初遇ping++
  • 原文地址:https://www.cnblogs.com/huanghanyu/p/12994709.html
Copyright © 2020-2023  润新知