namenode 優化 mv慢的問題


問題現象

問題描述

  公司業務程序需求每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:8021</value>
  </property>

  <property>
    <name>dfs.namenode.servicerpc-address.mycluster.nn2</name>
    <value>mynamenode2.example.com:8021</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{3}.%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.8020.callqueue.impl</name>
    <value>org.apache.hadoop.ipc.FairCallQueue</value>
  </property>
<property>
  <name>ipc.8020.faircallqueue.decay-scheduler.period-ms</name>
  <value>60000</value>
</property>
<property>
  <name>ipc.8020.backoff.enable</name>     //開啟rpc 客戶端 擁塞控制
  <value>true</value>
</property>

 

ipc.8020.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>10485760</value>

  </property>

 

調整namenode handler

修改hdfs-site.xml文件

<property>
     <name>dfs.namenode.handler.count</name>    //如果沒有配置service rpc  ,那么該參數配置的值處理所有的call
     <value>70</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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM