由Impala-3316导致的并发查询缓慢问题

Posted Hadoop实操

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了由Impala-3316导致的并发查询缓慢问题相关的知识,希望对你有一定的参考价值。

温馨提示:要看高清无码套图,请使用手机打开并单击图片放大查看。


Fayson的github:

https://github.com/fayson/cdhproject


提示:代码块部分可以左右滑动查看噢


1.文档编写目的



我们在前面的文章中介绍了《》,当Hive生成的parquet文件带有timestamp字段时,使用Impala查询时会出现时区与OS本地时区不一致的问题,因为Impala默认使用的是UTC时区。通过在Impala Daemon配置中增加-convert_legacy_hive_parquet_utc_timestamps,可以解决该问题。但是却又会带来Impala并发查询缓慢的问题,本文将重现该问题,并在文末给出总结以及解决方案建议。


  • 内容概述:

1.问题重现

2.解决方案建议

3.总结


  • 测试环境:

1.操作系统:Redhat7.2

2.CDH和CM的版本为5.13.1

3.Impala已配置负载均衡

4.采用root用户进行操作


2.问题重现



确认Impala Daemon已启用-convert_legacy_hive_parquet_utc_timestamps,具体参考《》。


2.1.创建测试表



1.使用Hive创建测试表

建表语句如下,其中“statsdate”字段为TIMESTAMP类型:


[root@cdh4 scripts]# cat createSourceTable.sql 
create database if not exists iot_test;
use iot_test;
create table if not exists hive_table_text (
ordercoldaily BIGINT,
smsusedflow BIGINT,
gprsusedflow BIGINT,
statsdate TIMESTAMP,
custid STRING,
groupbelong STRING,
provinceid STRING,
apn STRING )
PARTITIONED BY ( subdir STRING )
ROW FORMAT DELIMITED FIELDS TERMINATED BY "," ;

(可左右滑动)



执行./hivesql_exec.sh createSourceTable.sql命令创建测试表


2.在beeline中查看,测试表已成功创建


由Impala-3316导致的并发查询缓慢问题


执行show create table hive_table_test;命令,查看表结构,与预期一致。


由Impala-3316导致的并发查询缓慢问题


2.2.准备测试数据



1.生成测试数据

gendata.sh脚本内容如下:


[root@cdh4 scripts]# cat gendata.sh 
function rand(){  
   min=$1  
   max=$(($2-$min+1))  
   num=$(($RANDOM+1000000000))
   echo $(($num%$max+$min))  
}  
let i=1
while [ $i -le 3 ];
do
let n=1
while [ $n -le $1 ];
do
 let month=$n%12+1
 if [ $month -eq 2 ];then
   let day=$n%28+1
 else
   let day=$n%30+1
 fi  
 let hour=$n%24
 rnd=$(rand 10000 10100)
 echo "$i$n,$i$n,$i$n,2017-$month-$day $hour:20:00,${rnd},$n,$n,$n" >> data$i.txt
 let n=n+1
done
let i=i+1
done

(可左右滑动)


执行./gendata.sh 300000命令,生成3个测试文件,每个文件包含30万条样例数据。


由Impala-3316导致的并发查询缓慢问题


2.上传测试数据

运行upLoad.sh脚本,将测试数据上传至HDFS的/tmp/hive目录下


[root@cdh4 scripts]# cat upLoadData.sh 
#!/bin/sh

num=3
path='/tmp/hive'
#create directory
sudo -u hdfs hdfs dfs -mkdir -p $path
sudo -u hdfs hdfs dfs -chmod 777 $path
#upload file
let i=1
while [ $i -le $num ];
do
 hdfs dfs -put data${i}.txt $path
 let i=i+1
done
#list file
hdfs dfs -ls $path

(可左右滑动)


由Impala-3316导致的并发查询缓慢问题


3.验证数据是否正确


由Impala-3316导致的并发查询缓慢问题


可以看到,三个文件共包含90万条数据,与原始文件数据总数一致


4.加载数据进入测试表


执行./hivesql_exec.sh loadData.sql命令,加载数据


[root@cdh4 scripts]# cat loadData.sql 
use iot_test;
LOAD DATA INPATH '/tmp/hive/data1.txt' INTO TABLE hive_table_test partition (subdir="10");
LOAD DATA INPATH '/tmp/hive/data2.txt' INTO TABLE hive_table_test partition (subdir="20");
LOAD DATA INPATH '/tmp/hive/data3.txt' INTO TABLE hive_table_test partition (subdir="30");

(可左右滑动)


由Impala-3316导致的并发查询缓慢问题


5.在Hive中验证,在beeline中查看数据总数

执行select count(*) from hive_table_test;命令,可以看到测试表数据总数与导入数据条数一致。


由Impala-3316导致的并发查询缓慢问题


2.3.由Hive生成包含timestamp的parquet表



1.使用Hive创建Parquet表

生成Parquet表语句如下,其中“statsdate”字段为TIMESTAMP类型:


[root@cdh4 scripts]# cat genParquet.sql 
use iot_test;
create table hive_table_parquet (
ordercoldaily BIGINT,
smsusedflow BIGINT,
gprsusedflow BIGINT,
statsdate TIMESTAMP,
custid STRING,
groupbelong STRING,
provinceid STRING,
apn STRING )
PARTITIONED BY ( subdir STRING )
STORED AS PARQUET;
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
insert overwrite table hive_table_parquet partition (subdir) select * from hive_table_test

(可左右滑动)


由Impala-3316导致的并发查询缓慢问题


执行./hivesql_exec.sh genParquet.sql命令,生成包含时间戳的parquet表


由Impala-3316导致的并发查询缓慢问题

由Impala-3316导致的并发查询缓慢问题


2.在Impala中查看数据总数

执行select count(*) from hive_table_parquet;命令,与生成Parquet表的源表数据总数一致。


由Impala-3316导致的并发查询缓慢问题


3.验证Parquet文件是否由Hive生成


[root@cdh4 scripts]# hdfs dfs -ls -R /user/hive/warehouse/iot_test.db/hive_table_parquet/

(可左右滑动)


由Impala-3316导致的并发查询缓慢问题


[root@cdh4 scripts]# parquet-tools meta hdfs://cdh3.macro.com:8020/user/hive/warehouse/iot_test.db/hive_table_parquet/subdir=10/000000_0
creator:       parquet-mr version 1.5.0-cdh5.13.1 (build ${buildNumber})
file schema:   hive_schema

(可左右滑动)


由Impala-3316导致的并发查询缓慢问题


注:parquet-tools meta $Parquet文件绝对路径


2.4.准备并发测试脚本




[root@cdh4 scripts]# cat impala-test.sh 
#!/bin/sh

#Concurrency test
let i=1
while [ $i -le $1 ];
do
impala-shell -B -i cdh4.macro.com:25003 -u hive -f $2 -o log/${i}.out &
let i=i+1
done
wait

(可左右滑动)


由Impala-3316导致的并发查询缓慢问题


2.测试SQL语句如下


SELECT 
nvl(A.TOTALGPRSUSEDFLOW,0) as TOTALGPRSUSEDFLOW, nvl(A.TOTALSMSUSEDFLOW,0) as TOTALSMSUSEDFLOW, B.USEDDATE AS USEDDATE
FROM ( SELECT SUM(GPRSUSEDFLOW) AS TOTALGPRSUSEDFLOW, SUM(SMSUSEDFLOW) AS TOTALSMSUSEDFLOW, cast(STATSDATE as timestamp) AS USEDDATE
FROM hive_table_parquet SIMFLOW
WHERE SIMFLOW.subdir = '10' AND SIMFLOW.CUSTID = '10099'
AND cast(SIMFLOW.STATSDATE as timestamp) >= to_date(date_sub(current_timestamp(),7))
AND cast(SIMFLOW.STATSDATE as timestamp) < to_date(current_timestamp())
GROUP BY STATSDATE ) A
RIGHT JOIN (
SELECT to_date(date_sub(current_timestamp(),7)) AS USEDDATE UNION ALL
SELECT to_date(date_sub(current_timestamp(),1)) AS USEDDATE UNION ALL
SELECT to_date(date_sub(current_timestamp(),2)) AS USEDDATE UNION ALL
SELECT to_date(date_sub(current_timestamp(),3)) AS USEDDATE UNION ALL
SELECT to_date(date_sub(current_timestamp(),4)) AS USEDDATE UNION ALL
SELECT to_date(date_sub(current_timestamp(),5)) AS USEDDATE UNION ALL
SELECT to_date(date_sub(current_timestamp(),6)) AS USEDDATE
) B on to_date(A.USEDDATE) = to_date(B.USEDDATE) ORDER BY B.USEDDATE

(可左右滑动)


由Impala-3316导致的并发查询缓慢问题


2.5.Impala并发测试



使用相同的测试SQL,在不同并发测试场景下做并发测试,为了避免单次测试结果的偶然性,针对3种并发测试场景分别作了三次测试。


1.测试1个并发查询

第一次测试:1.09秒返回查询结果


由Impala-3316导致的并发查询缓慢问题


第二次测试:0.76秒返回查询结果


由Impala-3316导致的并发查询缓慢问题


第三次测试:0.78秒返回查询结果


由Impala-3316导致的并发查询缓慢问题


可以看到,1个并发查询,能在秒级内返回结果


2.测试10个并发查询


第一次测试:所有并发查询均在6.4秒内完成


由Impala-3316导致的并发查询缓慢问题


第二次测试:所有并发查询均在6.8秒内完成


由Impala-3316导致的并发查询缓慢问题


第三次测试:所有并发查询均在6.8秒内完成


由Impala-3316导致的并发查询缓慢问题


可以发现,在10个并发查询的场景下,Impala查询性能已经有明显的下降了。


3.测试30个并发查询

第一次测试:前6个查询均在5秒内完成,但是随着并发数的增大,查询返回结果的时间越长,花费时间最长的为11.81秒。


由Impala-3316导致的并发查询缓慢问题

由Impala-3316导致的并发查询缓慢问题


第二次测试:前4个查询均在5秒内完成,30个并发查询中,花费时间最长的为12.24秒。


由Impala-3316导致的并发查询缓慢问题

由Impala-3316导致的并发查询缓慢问题


第三次测试:前5个查询均在5秒内完成,30个并发查询中,花费时间最长的为12.20秒。


由Impala-3316导致的并发查询缓慢问题


从并发测试结果来看,在30个并发查询的测试场景下,Impala查询性能急剧下降,即随着并发查询数量的增多,Impala查询性能越差。


3.总结



如果Parquet表是由Hive/Spark产生的,包含TIMESTAMP字段类型,并且Impala高级配置包含--convert_legacy_hive_parquet_utc_timestamps=true启用选项,那么使用Impala做并发查询时,随着并发的增加,查询性能会慢慢下降,并发越高,性能下降越厉害。根据我们在上一章的测试效果,可以看出,1个用户单独查询能秒级返回查询结果,10个用户并发查询需要3秒左右返回查询结果,30个用户并发查询需要耗时15秒左右。


该性能问题是由IMPALA-3316(https://issues.apache.org/jira/browse/IMPALA-3316)导致的,Impala在读取Hive或者Spark生成的Parquet表时,如果表包含TIMESTAMP字段类型,并且Impala高级配置包含--convert_legacy_hive_parquet_utc_timestamps=true启用选项。Impala会调用Linux本地的时间转换函数(localtime_r)将Timestamp数据转换成系统的当地时间,而缺省情况下,Impala并不做任何转换,且将Timestamp时间都作为UTC时间处理。但是localtime_r函数内部实现会加上进程全局锁,因此当有大量并发的Parquet读取时会影响性能。而并发越高,全局锁的问题就越严重,从而导致性能下降就越厉害。


4.解决方案建议



在Impala的该bug修复前,我们建议通过以下三种方式来规避这个问题:


1.如果不要求 Impala 返回本地时间, 可以去掉

--convert_legacy_hive_parquet_utc_timestamps=true启动选项


2.将相关的 Parquet表用 Impala 生成


3.Hive/Spark 产生 Parquet 表时使用STRING类型代表时间, 并且时间格式采用 yyyy-MM-dd HH:mm:ss.SSS 或者 yyyy-MM-dd HH:mm:ss,这种方式下,使用 Impala 的date/time函数时, Impala 会自动将其转换成TIMESTAMP类型

对于该三种方法的比较,我们会在后续的文章中持续进行说明。


测试脚本源码:

https://github.com/fayson/cdhproject/tree/master/ScriptFiles



提示:代码块部分可以左右滑动查看噢


为天地立心,为生民立命,为往圣继绝学,为万世开太平。

温馨提示:要看高清无码套图,请使用手机打开并单击图片放大查看。



推荐关注Hadoop实操,第一时间,分享更多Hadoop干货,欢迎转发和分享。


以上是关于由Impala-3316导致的并发查询缓慢问题的主要内容,如果未能解决你的问题,请参考以下文章

如何解决SQL Server查询速度缓慢的问题

Oracle:连接两个快速、不相关的查询导致查询缓慢

未使用数据库索引导致查询缓慢

Postgres 进程显示 100% CPU 但实际使用率为 6%,导致查询响应缓慢

在 MySql 中的 WHERE 语句上使用 OR 会导致执行缓慢

mysql 查询表并发高时的优化点