impala查询慢事件

版权声明:本文为博主原创文章,未经博主允许不得转载。https://www.jianshu.com/p/c47f9c2d95ed

【事件背景】

1月19日20:20应用反馈运营大数据集群impala查询超时。

         查询sql共涉及四张表,a、b、c、d,其中d表为历史表,大小5.9T,保留两日数据;a、b、c表为当前表,数据量较小,每小时顺序交替向d表写入两小时前数据。

           图1 各表大小

           图2 d表中保留两天数据

【所做工作】

---1月19日---

1、重启运营大数据impala服务

2、对查询语句做explain,推算sql执行所需内存开销能够满足

3、  通过hive验证查询语句,8min返回,预期impala执行应小于该时间

4、 对查询语句做compute statas操作,对sql执行计划进行优化

                图3 对d表做compute stats

---1月20日---

1、对查询sql进行拆分执行,发现大表单独执行仍需要13min

2、查看impala执行计划根据storagewaittime信息,发现集群中快、慢主机的磁盘吞吐量差别很大,推测集群磁盘性能不足导致查询慢

3、进行dd read测试,发现主机之间读性能差异不大,排除磁盘读性能较差可能

4、停机一台磁盘吞吐量表现较差的服务器,重新插拔主机raid卡。发起查询任务,发现该操作并未改善查询性能

5、运行大数据基准测试作业teregen和terasort,验证各节点磁盘读写性能相近

6、调整impala服务内存配置,从80G增加到120G,重跑查询作业,运行时间没有明显减少,排除内存不足可能

7、重跑前一日执行60分钟语句,发现执行过程中的数据读取阶段速度明显加快,推测为cache hit导致

8、清理cache后重跑该语句,20分钟完成,但数据量为前一日2倍。基于语句中存在order by,时间消耗并非随数据量线性增长,20分钟执行时间较为合理。

9、与工具室约定第二天早上进行验证

---1月21日---

1、与应用进行查询性能验证

2、查看集群HDFS磁盘读写情况,在19日凌晨开始集群I/O有明显冲高,确认为应用18日晚间压测导致

3、发现impala query不断有新作业产生,定位为应用后台脚本发起导致

4、应用方暂停脚本执行,并重启写应用

5、集群impala查询性能恢复

【事件回顾】

         工具室二线提供一条查询正常语句:1月18日早上的语句执行时间为4.45s,任务读取hdfs数据量为635G。1月21日上午再次运行该查询,执行时间超过5分钟没有返回。

                图4  1月18日语句执行4.45s,读取数据量635G

         查看集群HDFS磁盘读写情况,发现从19日凌晨开始,集群的磁盘IO冲高明显。后经应用确认,为18日晚间进行压测导致。

                     图5 近一周集群磁盘I/O曲线

通过impala query页面查看当前有多个作业执行,与工具室沟通后取消执行,但发现会有新的作业发起。

           图6  手工cancel一条语句后脚本后台自动发起下一条

通过追踪该sql,发现为由来自应用服务器客户端的两个脚本进程

csb.sh和main.sh发起。

11:00左右,与应用沟通后暂时停止这两个进程,同时重启写应用,再次运行之前作业:

       图7  重启应用后执行之前sql语句耗时14.44s(图中从上往下数第二条sql)

数据量由之前635G增长到1.1T,执行时间在14s以内。(之前4s,数据量翻倍)重启应用后,查询恢复正常。

                  图8  执行之前sql语句各节点吞吐量

查看节点吞吐量平均在5GB/s左右,对于单个节点,正常吞吐量峰值应在1GB/s,说明该查询因存在cache很快完成。

【原因分析】

1、缓存会对sql查询产生影响

当执行一条sql时,因该sql会对全表数据进行扫描,因此会将该表数据加载到OS内存,当执行下一条sql时,若发生cache hit,则查询效率会很高;反之则会通过scan hdfs从磁盘进行全表扫描的方式读取数据,效率变低;

2、数据量的增加导致查询性能衰减

针对前文提到的同一条sql语句,在数据量由之前635G增长到1.1T时,执行时间从4s增加到14s,目前虽然能满足业务需求,但随着数据量的增加,每次扫盘的数据量也会同步增加,cache的命中率会相应降低,因此预测查询性能会随着业务量增长而发生衰减,且因语句中存在排序,该衰减是非线性衰减。

3、Impala自身内存资源瓶颈

当前集群配置给各impala daemon节点的内存为80G,各节点未分配的内存大约是256-80-hbase-yarn-hdfs=100GB左右,可以作为OS cache使用,共计100*18=1.8T。那么对于单条查询来说,当其对全表进行扫描,在数据量大于1.8T时,即便OS层面存在cache,势必会有部分数据还是要通过扫盘方式获取,这会降低impala的查询性能;而应用在HDFS上的存储数据并未压缩,因此数据量往往是在TB级别,因此难以避免扫描磁盘;

4、当前AIM系统在HDFS上底层数据存储格式为txt,这是很不合理的一种数据存储方案,一般建议采用rcfile/parquet+snappy方式存储。一是因为txt格式存储空间占用大,数据扫描耗时很长;二是rcfile或parquet方式存储采用行列相结合的存储方式,有利于数据快速存取。

因此建议应用将数据改为rcfile/parquet+snappy方式存储,相信对于应用查询性能应会有显著提升。目前在线集群就采用该方式存储,单条查询语句数据扫描量基本是在10GB左右。下图为在线集群impala执行作业情况。数据量在10GB以内,并采用了rcfile+snappy方式存储,返回时间都在秒级。

     图9  在线集群采用rcfile+snappy方式,单次查询数据量读取很小

你可能感兴趣的:(impala查询慢事件)