周末去了趟外地,受托给某省移动公司做了一下Hadoop集群故障分析和性能调优,把一些问题点记录下来。
该系统用于运营商的信令数据,大约每天1T多数据量,20台Hadoop服务器,赞叹一下运营商乃真土豪,256G内存,32核CPU,却挂了6块2T硬盘。还有10台左右的服务器是64G内存,32核CPU,4~6块硬盘,据用户反馈,跑数据很慢,而且会有失败,重跑一下就好了。
软件环境是RedHat 6.2,CDH Hadoop 4.2.1。
总容量260多TB,已使用200多T。
首先,这硬件配置属于倒挂,内存CPU和硬盘不匹配,因为作为Hadoop来说,注重的是磁盘的高吞吐量,而并发读写磁盘个数决定了吞吐量的大小。对于Hadoop来说,硬盘数量多比单盘容量大更具有优势。举例说明,假设一块硬盘的读写速度是210MB每秒,一块硬盘3TB,那么全部扫描一遍大概需要4小时左右。而1TB的硬盘扫描一遍大概只需要一个多小时。Hadoop最好的硬盘挂载方式是JBOD,也就是直接插主板不做raid。那么如果同时10块硬盘读写,得到的吞吐量是2.1G左右。20块就是4G左右。所以,对于Hadoop来说,30块1TB硬盘的性能要绝对优于10块3TB的硬盘。但是目前来说,性价比最高的还是2TB的硬盘。
还好只有20台服务器,可以挨个手工上去查一下,如果是200台,挨个查我就死在移动了。除了硬件配置不合理外,还查出几个比较重要的问题。
一、20台机器没有做机架感知,而且复制份数是2,因为受集群总存储能力限制,目前只能复制两备份,这个没辙了,以后扩服务器再说吧。
二、配置不合理,且没有为异构硬件搭配不同的Hadoop配置项
1. 因为采用CDH 4,所以实际是在YARN上跑MRv1,256G内存的服务器配置的map槽位数是150个,reduce槽位数是130个,其实是很大程度上超出了32核CPU的计算能力,绝大部分的CPU时间消耗在了MR Java进程之间的切换上。大量的Java进程用strace跟踪看都是在互斥锁上等待(FUTEX_WAIT)。所以,跑任务的时候服务器的System CPU很高,真正用于MR的User CPU很少。
2. 256G跟64G内存的服务器,Hadoop配置文件一样,64G也是150 map slots, 130 reduce slots,mapred.map(reduce).child.java.opt内存也没改,没发生OOM真是奇迹...MR槽位数不是越大越好,要跟CPU和内存数量搭配着算才好,至于2.0,更简单一些,只要配置vcore数量就行了,但是也不是vcore配的越大就越好。而且,据说搭建集群之前有公司给他们培训过Hadoop,居然告诉他们map,reduce槽位数的配置项没用,不用管,这培训也太坑人了吧。
3. 没有做磁盘保留空间,我到了现场以后没多久一台NodeManager就挂了,我以为是我神威所致,服务器害怕了,上去一看是硬盘100%了...
三、Linux系统层面没有做优化。
1. 没有开启TCP回收和TCP复用
2. 没有设置文件打开句柄数
3. 还有三台服务器没有关闭SELinux
4. 没有自动化运维,20台Hadoop服务器都是tar包解压缩手工装的。
5. 没有监控,据说是我去之前几天才装的Ganglia...监控数据采集了MR和HBASE,没有HDFS
6. 没有做数据压缩。
7. 小文件太多,块数量380万,文件数量360万。分块大小设定128M,上去看很多文件都达不到,基本都是40~80兆左右。
四、业务层面太过复杂。
1. 数据清洗依赖Hive进行,而没有采用编写MR的方式,Hive开发速度快,但是执行效率是真低啊。
2. 单个查询Join太多,并开启了Hive的并行查询,引发大量的Stage任务,占用太多MR槽位。
3. 同时并发计算太多,没有做Job分解和规划调度。
4. 清洗后的数据使用snappy压缩,这玩意计算读取的时候不分块的,只能1map读取。
总的来说,基本还是由于硬件配置不合理和对Hadoop底层不熟悉导致的性能较低,这个不是我这个层面能解决的问题了。
当然,这不是我见过的配置最不合理的硬件,记得去年年初中软国际卖某部委的Hadoop服务器,找我给配置,128G内存,64核CPU,4块2T盘。当时我看着这服务器是真不知道该怎么配才合适。当时说给钱,到现在也没给,赖账了这帮人...
本文出自 “实践检验真理” 博客,谢绝转载!
原文地址:http://slaytanic.blog.51cto.com/2057708/1636197