前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Impala 3.4 SQL查询之ScanRange流程归纳(六)

Impala 3.4 SQL查询之ScanRange流程归纳(六)

作者头像
skyyws
发布2022-05-20 08:42:18
2190
发布2022-05-20 08:42:18
举报
文章被收录于专栏:skyyws的技术专栏

我们在前面几篇文章,从代码处理层面,详细分析了Impala的ScanRange相关知识,包括FE端的处理、parquet文件的处理、IO thread的处理等,涉及到的内容比较多。本文笔者将前几篇文章的内容做了一个汇总,整体看一下Impala的整个ScanRange的处理流程。需要注意的是,我们当前的分析都是基于parquet格式、remote HDFS的场景。我们将整个处理过程汇总到了一张流程图上,如下所示:

接下来,我们就根据流程图,来看下整个的ScanRange处理流程。

Coordinator处理

首先是左上方的紫色方框,表示的是Coordinator接收客户端发来的SQL请求,然后通过JNI传到FE端进行解析,最终生成分布式的执行信息,发到各个Executor上进行处理。这块的处理其实就是thrfit结构体在BE/FE之间的传输,我们在Impala 3.4 SQL查询之ScanRange详解(三)一文中,已经详细描述过了,这里不再赘述。

Disk Queue与IO thread构造

Executor有一个类专门用来管理本地磁盘或者远端文件系统上的IO相关的操作,叫DiskIoMgr。DiskIoMgr初始化的时候,会构造一个disk_queues_集合,集合中的每个成员都是代表一个本地disk对应的队列,或者是一种远端文件系统,例如remote HDFS/S3等。同时,对每个队列都会绑定指定数量的线程来处理后续的数据扫描,这些线程就是IO thead。不同的队列,可以通过参数配置IO thread数量,以remote HDFS为例,对应的参数就是num_remote_hdfs_io_threads,默认是8个。我们在Impala HDFS_SCAN_NODE之IO threads模型文章中,有详细介绍过这部分的处理流程。对应流程图中的,就是右上角的第一个蓝色方框。

RequestContext处理

当查询计划信息发到executor之后,executor会根据相关信息构造RequestContext对象,然后放到request_contexts_队列当中。一个RequestContext对象,可以简单理解为对一个表的扫描请求的封装。这个executor上所有每个表的扫描请求,都在这个request_contexts_队列中等待处理。

每个RequestContext都会包含一个PerDiskState集合,我们可以根据当前这个RequestContext的disk queue类型,获取到指定的PerDiskState对象,这个PerDiskState就包含了每个disk queue的状态,比如unstarted_scan_ranges_、in_flight_ranges_等。

这些包含关系就对应了流程图中的黄色方框,关于RequestContext和PerDiskState的介绍,在Impala HDFS_SCAN_NODE之IO threads模型Impala 3.4 SQL查询之ScanRange详解(三)中都有详细说明。

Footer ScanRange构造

Executor获取到coordinator发过来的执行计划信息之后,会构造footer ScanRange对象,然后加入到unstarted_scan_ranges队列中,然后准备启动scanner线程进行后续的处理。这个过程就对应流程图中左边的绿色方框。关于footer ScanRange的构造,我们在Impala 3.4 SQL查询之ScanRange详解(四)一文中,有详细介绍。

IO thread处理

IO线程启动之后,首先会先从request_contexts_队列中获取队首的RequestContext对象,然后获取对应的PerDiskState对象,接着从PerDiskState对象的unstarted_scan_ranges_队列中获取一个ScanRange成员,获取完成之后,IO thread会将该RequestContext对象又放回到request_contexts_队列的尾部。

接着,IO thread会将刚刚获取到的ScanRange对象加入到ready_to_start_ranges_队列中。然后,再从in_flight_ranges_队列的首部获取一个ScanRange对象,这个才是IO thread真正要处理的ScanRange。

从in_flight_ranges_队列获取到ScanRange之后,IO thread就会进行实际的scan操作,操作完成之后,会更新ScanRange的相关信息。然后再判断该ScanRange是否处理完成,如果没有处理完成,则加入到in_flight_ranges_队列尾部;如果已经处理完成,则直接返回。这表示IO thread完成了本次处理,结束之后,继续上述步骤,处理其他的ScanRange,直至结束。

上述的这些流程,我们在Impala 3.4 SQL查询之ScanRange详解(四)一文中,有详细的描述。

Scanner线程处理

当Executor构造完footer ScanRange之后,就会启动scanner线程进行处理,主要就是流程图中的红色方框部分。Scanner线程首先会从ready_to_start_ranges_队列中获取头部的ScanRange进行判断,如果buffer_tag不是NO_BUFFER(以remote HDFS为例),那么会分配buffer,然后加入到in_flight_ranges_。

此时IO thread就可以获取in_flight_ranges_中的ScanRange(这里是footer ScanRange)进行处理。处理完成之后,scanner线程就会根据扫描的数据,解析parquet文件的元数据,进而构造data ScanRange。同样,分配buffer之后,会将这些data ScanRange加入到in_flight_ranges_队列。等待IO thread处理完这些data ScanRange,scanner线程再进行后续处理。关于scanner线程的处理,可以参考Impala 3.4 SQL查询之ScanRange详解(五),有详细的介绍。

总结

以上就是整个ScanRange的基本处理流程,这其中比较重要的就是理解IO thread和scanner线程各自负责的功能,当然我们省略了一些实现细节。由于我们这里讨论的是parquet格式,因此我们Impala 3.4 SQL查询之ScanRange详解(五)一文中,也详细介绍了Impala对parquet文件的处理,这个在流程图中并没有体现。对于其他的文件格式的处理,我们目前也没有展开。后续有机会,再跟大家一起学习。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-04-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Coordinator处理
  • Disk Queue与IO thread构造
  • RequestContext处理
  • Footer ScanRange构造
  • IO thread处理
  • Scanner线程处理
  • 总结
相关产品与服务
大数据
全栈大数据产品,面向海量数据场景,帮助您 “智理无数,心中有数”!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档