搜索
首页数据库mysql教程Impala源代码分析(1)-Impala架构和RPC

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捆绑的是不一样的,所以就形成了service和backend一对多的关系,这个关系存储在StateStore.service_instances_组。

(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

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系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

热AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热工具

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器

DVWA

DVWA

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

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SecLists

SecLists

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

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)