Impala总共分为3个组件:impalad, statestored, client/impala-shell。关于这三个组件的基本功能在这篇文章中已经介绍过了。 Client?: 可以是Python CLI(官方提供的impala_shell.py),JDBC/ODBC或者Hue。无论哪个其实就是一个Thrift的client,连接到impala
Impala总共分为3个组件:impalad, statestored, client/impala-shell。关于这三个组件的基本功能在这篇文章中已经介绍过了。
Client?: 可以是Python CLI(官方提供的impala_shell.py),JDBC/ODBC或者Hue。无论哪个其实就是一个Thrift的client,连接到impalad的21000端口。
Impalad: 分为frontend和backend两部分,这个进程有三个ThriftServer(beeswax_server, hs2_server, be_server)对系统外和系统内提供服务。
Statestored: 集群内各个backend service的数据交换中心,每个backend会在statestored注册,以后statestored会与所有注册过的backend交换update消息。
RPC
Component | Service | Port | Access Requirement | Comment |
ImpalaDaemon | Impala Daemon Backend Port | 22000 | Internal | ImpalaBackendService export |
Impala Daemon Frontend Port | 21000 | External | ImpalaService export | |
Impala Daemon HTTP Server Port | 25000 | External | Impala debug web server | |
StateStoreSubscriber Service Port | 23000 | Internal | StateStoreSubscriberService | |
?ImpalaStateStore Daemon | StateStore HTTP Server Port | 25010 | External | StateStore debug web server |
StateStore Service Port | 24000 | Internal | StateStoreService export |
下面介绍三个组件之间的Thrift RPC(“”前面的表示RPC client,“”后面的表示RPC server)
(1)Client impalad(frontend)
BeeswaxService(beeswax.thrift): client通过query()提交SQL请求,然后异步调用get_state()监听该SQL的查询进度,一旦完成,调用fetch()取回结果。
TCLIService(cli_service.thrift): client提交SQL请求,功能和上面类似,更丰富的就是对DDL操作的支持,例如GetTables()返回指定table的元数据。
ImpalaService和ImpalaHiveServer2Service(ImpalaService.thrift)分别是上面两个类的子类,各自丰富了点功能而已,核心功能没啥大变化。
(2)Impalad(backend) statestored
StateStoreService(StateStoreService.thrift): statestored保存整个系统所有backend service状态的全局数据库,这里是个单节点中央数据交换中心(该节点保存的状态是soft state,一旦宕机,保存的状态信息就没了)。例如每个impala backend启动的时候会调用StateStoreService.RegisterService()向statestored注册自己(其实是通过跟这个backend service捆绑在一起的StateStoreSubscriber标识的),然后再调用StateStoreService.RegisterSubscription()表明这个StateStoreSubscriber接收来自statestored的update。
(3)Statestord impalad(backend)
StateStoreSubscriberService(StateStoreSubscriberService.thrift): backend向statestored调用RegisterSubscription之后,statestored就会定期向backend这边捆绑的StateStoreSubscriber发送该backend的状态更新信息。然后backend这边调用StateStoreSubscriberService.UpdateState()更新相关状态。同时这个UpdateState()调用在impalad backend/StateStoreSubscriber这端还会返回该backend的一些update信息给statestored。
(4)Impalad(backend) other impalad(backend) (这两个是互为client/server的)
ImpalaInternalService(ImpalaInternalService.thrift):某个backend的coordinator要向其他backend的execute engine发送执行某个plan fragment的请求(提交ExecPlanFragment并要求返回ReportExecStatus)。这部分功能会在backend分析中详细讨论。
(5)Impalad backend other frontend
ImpalaPlanService(ImpalaPlanService.thrift):可以由其他形式的frontend生成TExecRequest然后交给backend执行。
另外,Impala frontend是用Java写的,而backend使用C++写的。Frontend负责把输入的SQL解析,然后生成执行计划,之后通过Thrift的序列化/反序列化的方式传给backend。TExecRequest(frontend.thrift)是中间传输的数据结构,表示了一个Query/DML/DDL的查询请求,也是SQL执行过程中在frontend和backend之间的数据接口。所以我们可以把impala-frontend换掉,用其他的形式拼凑出这个TExecRequest就可以传给backend执行,这也就是前面说的ImpalaPlanService干的事。
impala组件执行流程
1, impala-shell
client就可以通过Beeswax和HiveServer2的Thrift API向Impala提交query。这两种访问接口的作用是一样的(都是用于client提交query,返回query result)。
Impala_shell.py是通过Beeswax方式访问impala的,下面我们看看impala_shell.py是怎么向impalad提交query的。
(1)通过OptionParser()解析命令行参数。如果参数中有—query或者—query_file,则执行execute_queries_non_interactive_mode(options),这是非交互查询(也就是就查询一个SQL或者一个写满SQL的文件);否则进入ImpalaShell.cmdloop (intro)循环。
(2)进入命令行循环后,一般是先connect某一个impalad,输入”connect localhost:21000”,进入do_connect(self, args)函数。这个函数根据用户指定的host和port,生成与相应的impalad的socket连接。最重要的就是这行代码:
self.imp_service = ImpalaService.Client(protocol)
至此imp_service就是client端的代理了,所有请求都通过它提交。
(3)下面以select命令为例说明,如果client输入这样的命令”select col1, col2 from tbl”,则进入do_select(self, args)函数。在这个函数里首先生成BeeswaxService.Query对象,向这个对象填充query statement和configuration。然后进入__query_with_result()函数通过imp_service.query(query)提交query。注意ImpalaService都是异步的,提交之后返回一个QueryHandle,然后就是在一个while循环里不断__get_query_state()查询状态。如果发现这个SQL的状态是FINISHED,那么就通过fetch() RPC获取结果。
2, statestored
Statestored进程对外提供StateStoreService RPC服务,而StateStoreSubscriberService RPC服务是在impalad进程中提供的。StateStoreService这个RPC的逻辑实现是在StateStore这个类里面实现的。
Statestored收到backend发送的RegisterService RPC请求时,调用StateStore::RegisterService()处理,主要做两件事:
(1)根据TRegisterServiceRequest提供的service_id把该service加入StateStore.service_instances_。
通常在整个impala集群只存在名为“impala_backend_service”这一个服务,所以service_id=”impala_backend_service”。而每个backend捆绑的
(2)Impalad backend在向statestored RegisterService的时候,会把subscriber_address发送过去。在statestored端,会根据这个subscriber_address生成对应的Subscriber对象(表示与该Subscriber捆绑的backend)。把与该backend绑定的Subscriber加入StateStore.subscribers_这个map里。每个Subscriber有个唯一的id,这样分布在集群内的impala backend就有了全局唯一id了。
这样如果以后某个backend/StateStoreSubscriber fail或者其中运行的SQL任务出了问题,在statestored这里就会有体现了,那么就会通知给其他相关的backend。
那么每个backend是怎么update的呢?StateStore::UpdateLoop()负责定期向各个backend推送其所订阅的service的所有成员的更新,目前的更新策略是全量更新,未来会考虑增量更新。
3, impalad
Impalad进程的服务被wrapper在ImpalaServer这个类中。ImpalaServer包括fe和be的功能,实现了ImpalaService(Beeswax), ImpalaHiveServer2Service(HiveServer2)和ImpalaInternelService API。
全局函数CreateImpalaServer()创建了一个ImpalaServer其中包含了多个ThriftServer:
(1)创建一个名为beeswax_server的ThriftServer对系统外提供ImpalaService(Beeswax)服务,主要服务于Query查询,是fe/frontend的核心服务,端口21000
(2)创建一个名为hs2_server的ThriftServer对系统外提供ImpalaHiveServer2Service服务,提供Query, DML, DDL相关操作,端口21050
(3)创建一个名为be_server的ThriftServer对系统内其他impalad提供ImpalaInternalService,端口22000
(4)创建ImpalaServer对象,前面三个ThriftServer的TProcessor被赋值这个ImpalaServer对象,所以对前面三个Thrift服务的RPC请求都交由这个ImpalaServer对象处理。最典型的例子就是我们通过Beeswax接口提交了一个BeeswaxService.query()请求,在impalad端的处理逻辑是由void ImpalaServer::query(QueryHandle& query_handle, const Query& query)这个函数(在impala-beeswax-server.cc中实现)完成的。
下面是impalad-main.cc的主函数:
int main(int argc, char** argv) { //参数解析,开启日志(基于Google gflags和glog) InitDaemon(argc, argv); LlvmCodeGen::InitializeLlvm(); // Enable Kerberos security if requested. if (!FLAGS_principal.empty()) { EXIT_IF_ERROR(InitKerberos("Impalad")); } //因为frontend, HBase等相关组件是由Java开发的,所以下面这几行都是初始化JNI相关的reference和method id JniUtil::InitLibhdfs(); EXIT_IF_ERROR(JniUtil::Init()); EXIT_IF_ERROR(HBaseTableScanner::Init()); EXIT_IF_ERROR(HBaseTableCache::Init()); InitFeSupport(); //ExecEnv类是impalad backend上Query/PlanFragment的执行环境。 //生成SubscriptionManager, SimpleScheduler和各种Cache ExecEnv exec_env; //生成Beeswax, hive-server2和backend三种ThriftServer用于接收client请求,不过这三种服务的后端真正的处理逻辑都是ImpalaServer* server这个对象。 ThriftServer* beeswax_server = NULL; ThriftServer* hs2_server = NULL; ThriftServer* be_server = NULL; ImpalaServer* server = CreateImpalaServer(&exec_env, FLAGS_fe_port, FLAGS_hs2_port, FLAGS_be_port, &beeswax_server, &hs2_server, &be_server); //因为be_server是对系统内提供服务的,先启动它。 be_server->Start(); //这里面关键是启动了SubscriptionManager和Scheduler Status status = exec_env.StartServices(); if (!status.ok()) { LOG(ERROR) RegisterService(IMPALA_SERVICE_ID, host_port); unordered_set services; services.insert(IMPALA_SERVICE_ID); //注册callback函数,每当StateStoreSubscriber接收到来自statestored的update之后调用该函数。 cb.reset(new SubscriptionManager::UpdateCallback( bind(mem_fn(&ImpalaServer::MembershipCallback), server, _1))); exec_env.subscription_mgr()->RegisterSubscription(services, "impala.server", cb.get()); if (!status.ok()) { LOG(ERROR) Start(); hs2_server->Start(); beeswax_server->Join(); hs2_server->Join(); delete be_server; delete beeswax_server; delete hs2_server; }
exec_env.StartServices()调用SubscriptionManager.Start(),进一步调用StateStoreSubscriber.Start()启动一个ThriftServer。
StateStoreSubscriber实现了StateStoreSubscriberService(StateStoreSubscriberService.thrift中定义),用于接收来自statestored的update,并把与这个StateStoreSubscriber捆绑的backend的update反馈给statestored。这样这个backend就可以对其他backend可见,这样就可以接受其他impala backend发来的任务更新了(当然,接收backend更新是通过statestored中转的)。
参考文献:
http://www.sizeofvoid.net/wp-content/uploads/ImpalaIntroduction2.pdf
原文地址:Impala源代码分析(1)-Impala架构和RPC, 感谢原作者分享。

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

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

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

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

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

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

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


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

VSCode Windows 64位 下载
微软推出的免费、功能强大的一款IDE编辑器

DVWA
Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

记事本++7.3.1
好用且免费的代码编辑器

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)