select jobinfo.dt,user,
max(taskinfo.finish_time-taskinfo.start_time),
max(jobinfo.finish_time-jobinfo.submit_time)
from taskinfo join jobinfo on jobinfo.jobid=taskinfo.jobid
where jobinfo.job_status='SUCCESS' and taskinfo.task_status='SUCCESS'
group by jobinfo.dt,user
通过调用Status ImpalaServer::GetExecRequest(const TClientRequest& request, TExecRequest* result) 函数把TClientRequest转化成TExecRequest
在这个函数里通过JNI接口调用frontend.createExecRequest()生成TExecRequest。首先调用AnalysisContext.analyze(String stmt)分析提交的SQL语句。
注释:Analyzer对象是个存放这个SQL所涉及到的所有信息(包含Table, conjunct, slot,slotRefMap, eqJoinConjuncts等)的知识库,所有跟这个SQL有关的东西都会存到Analyzer对象里面。
1,SQL的词法分析,语法分析
AnalysisContext.analyze(String stmt)会调用SelectStmt.analyze()函数,这个函数就是对SQL的analyze和向中央知识库Analyzer register各种信息。
(1)处理这个SQL所涉及到的Table(即TableRefs),这些Table是在from从句中提取出来的(包含关键字from, join, on/using)。注意JOIN操作以及on/using条件是存储在参与JOIN操作的右边的表的TableRef中并分析的。依次analyze()每个TableRef,向Analyzer注册registerBaseTableRef(填充TupleDescriptor)。如果对应的TableRef涉及到JOIN操作,还要analyzeJoin()。在analyzeJoin()时会向Analyzer registerConjunct()填充Analyzer的一些成员变量:conjuncts,tuplePredicates(TupleId与conjunct的映射),slotPredicates(SlotId与conjunct的映射),eqJoinConjuncts。本例中on从句是一种BinaryPredicate,然后onClause.analyze(analyzer)会递归analyze这个on从句里的各种组件。
(2)处理select从句(包含关键字select, MAX(), AVG()等聚集函数):分析这个SQL都select了哪几项,每一项都是个Expr类型的子类对象,把这几项填入resultExprs数组和colLabels。然后把resultExprs里面的Expr都递归analyze一下,要分析到树的最底层,向Analyzer注册SlotRef等。
(3)分析where从句(关键字where),首先递归Analyze从句中Expr组成的树,然后向Analyzer registerConjunct()填充Analyzer的一些成员变量(同1,此外还要填充whereClauseConjuncts) 。
(4)处理sort相关信息(关键字order by)。先是解析aliases和ordinals,然后从order by后面的从句中提取Expr填入orderingExprs,接着递归Analyze从句中Expr组成的树,最后创建SortInfo对象。
(5)处理aggregation相关信息(关键字group by, having, avg, max等)。首先递归分析group by从句里的Expr,然后如果有having从句就像where从句一样,先是analyze having从句中Expr组成的树,然后向Analyzer registerConjunct()等。
(6)处理InlineView。
关于SQL解析中所涉及到的各种数据结构表示如下:
至此词法分析,语法分析结束,有点像一个小的编译器。我们现在回到frontend.createExecRequest()函数中。调用完AnalysisContext.analyze()之后,就开始填充TExecRequest内的成员变量。
(1)如果是DDL命令(use, show tables, show databases, describe),那么调用createDdlExecRequest();
(2)另外一种情况就是Query或者DML命令,那么就得创建和填充TQueryExecRequest了。
2,根据SQL语法树生成执行计划(PlanNode和PlanFragment的生成)
下面就是用Planner把SQL解析出的语法树转换成Plan fragments,后者能在各个backend被执行。
Planner planner = new Planner();
ArrayListfragments =
planner.createPlanFragments(analysisResult, request.queryOptions);
这个createPlanFragments()函数是frontend最重要的函数:根据SQL解析的结果和client传入的query options,生成执行计划。执行计划是用PlanFragment的数组表示的,最后会序列化到TQueryExecRequest.fragments然后传给backend的coordinator去调度执行。
下面进入Planner.createPlanFragments()函数看看执行计划是怎么生成的:
首先要搞清楚两个概念:PlanNode和PlanFragment。
PlanNode是SQL解析出来的逻辑功能节点;PlanFragment是真正的执行计划节点。
2.1,创建PlanNode
PlanNode singleNodePlan =
createQueryPlan(queryStmt, analyzer, queryOptions.getDefault_order_by_limit());
(1)这个函数首先根据from从句中的第一个TableRef创建一个PlanNode,一般为ScanNode(HdfsScanNode或者HBaseScanNode)。这个ScanNode关联一个ValueRange的数组(由多个cluster column取值区间组成)表示要读取的Table的范围,还关联一个conjunct(where从句)。
(2)这个SQL语句中TableRef中剩下的其他Table就需要建立HashJoinNode了。进入Planner.createHashJoinNode()函数:首先为这个Table建立ScanNode(同上),然后调用getHashLookupJoinConjuncts()获取两表或者多表JOIN的eqJoinConjuncts和eqJoinPredicates,利用这两个条件创建HashJoinNode。每个HashJoinNode也是树状的,会有孩子节点,对于我们举例的两表JOIN,孩子节点分别是两个表对应的ScanNode。(注意目前impala只支持一大一小两个表的JOIN,默认是左大右小,是通过把右边的小表分发到每个节点的内存中分别于左边大表的一个区间进行JOIN过滤实现的。)
(3)如果有group by从句,创建AggregationNode,并把刚才的HashJoinNode设为它的孩子。这里暂时不考虑DISTINCT aggregation function。
(4)如果有order by… limit从句,创建SortNode。
这样createQueryPlan()函数执行完毕,PlanNode组成的execution tree形成如下:
2.2,创建PlanFragment
接下来就看impala backend节点数目有多少,如果只有一个节点,那么整棵执行树都在同一个impalad上执行;否则调用createPlanFragments(singleNodePlan, isPartitioned, false, fragments)把PlanNode组成的执行树转换成PlanFragment组成的执行计划。
下面进入createPlanFragments()这个函数:
这是一个递归函数,沿着PlanNode组成的执行树递归下去,分别创建对应的Fragment。
(1)如果是ScanNode,创建一个PlanFragment(这个PlanFragment的root node是这个ScanNode,而且这个PlanFragment只包含一个PlanNode)。
(2)如果是HashJoinNode,并不是创建一个新的PlanFragment,而是修改leftChildFragment(是一个ScanNode)为以HashJoinNode作为root node的PlanFragment。因为对于HashJoinNode一般有两个ScanNode孩子,在处理HashJoinNode之前已经把这两个ScanNode变成了对应的PlanFragment。那么此时要得到HashJoinNode作为root node的PlanFragment是通过Planner.createHashJoinFragment()函数完成的:首先把当前HashJoinNode作为HashJoinFragment的root node;然后把leftChildFragment中的root PlanNode(也就是参与JOIN的两个表中左边的那个表对应的ScanNode)作为HashJoinNode的左孩子;通过调用Planner.connectChildFragment()函数把HashJoinNode的右孩子设置为一个ExchangeNode(这个ExchangeNode表示一个1:n的数据流的receiver);同时把rightChildFragment(ScanNode作为root node)的destination设置为这个ExchangeNode。
(3)如果是AggregationNode,聚集操作很复杂了。以我们的例子来说明:如果这个AggregationNode不是DISTINCT aggregation的2nd phase(因为本例中的AggregationNode的孩子是HashJoinNode而不是另外一个AggregationNode),首先把刚才生成的HashJoinNode作为root node对应的PlanFragment的root node设置为该AggregationNode,并把原来的root node(即HashJoinNode)设为新root node的孩子。然后通过Planner.createParentFragment()创建一个包含ExchangeNode作为root node的新的PlanFragment。并把孩子PlanFragment的destination设置为这个ExchangeNode。然后在这个新的PlanFragment中创建一个新的AggregationNode作为新的root node并把刚才的ExchangeNode作为其孩子节点。
至此,createPlanFragments()调用完成,生成的三个PlanFragment如下:
通过createPlanFragments(singleNodePlan, isPartitioned, false, fragments)获取了所以执行计划PlanFragment组成的数组fragments,这个数组的最后一个元素就是根节点PlanFragment。然后就是调用PlanFragment.finalize()把这个执行计划finalize(递归finalize每个PlanNode)同时为每个PlanFragment指定 DataStreamSink。
然后回到frontend.createExecRequest()函数中。执行完Planner.createPlanFragments()返回的ArrayList就是完整的执行计划了。然后就是一次调用PlanFragment.toThrift()把它序列化到TQueryExecRequest。填充TQueryExecRequest的相关变量:dest_fragment_idx,per_node_scan_ranges,query_globals,result_set_metadata等。最后返回TExecRequest型的对象给backend执行。
Impala-backend(C++代码)拿到这个TExecRequest对象,有coordinator在各个backend之间分发执行,这是下一篇文章的内容了。
吐槽:从中还是能够看到MapReduce的影子的。。。对于每个PlanFragment有个DataStreamSink,会指向其他PlanFragment中的ExchangeNode,是个1对N的关系。。。所以分布式系统的瓶颈还是Data Shuffle,不管是MapReduce模型还是impala。这也说明其实Tez/Stinger Initiative 对Hive的优化还是很值得期待的。
参考文献:http://blog.csdn.net/wind5shy/article/details/8563355
7 RepliesImpala的SQL解析与执行计划生成部分是由impala-frontend(Java)实现的,监听端口是21000。用户通过Beeswax接口BeeswaxService.query()提交一个请求,在impalad端的处理逻辑是由void ImpalaServer::query(QueryHandle& query_handle, const Query& que
PHP Thrift
SQL
Thrift
SQL.phar存档旨在提供对PHP
SQL-on-Hadoop框架的访问。 它将Thrift和各种服务包捆绑在一起,并公开了用于在各种框架上运行查询的通用接口。
当前支持以下引擎:
蜂巢-在HiveServer2节俭接口,SASL默认情况下启用,因此用户名和密码,必须提供然而,这可以通过关闭setSasl()方法调用之前connect()
Impala-通过
Impala Service Thrift接口扩展了Beeswax协议。
版本兼容性
该库当前针对以下数据库版本的Thrift定义进行编译:
Apache Hive 1.1.0 ( )
Apache
Impala 2.12.0 ( )
使用以下编译器和基本PHP类:
Apache Thrift 0.12.0 ( )
推荐的使用此库的方法是通过高效内存的迭代器从Hive /
Impala获取结果,该迭代器将保持连接打开并一次在结果中滚动几行。 这允许一次处理一个大型记录的大型结果数据集,从而最大限度地减少了PHP的内存消耗。
// Load this lib
dt-sql-parser
English |
dt-sql-parser是使用构建的SQL Parser项目,主要用于BigData域。 生成了基本的Parser,Visitor和Listener,因此很容易完成语法验证, tokenizer ,遍历AST等功能。
此外,它提供了一些辅助方法,例如拆分SQL,并在SQL中过滤--和/**/类型的注释。
支持SQL:
MySQL
Flink SQL
Spark SQL
Hive SQL
PL / SQL
提示:该项目是Javascript语言的默认项目,如果需要,您也可以尝试将其编译为其他语言。
// use npm
npm i dt-sql-parser --save
// use yarn
yarn add dt-sql-parser
首先,我们需要从dt-sql-parser导入Parser对象
手把手视频详细讲解项目开发全过程,需要的小伙伴自行百度网盘下载,链接见附件,永久有效。
从零开始讲解大数据分布式计算的发展及Impala的应用场景,对比Hive、MapReduce、Spark等类似框架讲解内存式计算原理,基于Impala构建高性能交互式SQL分析平台
1,知识体系完备,从小白到大神各阶段读者均能学有所获。
2,生动形象,化繁为简,讲解通俗易懂。
3,结合工作实践及分析应用,培养解决实际问题的能力。
4,每一块知识点, 都有配套案例, 学习不再迷茫。
1、对大数据感兴趣的在校生及应届毕业生。
2、对目前职业有进一步提升要求,希望从事大数据行业高薪工作的在职人员。
3、对大数据行业感兴趣的相关人员。
第一章:内存式计算发展
1.分布式计算的发展
2.大数据分布式计算分类
3.Impala内存式计算诞生
第二章:Impala原理初探
1.Impala的设计思想
2.Impala与Hive之间的联系
3.Impala的分布式架构详解
4.Impala角色概念详解
第三章:基于Cloudera镜像部署分布式Impala
1.基于CDH5.14构建本地Yum镜像
2.企业级分布式Impala部署
3.企业级配置与Hadoop集成
4.企业级配置与Hive集成
5.主从架构及元数据服务管理
第四章:Impala企业实战开发案例
1.基于企业案例实现Impala集群管理
2.Impala最全SQL语法详解
3.实战开发Impala数据库与表管理
4.基于分析案例实现Impala数据管理
5.Impala与应用系统集成JDBC
第五章:Impala原理深入
1.Impala各角色功能详解
2.Impala任务提交原理
3.Impala元数据同步原理
随着大数据时代的到来,Hadoop在过去几年以接近统治性的方式包揽的ETL和数据分析查询的工作,大家也无意间的想往大数据方向靠拢,即使每天数据也就几十、几百M也要放到Hadoop上作分析,只会适得其反,但是当面对真正的BigData的时候,Hadoop就会暴露出它对于数据分析查询支持的弱点。甚至出现《MapReduce:一个巨大的倒退》此类极端的吐槽,这也怪不得Hadoop,毕竟它的设计就是为了批处理,使用用MR的编程模型来实现SQL查询,性能肯定不如意。所以通常我也只是把Hive当做能够提供将SQL语义转换成MR任务的工具,尤其在做ETL的时候。在Dremel论文发表之后,开源社区涌现出了一
一.WITH AS的含义
WITH AS短语,也叫做子查询部分(subquery factoring),可以让你做很多事情,定义一个SQL片断,该SQL片断会被整个SQL语句所用到。有的时候,是为了让SQL语句的可读性更高些,也有可能是在UNION ALL的不同部分,作为提供数据的部分。
特别对于UNION ALL比较有用。因为UNION ALL的每个部分可能相同,但是如果每个部
在一张hive表中 存储了自身关联自身两键值 即: 当前id(newid) 和 原先id (oldid);
每一个 newid 和 oldid 两id有可能 关联本表中 其他的id
现有需求找到 最后newid 和 最早oldid 使其一一对应
网上有sqlserver 等关系型数据库的递归说明大抵就是利用with as 建立子表 自身调用自身实现递归,但是hive中不支持这种方式,
后来想使用datax 提交代码到sqlserver运行,运行即结果直接传输到建立的hive表中,
#修改分隔符
alter table firstround.person_aaa_crime_criminalperson1 set SERDEPROPERTIES('field.delim'='\001');
#查看建表语句
show CREATE TABLE firstround.banklog_decrypt
#修改字段类型
ALTER TABLE data_market.last_p...
current_timestamp()
–当前时间戳相对于 linux epoch 的秒数
unix_timestamp() , 不带参数, 则返回 ‘1970-01-01 00:00:00’ UTC 到现在的秒数
– 转换到相对于 linux epoch 的秒数
unix_timestamp(now()+ interval 3 days), 如果传入 tim...
0x02 简介
Impala是一个开源的关系型查询引擎,执行查询SQL。数据是追加式的,没有修改和删除。
Impala属于MPP架构,查询分布在多个节点中执行,拥有并行查询能力(每个节点,每个集群)。
Impala是一个编译器,他依赖HDFS,使用外部元数据:hive metastore
SQL on Hadoop是指在Hadoop生态系统中使用SQL查询和分析大数据。在这个生态系统中,有多种SQL引擎可供选择,包括Hive、Spark SQL和Impala。这些引擎在性能上有所不同。
Hive是Hadoop生态系统中最早的SQL引擎之一。它使用Hadoop MapReduce作为执行引擎,因此它的查询速度相对较慢。但是,Hive具有广泛的生态系统支持和易于使用的接口,因此它仍然是许多企业的首选。
Spark SQL是一个基于Spark的SQL引擎,它使用Spark的内存计算引擎来加速查询。相对于Hive,Spark SQL的查询速度更快,特别是在处理大型数据集时。此外,Spark SQL还支持许多高级功能,如机器学习和图形处理。
Impala是一个基于内存的SQL引擎,它专门为快速查询大型数据集而设计。Impala的查询速度比Hive和Spark SQL都要快,特别是在处理大型数据集时。但是,Impala的生态系统支持相对较少,因此它可能不适合所有企业。
总的来说,选择哪个SQL引擎取决于企业的具体需求和数据规模。如果需要广泛的生态系统支持和易于使用的接口,则Hive可能是最好的选择。如果需要快速查询大型数据集,则Impala可能是最好的选择。如果需要高级功能和快速查询速度,则Spark SQL可能是最好的选择。