Impala作为一种查询系统,提供SQL语义,可以查询存储在Hadoop的HDFS和HBase中的PB级大数据。相比于其它查询工具,Impala的最大特点是查询速度较快。所以对Impala的优化也是对其查询速度的一种保障。
1、选择合适的文件存储格式,既然使用impala,无非就是为了一个目的:性能好/资源消耗少,Impala为了做到通用性,也就是为了更好的hive无缝连接,支持了大部分Hive支持的文件格式,例如Text、Avro、RCFile、Parquet等(不支持ORC),但是为了实现更快的ad-hoc查询(基本上都是OLAP查询,查询部分列,聚合,分析),我们基本上都会选择使用Parquet格式作为数据文件存储格式,即使你的数据导入到hive中存储的使用的是其它格式(甚至通过自定义serde解析,例如Json),仍然建议你新建一个Parquet格式的表,然后进行一次数据的转换。因此这个条目可以看做是:请选用Parquet作为文件存储格式!
2、选择合适的Partition粒度,分区的个数通常是根据业务数据来的,通常时间分区(例如日期/月份)是少不了的,例如对于一个支持多终端的应用,可能在时间分区下面再加一层终端类型的分区,设置对于每一个终端的不同操作在进行一层分区,根据唯物辩证法,凡事都需要保持一个度,那么就从两个极端的情况下来分析分区的粒度如何确定:1:分区过少:,整个表不使用分区,或者只有一个日期的分区,这样会导致频繁的查询某一个终端的数据不得不扫描整天的数据甚至整个表的数据,这是一种浪费;2、分区过多,对于每一个要统计的维度都创建一个分区,这样对于任何一个维度=’xxx’的查询都只需要扫描精确需要的数据,但是这样会导致大量的数据目录,进而导致大量的文件需要扫描,这对于查询优化器是一个灾难。因此最终的建议是:根据查询需求确定分区的粒度,根据每一个分区的成员个数预估总的分区数,保证一个表的分区数不超过30000(经验之谈?),避免过小的分区。
3、尽量分区的成员的长度,目前分区字段可以支持数值类型和字符串,但是这里推荐尽可能的使用合适的整数(一般用0-256就可以保存一个分区成员的映射了,否则分区会很多)而非原始的字符串,可以在外面建立字符串到整数的映射以保存原始信息,这个约束的主要原因是每一个分区会占用一个目录,每一个目录名又会在NameNode中占用一定的内存,所以不光光是对于Impala而言,对于使用Hadoop的用户而言,尽量减小文件目录的长度。
4、选择合适的Parquet Block大小,在条目1中已经明确,要使用Impala获得较快的查询性能,那么就老老实实的使用Parquet作为存储格式,而每一个Parquet的Block大小又有什么影响呢,这里暂且把Block的大小理解成一个Parquet分区的大小,在存储上表现为文件大小,如果文件过大,那么会导致这个文件只会一个Impalad进程处理,这样大大降低了Impala的并行处理能力;而如果文件过小则会导致大量的小文件,在带来并发执行的同时也会带来大量的随机I/O的影响,因此需要对于特定的数据进行不同的parquet Block大小测试以寻求最适合该数据集的Block大小。
5、收集表和分区的统计信息,在执行完数据导入之后,建议使用 COMPUTE STATS语句收集表的统计信息,当然也可以只收集某一个分区的统计信息。
6、减少返回结果大小,如果需要统计聚合,直接在SQL中完成,尽可能的在where中执行过滤而不要查出来之后在应用端做过滤,对于查询结果尽可能使用LIMIT限制返回结果集大小;避免大量的结果展示在终端,可以考虑通过INSERT xxx的方式把结果输出到文件,或者通过impala-shell参数将结果重定向。
7、对于执行性能较差的查询使用EXPLAIN分析原因。
8、最后,查询操作系统配置、查看系统使用负载,可以使用Query Profile工具来探测。
上面的这些条目是最基本的应对性能调优的方案,主要包括:使用Parquet格式存储数据、分区粒度要确定好,保证整个表的分区数不要太多(目录不要太多),每一个分区下不要存在过多的小文件(选择合适的Parquet文件大小),收集统计信息使得查询优化器能够选择更好的查询方案,最后要学会使用EXPLAIN和Profile功能分析性能问题所在。
领取专属 10元无门槛券
私享最新 技术干货