hadoop hdfs 性能调优

说明

  • 其实hdfs 并不适合作为小文件的分布式存储系统 . 前人埋下的坑....

背景

  • 一次线上环境的hdfs namenode 进程打满cpu. 一直在百分之6 7百 . namenode 一直在做 full gc, 此时hdfs基本处于不可用状态 , 此时系统可用内存又不足,而且cpu负载很高. 由于这个环境第一次接手维护 . 这篇文章主要总结下如何做的优化.

环境:

  • hadoop 版本:Hadoop 2.6.0-cdh5.5.0
  • 服务器 : CentOS release 5.6 (Final) , 32G 内存 , 8核cpu , 12块盘
  • 内核版本: Linux version 2.6.18-308.13.1.el5
  • hadoop 集群一共三台机器 , namenode 做了自动HA , datanode 也都在这三台机器上.

正文

  这个hadoop 环境是通过CDH 的Unmanaged Deployment方式来安装的 . 可以参考这里 ,没有管理端 没有监控. (个人还是偏好社区版本 , 灵活可控. ) . 那没有监控自然是先加监控呗

指标收集

  • 采集工具
      没有监控首先考虑的是加个监控上去 . 由于我们线上有opentsdb , grafana . 缺了个采集工具 , 网上找了把 , 找了个tcollector可以作为指标采集的工具. 参考这里. 而且tcollector自带了hadoop 的采集脚本.这个采集脚本使用了python语言通过采集hadoop 提供的 restapi接口来实现的. 具体hadoop指标参考这里
  • 兼容性的适配
       例如: 1. 在hadoop_namenode.py这个采集脚本里面连接的本地是localhost地址. 由于我们hdfs没有监听localhost ip所以连不上. 2. 在procstats.py这个采集系统状态的脚本里面会用到/proc/softirqs这个系统状态文件.然而在Linux version 2.6.18这个版本里面没有这个文件.
  • 定制化监控
      在tcollector这个程序里添加一个定制化监控还是非常简单的. 只要在它指定的文件夹中添加一个采集脚本 在程序里按照它的格式输出就可以 . 用python ,shell 实现都可以. 例如
#!/bin/bash
. "/etc/profile"
etc_path="$(cd "`dirname "$0"`"/../etc; pwd)"
run_day=$(date "+%Y-%m-%d")
time=$(date '+%H%M')
for i in `cat ${etc_path}/dir.txt` ;
 do
 meta_array=($(hadoop fs -count $i 2> /dev/null))
 echo "hadoop.hdfs.dir.count.dirs $(date +"%s") ${meta_array[0]:-0} dir=$i "
 echo "hadoop.hdfs.dir.count.files $(date +"%s") ${meta_array[1]:-0} dir=$i "
 echo "hadoop.hdfs.dir.count.size $(date +"%s") ${meta_array[2]:-0} dir=$i "
done ;

这里实现的是对重点目录的增长趋势做一个监控. 输出的第一列是指标名称. 第二列是时间戳, 第三列是指标值 后面是tags键值对. tcollector在读取到脚本输出后会自动将指标输出到opentsdb中去.

  • 启动tcollector
sh tcollector start -L opentsdb_host1,opentsdb_host2 -v -D

指标分析

  • 下图展示了张系统的内存的指标 (其实想精确统计系统可用内存还是很困难的这个后面会提到) 从这张图看系统可用内存还是挺紧张的. 而且系统已经用了一部分swap. 我们系统的swappiness 设置的是0(可以通过命令cat /proc/sys/vm/swappiness 查看) . 这表示只有物理内存已经快用尽了才会使用swap.(ps , 好像最新的内核如果设置为0 , 表示never swap .)


    系统内存

系统swap

但是系统内存都用到哪里去了呢 , 统计所有进程总共占用多少内存可以用下面的命令进行统计

[root@XXX scripts]#  grep Pss /proc/[1-9]*/smaps | awk '{total+=$2}; END {print total}'

结果是进程占用的内存才十多个G 远没到30多G那剩下的内存去哪里了呢,

[root@XXX scripts]# free -m
             total       used       free     shared    buffers     cached
Mem:         32176      32026        150          0        801         76
-/+ buffers/cache:      31148       1028
Swap:        18041       1643      16398

那系统内存被谁给用去了呢 而且此时的cpu负载一直很高


系统cpu负载
slab_info

为了看了更直观,这里的slab用了负值表示.这里可以看出系统内存波动和slab完全一致. 那slab又被谁给用去了呢


slabtop

使用slabtop命令看到slab绝大部分被ext3_inode_cache和dentry_cache 用去了. 而ext3_inode_cache是被谁用去了呢. 在top 查看进程时 ,经常看到du -sk /data1/hdfs/data/current/BP-xx.xx.xx.xx 在运行. 我们有12块盘,所以经常看到很多du -sk 在运行. 这个统计脚本的父进程是datanode, datanode 会定期(默认10分钟)统计BP的大小.我们每块盘都有大量的小文件. 其中一块盘就有差不多块200万的文件. 12块盘那就是2000多万的文件.

##统计一个目录下的文件个数
[root@XXXX  hdfs]# ls -lR| grep "^-" | wc -l
1885296

这时使用du -sk是非常耗时的.它会递归文件所以会导致slab cache一直很高.基本都超过10分钟.du -sk 这个命令在2.8的版本已经可以被替换了 详情见这里
这里提到可以用df 替换du的一个方案具体实现是这样的

mv /usr/bin/du /usr/bin/du_bak
vim /usr/bin/du

#!/bin/sh
if [[ $2 == */current/BP-* ]] && [ $1 == -sk ]
then
    used=`df -k $2 | grep -vE 'Used|可用' | awk '{print $3}'`
    echo -e "$used\t$2"
else
    echo -e "$(du_bak $@)"
fi
chmod +x /usr/bin/du

方案参考这里
由于df是基于硬盘统计的所以很快, 而du是基于文件统计的. 这种方案在datanode的目录分别在不同的硬盘上问题不大.
而且调整后的效果很明显(红框是调整后的效果)

meminfo

上图可以看到slab里用到的cache明显减少 . 用于系统的cache明显增多.而且系统的cpu负载也明显降低
红框是调整后的效果

细心的同学可能还会问,为什么还是每隔6个小时slab还是会去增长呢. 这是由于datanode 的directoryscan会每隔6小时扫描一次目录这里也是递归,会去检查文件是否有坏块, 丢失块或者不一致的情况.

这里可以调整/proc/sys/vm/vfs_cache_pressure的值让操作系统更加积极的回收slab里面的cache . 默认是100 可以被调整500或1000.这里调整到500 . 下面这张图可以看到调整前后的变化.


vfs_cache_pressure调整前后比较

总结

说明

  • 不同linux版本的free看到的统计方式不一样.参考这里

    当我们考虑有多少cache可供回收的时候,首先要知道的是:不同版本的”free”命令计算cache值的算法不同,据不完全统计举例如下:
    版本:procps-3.2.8-36
    cache值等于/proc/meminfo中的”Cached”;
    版本:procps-3.3.9-10.1
    cache值等于/proc/meminfo的 [Cached + SReclaimable];
    版本:procps-ng-3.3.10-3
    cache值等于/proc/meminfo的 [Cached + Slab]。

  • 系统可用内存的计算方式 参考这里
      如果/proc/meminfo中有MemAvailable时取MemAvailable
    /proc/meminfo中无MemAvailable时取 free+cache+ SReclaimable 当然cache 里面还有一分部可能不能被回收.
      总的来说 很难精确估计系统剩余可用内存.

海量小文件优化方案

  • 使用df替换du去统计
  • 修改vfs_cache_pressure的值让系统内核更加积极回收slab里的cache
  • 减少数据存储的现有目录层级[HDFS-8791]参考这里
  • 控制扫描的速度 参考这里 . hadoop2.8 提供了控制Allow the directoryScanner to be rate-limited
  • 使用文件归档 Archives 参考这里 可以将多个文件合并成一个文件.
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,843评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,538评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,187评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,264评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,289评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,231评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,116评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,945评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,367评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,581评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,754评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,458评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,068评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,692评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,842评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,797评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,654评论 2 354