前言
从去年下半年开始,组内就开始着手准备升级公司内部的Hadoop集群,由于老版本实在已经落后社区很多了,也陆续碰到很多社区上已经被fix的bug。所以决定做一个大胆的举动:升级公司内部大集群版本。像这种比较aggressive的做法,很多人不是一开始能够接受,它存在不可控的风险。但所幸,在今年暑假,我们成功将内部版本升到了最近比较新的Hadoop版本。本文是对此过程的经验教训,相信会给很多想要做Hadoop Rolling Upgrade的同学有所帮助。
Rolling Upgrade兼容性测试
我们此次升级采用的不是停服务的方式,而是Rolling Upgrade的方式,也算是对我们团队的一个考验吧。所以在这里面,要做大量的兼容性测试。因为rolling的过程中,会存在新老版本(NN,DN,RM和NN)共存的情况。再加上同时在跑的YARN,情况组合起来还是挺多的。不过,测试下来,除了HDFS新版本特性异构存储(StorageType)出现明显不兼容错误,其它都正常。
升级后的性能不稳定问题
其实前期兼容性测试做的足够完善的情况下时,整个Rolling Upgrade的过程问题不大。按照官方文档的建议,从NN开始升级,然后DN一点点的rolling替换即可,用户应用对此无感知。
但是后面我们怎么也没料到,在新的升级后的版本运行过程中,出现了严重的性能不稳定问题,主要表现为RPC周期性变慢,到最慢的时候,延时已经达到秒级别,甚至到了用户都无法正常使用的情况。但是每次一重启NN,这个问题立马恢复,然后过一段时间,又开始变慢。
Jvm层面调优
像这种系统逐渐变慢的问题,我们的第一反应,HDFS本身应该是没问题,可能是jvm层面,比如某些资源没有被回收的问题,或gc参数没配对。于是乎,我们加了以下对我们有用的参数:
1).调整NN heap大小,之前总heap设置过大,导致其几乎不full gc,这样导致jvm中的大量垃圾数据一直得不到清理,加重Jvm本身的内存管理。得到的教训是,不是说不让进程full gc就是好的操作。经过这个调整之后,缓慢周期得到了适当的延长,但是还是没有根本解决,:(。
2).增加更细粒度的jvm控制参数,如下:
- XX:+PrintTenuringDistribution 查看每次minor GC后新的存活周期的阈值,为新生代的比例调整提供依据
- -XX:+PrintHeapAtGC 打印GC前后的详细堆栈信息
- -XX:+PrintGCApplicationStoppedTime 打印JVM应用停顿时间
- -XX:-UseBiasedLocking 禁用偏向锁(在存在大量锁对象的创建并高度并发的环境下禁用偏向锁能够带来一定的性能优化)
期间,我们也有关注过是否是jvm的Code Cache区满了,导致系统响应变慢呢,Code Cache用于存储jvm JIT产生的编译代码。
HDFS系统层面优化
在jvm层面的优化都做完后,我们发现NN还是会出现周期性变慢的情况。于是乎,又将目光转向了HDFS系统本身。我们对内部的HDFS环境,结构部署做了考量之后,打算对HDFS开启一轮轮的优化,然后看看问题最终出在哪里。截止目前为止,我们做了以下优化(都是大规模集群中通常也会采用的):
- NN,JN分离部署,这个很重要,JN同步慢了,直接影响NN的RPC处理
- 开启async editlog功能
- Fair Call Queue开启,解决潜在的RPC拥塞问题,延用默认参数即可
- Fsimage压缩功能开启,同时对fsimage的传输做带宽限速设置,这可以减少SBN向ANN,同步fsimage时造成的瞬时RPC毛刺(因为当时2者之间会占用大量带宽)。
- NN删除操作相关优化。新版本的NN删除对我们来说,算是我们踩得比较大的一个坑。新版本的HDFS对DN的块存储结构做了优化,用新的结构FoldedTreeSet取代原本的LightWeightGSet(详见HDFS-9260)。前者在内存利用率上会跟高,但是对应地它不利于块的update,也就是我们的删除块操作这种方式。本来NN在删除大的文件目录时,会出现严重的响应延时问题,加上这个改动,这种延时的表现就更加明显了。感兴趣的同学,可以关注HDFS-13671(Namenode deletes large dir slowly caused by FoldedTreeSet#removeAndGet)。这个我们调整了FoldedTreeSet的碎片阈值参数。还有一个小的优化点,是可配置化了删除操作的批量间隔时间。
以上就是我们对HDFS层面的优化改造。以上都是我们最近一段时间踩过的坑,和经验总结。
引用
[1].https://issues.apache.org/jira/browse/HDFS-13671. Namenode deletes large dir slowly caused by FoldedTreeSet#removeAndGet
[2].https://issues.apache.org/jira/browse/HDFS-9260. Improve the performance and GC friendliness of NameNode startup and full block reports