Impala+kudu数仓经验及sql调优过程分享
⽂章分两部分
1 基于impala的sql执⾏优化过程
2 Impala+kudu架构的数据仓库经验分享
第⼀部分,sql调优
1.⽼⽣常谈,sql调优必看执⾏计划,⽆论是hive还是impala。查看impala的执⾏计划可以说⽐较详细,分为三个粒度,分别是:explain、summary、profile。
(1) impala-shell中执⾏explain sql,会打印sql语句的执⾏计划,每⼀步的解释如下图所⽰:
优点:查看执⾏计划,调整sql语句
缺点:不清楚sql的执⾏详情,调整sql语句只能凭经验
(2) 在sql执⾏完成后,执⾏summary可以 看到这条sql语句执⾏时所消耗的时间和资源的情况,还有Impala预估的资源使⽤
执⾏summary语句后打印情况如下图:
优点:明确sql每个阶段的执⾏时间以及资源占⽤情况,和具体的关联⽅式
缺点:执⾏复杂的sql可能会耗费长时间,只能在sql执⾏后查看明细
(3)sql执⾏完成后,执⾏profile,产⽣⼀个详细的报告显⽰低⽔平的最新查询被执⾏。此信息仅在查询完成后才可⽤。它显⽰物理细节,如读取字节数、最⼤内存使⽤量等每个节点的物理细节,部分显⽰如下图:
优点:使⽤此信息来确定如果查询是I/O密集型或CPU绑定的,是否有⽹络条件实施的瓶颈,是否放缓是影响⽽不是其他的⼀些节点,并检查推荐配置设置,如短路本地读取效果
缺点:打印输出的明细数据量⾮常⼤,不太容易查看
根据以上三类语句,基本上可以分析清楚sql的执⾏情况,以及每个阶段所消耗的执⾏时间和资源情况,就可以出拖累整体运⾏效率的执⾏⽚段,定位到具体环节,针对此过程进⾏优化就会⼤⼤的提⾼整体sql脚本的执⾏效率。
优化的侧重点主要有⼀下⼏个⽅⾯:
1. 结合执⾏计划,进⾏Join 时防⽌⼤表被⼴播。
sql优化的几种方式2. 根据实际情况调整关联⽅式: broadcast 、(Shuffle)partitioned join
broadcast 适合⼤表关联⼩表,将⼩表⼴播复制到各个节点,再和左表进⾏JOIN
(Shuffle)partitioned join 适合⼤表和⼤表关联. 注意 partitioned join 和右表的 partition 没有直接关系, impala 会将右表打散成N 份, 发送到左表所在的节点, 然后作join
3. 要写⼊⼤量数据时,尽量使⽤Kudu的API直接写⼊,采⽤impala写⼊时,impala会进⾏预分区/排序来降低Kudu的负载,并防⽌⼤批
量的insert超时,but,正是由于这种机制存在,会降低写⼊数据时 end-to-end 的性能(impala预处理,在执⾏很长时间后才能查到数据,不让impala预处理,⽬标表很快就能查到数据),从CDH5.13/Impala2.10起,可以使⽤/* +NOCLUSTERED*/、
/NOSHUFFLE /让impala不预排序、分区数据。
例如 insert into table_a / +NOCLUSTERED/,/*NOSHUFFLE */ select * from table_b
5. 定期对表收集统计信息, 或者在⼤量DML操作后主动收集统计信息. 执⾏ COMPUTE STATS table,需要注意的是此语句在进⾏⼤表
操作时会耗费相当长的时间
6. 使⽤not in,not exists 默认将右表⼴播,⽽且没法指定partitioned join ,使⽤left anti join
7. 使⽤ straight_join 进⾏⾃定义表的关联顺序,不按照impala优化器的优化顺序执⾏
8. 根据 summary 的结果,确定出需要优化的位值,减少关联数据量和表字段
(各位⼤佬有其他途径或者⽅法,希望留⾔告知,⾮常感谢)
第⼆部分,Impala+kudu架构的数据仓库经验分享
impala + kudu 在数据仓库中需要注意的点:(浅谈经验)
1. kudu表的类型及其优缺点 range分区 如果创建时间序列的分区,分区忘记创建容易导致数据写⼊失败 Hash分区会导致数据表越来越
⼤,查询检索性能收到影响
2. kudu 进⾏⼤批量的delete效率低,并且集产⽣垃圾较多(必要时候直接drop,再create,效率会更⾼,空间也会释放)
3. 在进⾏数据仓库分层统计时,应保持相应的数据⼀致性,这个是kudu⽬前发现的⽐较鸡肋的点,就是没有overwrite 功能,不能重
写,不能truncate table/partitions。
在数据处理过程中,会出现如下情况:
第⼀次写⼊数据为10条
由于当第⼀次计算错误。
第⼆次计算将新结果写⼊时,⽤upsert只会更新和添加与第⼀次主键重复或者新增的数据,⽐如更新了8条,那么表⾥会有两条脏数据,没法处理。
这种情况有两种⽅式处理:
第⼀,当数据为中间结果表,量级⼩时可以采取的措施要么进⾏drop或者delete,清空或者重建表重新插⼊。
第⼆,在新数据插⼊/更新之前,将表中的数据进⾏标记删除,之后插⼊的数据会更新标记,此操作相对合理
(另⼀种⽅式可以借助Parquet列式存储格式的hive表,Impala+Parquet查询性能也是⾮常快,并且可以使⽤overwrite,避免产⽣数据垃圾)
5. 在执⾏ETL操作前,尽可能执⾏compute stats 表名,不然impala执⾏sql⽣成的计划执⾏数评估的内存不准确,容易评估错误导致
实际执⾏不了
6. 查看kudu表分区下所占的存储空间 和表总的存储空间
a.查看表整体所占⽤的存储空间,如下图:
b.查看表分区所占的存储空间
Cloudera Manager -->进⼊Kudu --> 进⼊Web UI–如下图:
进⼊Tablet Servers之后就能查看集节点的Tablet Servers详情列表,如下图
进⼊任意⼀个Tablet Servers后,能够查到具体的表对应的分区⼤⼩,如下图:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论