问题现象

问题描述

  公司业务程序需求每30分钟mv 一万多个文件,如果三十分钟之内当前的文件内容没有全部移动,程序报错并且停止。

分析

  通过分析,发现在启动balancer和不启动balancer的情况下,namenode的处理能力差别巨大。不启动balancer,一万多个文件不到20秒全部移动成功,启动balancer的情况下,如果当前需要平衡的数据量大,
30分钟根本不能全部移动,这时候程序就报错了。如果在启动balancer的情况下,这时候程序正在执行mv操作(已经执行了一段时间,但不到三十分钟),关掉balancer,mv操作基本在两三秒以后就完成。

优化

RPC队列拆分(开启SERVER RPC)

在默认情况下,service RPC端口是没有使用的,client和DataNode汇报,zkfc的健康检查都会公用RPC Server,当client的请求量比较大或者DataNode的汇报量很大,会导致他们之间相互影响,导致访问非常缓慢,开启之后,DN的汇报和健康检查请求都会走Service RPC端口,避免了因为client的大量访问影响,影响服务之间的请求,在HA集群中,可以在hdfs-site.xml中设置。

<property>
<name>dfs.namenode.servicerpc-address.mycluster.nn1</name>
<value>mynamenode1.example.com:</value>
</property> <property>
<name>dfs.namenode.servicerpc-address.mycluster.nn2</name>
<value>mynamenode2.example.com:</value>
</property>

开启之后,需要重新格式化ZKFC

hadoop-daemon.sh stop zkfc
hdfs zkfc –formatZK
需要重启集群,当然可以分开启动某些节点进程

注意:该功能对于生产环境,自行评估严重性。最好是两个namenode分开启动,防止namenode不可用。

HDFS审计日志

1、开启审计日志

HDFS审计日志是一个和进程分离的日志文件,默认是没有开启的,开启之后,用户的每个请求都会记录到审计日志当中,通过审计日志可以发现哪些ip,哪些用户对哪些目录做了哪些操作,比如:那些数据在哪些在什么时候删除,和分析哪些Job在密集的对NameNode进行访问。

修改hadoop-env.sh文件

-Dhdfs.audit.logger=${HDFS_AUDIT_LOGGER:-INFO,NullAppender}

修改为

-Dhdfs.audit.logger=${HDFS_AUDIT_LOGGER:-INFO,RFAAUDIT}

对应的log4j.properties可以新增保存个数以及配置日志文件的位置

#
# hdfs audit logging
#
hdfs.audit.logger=INFO,NullAppender
hdfs.audit.log.maxfilesize=2560MB //默认是256m
hdfs.audit.log.maxbackupindex=30        //默认是20
log4j.logger.org.apache.hadoop.hdfs.server.namenode.FSNamesystem.audit=${hdfs.audit.logger}
log4j.additivity.org.apache.hadoop.hdfs.server.namenode.FSNamesystem.audit=false
log4j.appender.RFAAUDIT=org.apache.log4j.RollingFileAppender
log4j.appender.RFAAUDIT.File=/data1/hadoop/hadoop/logs/hdfs-audit.log     //默认是${hadoop.log.dir}/hdfs-audit.log
log4j.appender.RFAAUDIT.layout=org.apache.log4j.PatternLayout
log4j.appender.RFAAUDIT.layout.ConversionPattern=[%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}] [%p] %c{}.%M(%F %L) [%t] : %m%n
log4j.appender.RFAAUDIT.MaxFileSize=${hdfs.audit.log.maxfilesize}
log4j.appender.RFAAUDIT.MaxBackupIndex=${hdfs.audit.log.maxbackupindex}

2、开启异步审计日志

使用异步的log4j appender可以提升NameNode的性能,尤其是请求量在10000 requests/second,可以设置hdfs-site.xml

<property>
<name>dfs.namenode.audit.log.async</name>
<value>true</value>
</property>

<property>

<name>dfs.namenode.edits.asynclogging</name>

<value>true</value>

</property>

3、关闭多余的日志

有时候,NameNode上日志打印会严重影响NN的性能,出问题时也会造成没必要的干扰,所以可以修改log4j的文件,对没必要的日志进行日志级别的调整,例如

log4j.logger.BlockStateChange=WARN
log4j.logger.org.apache.hadoop.ipc.Server=WARN

RPC FairCallQueue(公平调度策略)

这个是基于上面第一点开启Service RPC继续说的,这是较新版本的Hadoop的新特性,RPC FairCallQueue替换了之前的单一的RPC queue的模式,RPC Server会维护并按照请求的用户进行分组,Handler会按照队列的优先级去消费queue里面的RPC Call,这个功能它可以防止因为某个用户的cleint的大量请求导致NN无法响应,整个集群瘫痪的状态,开启了之后,请求多的用户请求会被降级,这样不会造成多租户下,影响他用户的访问。

如需开启,修改core.-site.xml

<property>
<name>ipc..callqueue.impl</name>
<value>org.apache.hadoop.ipc.FairCallQueue</value>
</property>
<property>
<name>ipc..faircallqueue.decay-scheduler.period-ms</name>
<value></value>
</property>
<property>
  <name>ipc..backoff.enable</name> //开启rpc 客户端 拥塞控制
  <value>true</value>
</property>
ipc..scheduler.priority.levels //队列优先级,默认是4,基于提交用户来区分,目前就hadoop一个用户,所以不需要调整该参数,客户端用户数越多的情况,效果越明显
ipc.8020.scheduler.impl //默认DefaultRpcScheduler,这里只是记录一下,该参数配置以后,启动namenode提示找不到改类,这里仅仅记录一下。

注意:不能对Datanode 和NameNode的端口开启。

避免读取stale DataNodes(也就是坏数据)

修改hdfs-site.xml

dfs.namenode.avoid.read.stale.datanode=true
dfs.namenode.avoid.write.stale.datanode=true

开启short circuit reads(短路读取)

开启短路读之后,当client读取数据时,如果在改节点,会直接通过文件描述符去读取文件,而不用通过tcp socket的方式(也就是绕过了datanode,不从datanode去读取数据)

修改hdfs-site.xml

dfs.client.read.shortcircuit=true
dfs.domain.socket.path=/var/lib/hadoop-hdfs/dn_socket //该路径是存放数据块的目录

设置系统CPU为performance

设置cpu的scaling governors为performance模式,你可以运行cpufreq-set -r -g performance或者修改/sys/devices/system/cpu/cpu*/cpufreq/scaling_governor文件,并设置为performance

关闭操作系统的Transparent Huge Pages (THP)

#cat /sys/kernel/mm/transparent_hugepage/defrag    //查看透明缓存页
[always] madvise never                  //默认是开启的 # echo "never" > /sys/kernel/mm/transparent_hugepage/defrag //关闭透明缓存页,注意,该方式重启以后失效,如果需要永久有效,可以把命令添加到/etc/rc.local文件里面

设置系统能使用交换分区的值

在大多数系统中,该值默认为60,该值越高,说明把内存数据交换到交换分区越积极,这对大数据集群来说,会影响稳定性和可用性。范围0-100

#sysctl -w vm.swappiness = 10    //不要设置为0

配置balancer 获取信息节点

将hdfs balancer获取存储信息的请求发送到standby namenode以及忽略小的数据块

修改hdfs-site.xml文件

<property>

    <name>dfs.namenode.balancer.request.standby</name>     //这个值在hadoop2.9.2版本与hadoop3.2版本的默认配置文件中未找到,设置以后,发现集群的balancer依然获取的是active节点,这里仅仅记录一下

    <value>true</value>

  </property>

  <property>

    <name>dfs.balancer.getBlocks.min-block-size</name>

    <value></value>

  </property>

调整namenode handler

修改hdfs-site.xml文件

<property>
<name>dfs.namenode.handler.count</name> //如果没有配置service rpc ,那么该参数配置的值处理所有的call
<value></value>                //该参数的建议值:集群的自然对数 * 20 例如:python -c "import math;print(math.log(70) *20)",70为集群大小
</property>

<property>
  <name>dfs.namenode.service.handler.count</name>    //在开启service rpc的情况配置改参数,用于处理datanode 上报数据块和心跳的线程数量。
  <value>50</value>
</property>

修改jvm GC 的年轻代

当前系统heap大小为15G,整个集群维护了8千万左右的文件、目录和块的信息,集群使用堆内存已经达到了10G左右,在查看集群的时候,发现一分钟进行好几次的的年轻代GC,二年轻代只有仅仅的几百兆。

调整策略,年轻代的内存容量最好是整个堆文件的1/3或者1/4

修改hadoop-env.sh文件,修改 -Xmn为3g

export HADOOP_NAMENODE_OPTS="-Dhadoop.security.logger=${HADOOP_SECURITY_LOGGER:-INFO,RFAS} -Dhdfs.audit.logger=${HDFS_AUDIT_LOGGER:-INFO,RFAAUDIT} -Xmn3g  -XX:ParallelGCThreads=56  -XX:+UseConcMarkSweepGC -XX:ErrorFile=${HADOOP_HOME}/logs/gc_err.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:${HADOOP_HOME}/logs/gc.log.`date "+%Y-%y-%d"` $HADOOP_NAMENODE_OPTS"

参考文章:

cloudera文档

hortonworks社区

http://hackershell.cn/?p=1382

https://www.cnblogs.com/moonypog/p/11008161.html

http://www.inter12.org/archives/1304

namenode 优化 mv慢的问题的更多相关文章

  1. Hadoop记录-NameNode优化

    1.NameNode启动过程 加载FSImage: 回放EditLog: 执行CheckPoint(非必须步骤,结合实际情况和参数确定,后续详述): 收集所有DataNode的注册和数据块汇报. 采用 ...

  2. Linux 运维工作中的经典应用ansible(批量管理)Docker容器技术(环境的快速搭建)

    一 Ansible自动化运维工具 Python 在运维工作中的经典应用 ansible(批量管理操作) .安装ansible(需要bese epel 2种源) wget -O /etc/yum.rep ...

  3. 杭州蓝松科技---短视频SDK介绍

    蓝松短视频的口号和 更新周期: 我们的口号是:  蓝松短视频  任意个性化. 我们是杭州蓝松科技,  专业做视频短视频SDK的技术团队. 我们提供 Android/IOS平台上的 短视频编辑SDK,  ...

  4. NameNode内存优化---基于缓存相同文件名的方法

    NameNode内存优化---重用相同的文件名      原创文章,转载请注明:博客园aprogramer 原文链接:NameNode内存优化---重用相同的文件名      众所周知,Hadoop集 ...

  5. HDFS NameNode重启优化

    http://tech.meituan.com/namenode-restart-optimization.html 一.背景 在Hadoop集群整个生命周期里,由于调整参数.Patch.升级等多种场 ...

  6. namenode 性能优化 RPC队列拆分

    一.Service RPC port NameNode默认使用8020端口侦听所有的RPC请求(HDP版本),包括客户端数据请求,DataNode心跳和block上报,ZKFC模块监控检查和切换控制. ...

  7. Linux实战教学笔记06:Linux系统基础优化

    第六节 Linux系统基础优化 标签(空格分隔):Linux实战教学笔记-陈思齐 第1章 基础环境 第2章 使用网易163镜像做yum源 默认国外的yum源速度很慢,所以换成国内的. 第一步:先备份 ...

  8. CentOS(5.8/6.7)linux生产环境若干优化实战

    CentOS系统安装之后并不能立即投入生产环境使用,往往需要先经过我们运维人员的优化才行.在此讲解几点关于Linux系统安装后的基础优化操作.注意:本次优化都是基于CentOS(5.8/6.7). 下 ...

  9. Tomcat8安装, 安全配置与性能优化(转)

    一.Tomcat 安装 官网:http://tomcat.apache.org/ Tomcat8官网下载地址:http://tomcat.apache.org/download-80.cgi 为了便于 ...

随机推荐

  1. RabbitMQ实战-死信队列

    RabbitMQ死信队列 场景说明 代码实现 简单的Util 生产者 消费者 场景说明 场景: 当队列的消息未正常被消费时,如何解决? 消息被拒绝并且不再重新投递 消息超过有效期 队列超载 方案: 未 ...

  2. error LNK2005: “找到一个或多个多重定义的符号” 已经在 xxxx.obj 中定义 的解决方法

    1 问题还原 这里我有三个源文件:Base.hpp, Base.cpp 和 main.cpp 在Base.hpp里面定义一个基类,注意,基类只包含构造函数和析构函数的声明,函数在Base.cpp里实现 ...

  3. linux对象系统---kobject, ktype, kset, subsys

    本文转自:linux中kobject/ktype/kset/subsys之间的关系 随着内核版本的发展,会有一些变化,无论怎样,变化的是形式,不变的是思想! 那么他们之间具有什么关系?那应该不是'小3 ...

  4. 代替for-in 遍历对象

    object.keys() object.getOwnPropertyName()

  5. 1、[python] PyMouse、PyKeyboard用python操作鼠标和键盘

    [python] PyMouse.PyKeyboard用python操作鼠标和键盘 1.PyUserInput 简介 PyUserInput是一个使用python的跨平台的操作鼠标和键盘的模块,非常方 ...

  6. World发布博客测试

    姓名 地址 博客 www.bk.com  插入一个单元格并放入代码 using System; using System.Collections.Generic; using System.Linq; ...

  7. VLAN实验2:配置Trunk接口

    实验环境公司规模较大200多个员工.内部网络是一个较大的局域网,有两台交换机S1和S2来负责员工网络的接入,接入交换机之间通过汇聚交换机S3相连.公司通过划分VLAN来隔离广播域,由于员工较多,同部门 ...

  8. props、state、forms

    {}用来内嵌任何JS表达式JSX属性JS核心分为三大块:Es6.DOM.WindowBABEL编译器:可以在线编译html语法生成对应的react语法 **自定义组件第一个字母大写:用于区别普通的对象 ...

  9. 公用表表达式(CTE) with as

    在编写T-SQL代码时,往往需要临时存储某些结果集.前面我们已经广泛使用和介绍了两种临时存储结果集的方法:临时表和表变量.除此之外,还可以使用公用表表达式的方法.公用表表达式(Common Table ...

  10. spring常用的事务传播属性说明

    事务Transaction,就是一组操作数据库的动作集合.事务是现代数据库理论中的核心概念之一.如果一组处理步骤或者全部发生或者一步也不执行,我们称该组处理步骤为一个事务.当所有的步骤像一个操作一样被 ...