cari
Rumahpangkalan datatutorial mysqlImpala源代码分析(3)-backend查询执行过程
Impala源代码分析(3)-backend查询执行过程Jun 07, 2016 pm 04:31 PM
impalamenganalisismelaksanakanPertanyaankod sumber

这篇文章主要介绍impala-backend是怎么执行一个SQL Query的。 在Impala中SQL Query的入口函数是: void ImpalaServer::query(QueryHandle query_handle, const Query query) 生成一个QueryExecState伴随这个SQL执行的生命周期,代表正在执行的这个SQL; 调用E

这篇文章主要介绍impala-backend是怎么执行一个SQL Query的。
在Impala中SQL Query的入口函数是:
void ImpalaServer::query(QueryHandle& query_handle, const Query& query)

  • 生成一个QueryExecState伴随这个SQL执行的生命周期,代表正在执行的这个SQL;
  • 调用Execute函数启动执行流程;
  • 启动一个Wait线程等待结果。

这个Execute()函数首先是通过JNI向impala-fe请求SQL解析和执行计划生成(已经在上一篇文章中讲了这个过程),得到该Query对应的TExecRequest对象,交由impala-backend执行。
从下面这个函数开始backend执行,同时开始fragment status report。
Status ImpalaServer::QueryExecState::Exec(TExecRequest* exec_request)
因为我们知道在impala里面,一个Query是分配到多个节点执行的,我们把其中负责分配和协调这个Query执行的组件叫Coordinator;参与这个Query执行的每个节点叫backend instance,每个backend instance上面会执行一个或者多个PlanFragment。那么每个Query就对应一个Coordinator对象和多个backend instance,同时Coordinator中的query_profile_ 变量是用来统计这个query的执行的整个profile的。

Coordinator

这里首先生成Coordinator用于协调这个Query的执行,然后调用
Status?Coordinator::Exec(
const TUniqueId& query_id, TQueryExecRequest* request,
const TQueryOptions& query_options)
启动异步的执行过程:说白了这个Coordinator就是老板,把活(PlanFragment)都给各个下属(backend instance)安排好了,发出去,然后自己下班走人了,才不会等着下属干完了才走呢。因为老板早就安排好自己的秘书(ImpalaServer::Wait())去盯着结果呢。
这个函数里面最重要的两个步骤:

  • ComputeScanRangeAssignment(*request);
  • ComputeFragmentExecParams(*request);

其中ComputeScanRangeAssignment(const TQueryExecRequest& exec_request)?用于填充std::vector scan_range_assignment_ 这个数组是以PlanFragment为索引的。
typedef boost::unordered_map FragmentScanRangeAssignment表示某个PlanFragment的backend instance以及其对应的PerNodeScanRanges的映射。而PerNodeScanRanges表示某个PlanFragment所涉及到的所有PlanNode到ScanRange的映射。

另外一个函数ComputeFragmentExecParams?(const TQueryExecRequest& exec_request)?用于填充std::vector fragment_exec_params_?。这个参数中每个FragmentExecParams对应着一个PlanFragment执行中用到的参数。

  • Status Coordinator::ComputeFragmentHosts(const TQueryExecRequest& exec_request):为每个PlanFragment找到执行所在的backend instance。如果一个PlanFragment是UNPARTITIONED,那么就在这个Coordinator所在的host上运行;如果一个PlanFragment含有ScanNode,那么就调度这个PlanFragment到HDFS/HBase数据块所在的那些DataNodes上,也就是这些DataNodes就成为了执行这个Query的backend instance。
  • 计算TQueryExecRequest.fragments中每个PlanFragment会在哪些hosts上得到执行,填充到fragment_exec_params_ 中。
  • 依次给每个PlanFragment执行的每个host分配一个instance_id。
  • 填充每个?FragmentExecParams?的destinations(即Data Sink的目的地PlanFragment)和per_exch_num_senders(这个ExchangeNode会接收来自多少个PlanFragment的数据)

回到Coordinator::Exec()函数中,下面就该把各个PlanFragment分配干活了。

  • 如果有Coordinator PlanFragment,那么先new PlanFragmentExecutor()生成这个PlanFragment所对应的PlanFragmentExecutor。然后填充其对应的TExecPlanFragmentParams。
  • 下面是个双层循环:外层遍历PlanFragment,内层遍历backend instance,生成与每个instance关联的BackendExecState(主要是生成TExecPlanFragmentParams用于Coordinator与多个backend instance交互时的参数),并加入backend_exec_states_列表,用于Coordinator对所有的backend instance执行状况的管理。然后向每个instance发起RPC请求开始执行,请求协议是ImpalaInternalService:: ExecPlanFragment(TExecPlanFragmentParams)

Status fragments_exec_status = ParallelExecutor::Exec(
bind(mem_fn(&Coordinator::ExecRemoteFragment), this, _1),
reinterpret_cast(&backend_exec_states_[backend_num - num_hosts]),
num_hosts);

每个Coordinator,PlanFragmentExecutor和ExecNode都会有一个RuntimeProfile,所有的RuntimeProfile会构成树状结构来记录每个执行节点的执行过程中的信息。
在Coordinator有个成员变量boost::scoped_ptr query_profile_用于表示这个query过程中的所有的profile信息。
每个Coordinator还有个aggregate_profile_专门负责aggregate相关的profile。

PlanFragmentExecutor和ExecNode

无论是在Coordinator端还是在backend instance端执行的PlanFragment都是由一个PlanFragmentExecutor控制的。下面我们看看PlanFragment在backend instance是怎么执行的?
在RPC的server端调用了ImpalaServer::ExecPlanFragment()->ImpalaServer::StartPlanFragmentExecution()
生成FragmentExecState里面含有一个PlanFragmentExecutor。那么下面就是分析PlanFragmentExecutor怎么控制Query的执行的了。

  • FragmentExecState::Prepare()调用PlanFragmentExecutor::Prepare()
  • FragmentExecState::Exec()调用PlanFragmentExecutor::Open(),这个是PlanFragment执行的主循环,block直到该PlanFragment执行结束。

真正控制PlanFragment执行的是PlanFragmentExecutor,主要由Prepare()/Open()/GetNext()/Close()这几个函数组成。

1,? PlanFragmentExecutor::Prepare(TExecPlanFragmentParams):准备执行,主要流程如下:

  • 设定这个query能够使用的内存mem_limit;
  • DescriptorTbl::Create():初始化descriptor table;
  • ExecNode::CreateTree():生成执行树的结构(父子关系)。执行树由ExecNode组成,每一个ExecNode也提供了Prepare(), Open(), GetNext()函数。后面执行ExecNode::Prepare/Open/GenNext /EvalConjuncts/Close函数都是按照这个树状结构递归下去的。初始化完成后,PlanFragmentExecutor ::plan_指向了执行树的根节点。在这棵树中,root节点被最后执行,叶子节点被最先执行;
  • 设置该PlanFragment的Exchange Node会接收来自多少个sender的数据;
  • 调用plan_->Prepare():从根节点开始递归初始化执行树,主要是初始化runtime_profile等统计信息和conjuncts的LLVM本地代码生成 (adding functions to the LlvmCodeGen object);
  • 如果使用本地代码生成,调用runtime_state_->llvm_codegen()->OptimizedModule()进行优化;
  • 把所有的ScanNode对应的Scan Range映射到file/offset/length;
  • DataSink::CreateDataSink();
  • set up profile counter;
  • 生成RowBatch用于存储结果。

2,PlanFragmentExecutor::Open()

先是start the profile-reporting thread,然后调用OpenInternal()

(1)???? 调用plan_->Open()沿着生成的ExecNode执行树依次调用ExecNode:: Open()
下面以HdfsScanNode::Open()为例说明:

  • 调用DiskIoMgr:: RegisterReader初始化与HDFS的连接hdfs_connection_;
  • 把要读取的File 和Split加入HdfsScanNode的队列queued_ranges_中;
  • 调用HdfsScanNode::DiskThread驱动HdfsScanNode::StartNewScannerThread()->HdfsScanNode::ScannerThread->HdfsScanner:: ProcessSplit()去读取数据(目前一个scanner thread只能读取一个scan range);
  • 调用IssueQueuedRanges()把上面加入queued_ranges_中的预读取Range发送给DiskIoMgr。由于上一步中已经启动了disk thread,所以就可以读取数据了。

(2)???? 如果当前这个PlanFragmen有sink,那么需要把这个PlanFragment要发给其他PF的数据都发出去。在发出去之前肯定得获取要发的东西吧,调用PlanFragmentExecutor ::GetNextInternal()从上到下递归调用执行树的ExecNode::GetNext()获取执行结果。
上面说到对于ExecNode::Open()不同种类的ExecNode的逻辑是不一样的,对于GetNext()也是一样的,可以参考下HdfsScanNode::GetNext()或者HashJoinNode::GetNext()看看具体是怎么获取查询结果的。

3,? PlanFragmentExecutor::GextNext(RowBatch** batch)

显示触发执行树的ExecNode::GetNext()函数获取查询结果。当其标记PlanFragmentExecutor::done_==true时,则表明所有数据已经被处理完,该PlanFragmentExecutor可以退出了。

至此,impala-backend也分析完了。总的来说impala在执行过程中和MapReduce及Hive的不同可以概括为一拉一推。

  • 在MapReduce中,Map的输出结果要等着Reduce去拉;而impala中各个PlanFragment执行结束之后DataSink是推送到其他PlanFragment的。这样能更加有效利用带宽,加快Job执行速度。
  • 在Hive中,逻辑上下游节点是由上游节点推送给下游节点的;而impala中是下游节点通过递归调用GetNext()向上游节点拉取的。
Kenyataan
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Linux下更新curl版本教程!Linux下更新curl版本教程!Mar 07, 2024 am 08:30 AM

在Linux下更新curl版本,您可以按照以下步骤进行操作:检查当前curl版本:首先,您需要确定当前系统中安装的curl版本。打开终端,并执行以下命令:curl--version该命令将显示当前curl的版本信息。确认可用的curl版本:在更新curl之前,您需要确定可用的最新版本。您可以访问curl的官方网站(curl.haxx.se)或相关的软件源,查找最新版本的curl。下载curl源代码:使用curl或浏览器,下载您选择的curl版本的源代码文件(通常为.tar.gz或.tar.bz2

如何使用MySQL数据库进行预测和预测分析?如何使用MySQL数据库进行预测和预测分析?Jul 12, 2023 pm 08:43 PM

如何使用MySQL数据库进行预测和预测分析?概述:预测和预测分析在数据分析中扮演着重要角色。MySQL作为一种广泛使用的关系型数据库管理系统,也可以用于预测和预测分析任务。本文将介绍如何使用MySQL进行预测和预测分析,并提供相关的代码示例。数据准备:首先,我们需要准备相关的数据。假设我们要进行销售预测,我们需要具有销售数据的表。在MySQL中,我们可以使用

如何使用 Go 语言进行数据可视化分析?如何使用 Go 语言进行数据可视化分析?Jun 10, 2023 am 10:46 AM

随着大数据时代的到来,数据可视化分析在各行各业中扮演着至关重要的角色。而Go语言作为一种快速、高效、安全的编程语言,也逐渐在数据可视化分析领域占据一席之地。本文将探讨如何使用Go语言进行数据可视化分析。一、Go语言常用的数据可视化库Plotly:可用于在浏览器中创建交互式的图形,支持多种图形类型,如线图、条形图、散点图、热力图等。Gonum/plo

Linux下的实时日志监控与分析Linux下的实时日志监控与分析Jul 29, 2023 am 08:06 AM

Linux下的实时日志监控与分析在日常的系统管理和故障排查中,日志是一个非常重要的数据来源。通过对系统日志的实时监控和分析,我们可以及时发现异常情况并进行相应的处理。本文将介绍Linux下如何进行实时日志监控和分析,并提供相应的代码示例。一、实时日志监控在Linux下,最常用的日志系统是rsyslog。通过配置rsyslog,我们可以实现将不同应用程序的日志

统计分析法的步骤统计分析法的步骤Jun 28, 2023 pm 03:27 PM

统计分析,常指对收集到的有关数据资料进行整理归类并进行解释的过程。统计分析的基本步骤包括:1、收集数据;2、整理数据;3、分析数据。

java源码怎么查看java源码怎么查看Dec 27, 2023 pm 04:41 PM

查看步骤:1、找到安装目录或者在线查看;2、解压源代码;3、使用文本编辑器或集成开发环境;4、导航和查看源码。详细介绍:1、找到安装目录或者在线查看:如果安装了JDK,可以在JDK的安装目录中找到Java的源代码。在JDK的安装目录中,通常有一个 src.zip 或类似的压缩文件,里面包含了 Java 核心类库的源代码;在线查看Java源代码也是可能的等等。

Linux内核源代码存放路径解析Linux内核源代码存放路径解析Mar 14, 2024 am 11:45 AM

Linux内核是一个开源的操作系统内核,其源代码存储在一个专门的代码仓库中。在本文中,我们将详细解析Linux内核源代码的存放路径,并通过具体的代码示例来帮助读者更好地理解。1.Linux内核源代码存放路径Linux内核源代码存储在一个名为linux的Git仓库中,该仓库托管在[https://github.com/torvalds/linux](http

如何使用PHP进行性能分析和调优如何使用PHP进行性能分析和调优Jun 06, 2023 pm 01:21 PM

作为一种流行的服务端语言,PHP在网站开发和运行中扮演着重要的角色。然而,随着PHP代码量的不断增加和应用程序的复杂性提高,性能瓶颈也越来越容易出现。为了避免这种问题,我们需要进行性能分析和调优。本文将简单介绍如何使用PHP进行性能分析和调优,为您的应用程序提供更高效的运行环境。一、PHP性能分析工具1.XdebugXdebug是一款广泛使用的代码分析工具,

See all articles

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Alat panas

PhpStorm versi Mac

PhpStorm versi Mac

Alat pembangunan bersepadu PHP profesional terkini (2018.2.1).

Dreamweaver Mac版

Dreamweaver Mac版

Alat pembangunan web visual

SecLists

SecLists

SecLists ialah rakan penguji keselamatan muktamad. Ia ialah koleksi pelbagai jenis senarai yang kerap digunakan semasa penilaian keselamatan, semuanya di satu tempat. SecLists membantu menjadikan ujian keselamatan lebih cekap dan produktif dengan menyediakan semua senarai yang mungkin diperlukan oleh penguji keselamatan dengan mudah. Jenis senarai termasuk nama pengguna, kata laluan, URL, muatan kabur, corak data sensitif, cangkerang web dan banyak lagi. Penguji hanya boleh menarik repositori ini ke mesin ujian baharu dan dia akan mempunyai akses kepada setiap jenis senarai yang dia perlukan.

DVWA

DVWA

Damn Vulnerable Web App (DVWA) ialah aplikasi web PHP/MySQL yang sangat terdedah. Matlamat utamanya adalah untuk menjadi bantuan bagi profesional keselamatan untuk menguji kemahiran dan alatan mereka dalam persekitaran undang-undang, untuk membantu pembangun web lebih memahami proses mengamankan aplikasi web, dan untuk membantu guru/pelajar mengajar/belajar dalam persekitaran bilik darjah Aplikasi web keselamatan. Matlamat DVWA adalah untuk mempraktikkan beberapa kelemahan web yang paling biasa melalui antara muka yang mudah dan mudah, dengan pelbagai tahap kesukaran. Sila ambil perhatian bahawa perisian ini

MinGW - GNU Minimalis untuk Windows

MinGW - GNU Minimalis untuk Windows

Projek ini dalam proses untuk dipindahkan ke osdn.net/projects/mingw, anda boleh terus mengikuti kami di sana. MinGW: Port Windows asli bagi GNU Compiler Collection (GCC), perpustakaan import yang boleh diedarkan secara bebas dan fail pengepala untuk membina aplikasi Windows asli termasuk sambungan kepada masa jalan MSVC untuk menyokong fungsi C99. Semua perisian MinGW boleh dijalankan pada platform Windows 64-bit.