《深入浅出Greenplum内核》系列直播以每月一场的速度持续推出中。在第一场《架构解读》直播里,我们了解了Greenplum的整体架构、存储管理、索引、查询执行、事务与日志等内容。今天(5月22日),第二场《Greenplum内核揭秘之执行引擎》也顺利播出啦!现在,我们来回顾一下直播演讲内容吧!

看完别忘了前往askGP做一下小测试(ask.greenplum.cn/exam)巩固一下所学的知识点哦!

感谢大家参加Greenplum的直播活动!在《深入浅出Greenplum内核》系列活动的第二场直播中,我们为大家详细介绍了Greenplum执行器内容,以及Greenplum为了完成执行计划而设计的两个特殊模块Dispatcher和Interconnect等内容。

执行器

首先我们先来了解一下什么是执行器。简单来讲,执行器是处理一个由执行计划节点组成的树,并返回查询结果。那么什么是执行计划节点呢?从本质上讲,一个执行计划节点,实际上就是一个数据处理节点。从下图可看到,在数据输入后,执行节点会对数据进行数据处理,然后返回数据作为输出。这些执行节点会被组织成树的形式。

下图是一个SELECT查询的执行计划树。通过优化器优化后,就会生成这样的树状结构,我们可以看到里面有四个执行节点,包括HashJoin节点,Hash节点,顺序扫描节点,所有的节点通过树的方式组织在一起,来表示各节点之间的数据流动或者顺序关系。  每一个计划节点包含足够多的元数据信息提供给执行器。

图中的Seq Scan被称为原发性的扫描节点,原发性的扫描节点是指,节点本身可以自己产生数据,而不依赖于其他节点;反之,非原发性扫描节点是需要子节点来为其提供数据,图中的Hash Join和Hash就是非原发性扫描节点。了解了原发性扫描节点和非原发性扫描节点的不同,就可以更好的理解后面的执行模型。

那么执行器是怎么执行生成的执行计划树呢?就需要利用执行模型了。面对这样的执行计划树时,处理方式其实很多,我们会根据包括每一个节点内的数据输入是怎么样的规定,输出有什么样的特点等不同的信息,会选择不同的执行模型。现在我们来介绍一下几种常见的执行模型。

执行模型

第一种是迭代模型,也被称为流式模型,或者是抽拉式模型。它的定义非常简单,每一个执行节点本质上就是一个next函数,我们会从一个树节点的根节点一直往下执行这个next 函数。next 函数的实现会遵循这样的特点:

  • 从输出角度看,next 函数的每一次调用,执行节点返回一个tuple,没有更多tuple的时候返回一个NULL。

  • 从输入的角度看,执行节点实现一个循环,每次调用子执行节点的next函数来获取它们的输出,并处理它们直到能返回一个tuple或者NULL。

  • 执行控制流方向是自上往下,不断抽拉的方式,由上层节点直接驱动下层节点来进行数据的驱动。而从数据流的角度来看,还是由上层节点往下层节点传输来完成。

这种执行模型的有点在于规则简单,易懂,资源使用少,通用性好,大部分的执行计划节点一般都可以用这种模式来实现。缺点也很显而易见,由于每次迭代只返回一个tuple,迭代次数多,代码局部性较差,同时对CPU cacheline也不是很友好。

向量化模型

第二种模型就是向量化模型,和迭代模型有一些相似之处,比如每一个执行节点实现一个next函数,但也有其不同之处。每一次迭代,执行节点返回一组tuple而非一个tuple,从而减少迭代次数,可以利用新的硬件特性如SIMD来加快一组tuple的处理。同时一组tuple在不同的节点之间传输,对列存也更加友好。执行节点实现一个循环,每次调用子执行节点的next函数来获取它们的输出,并能够批量的处理数据。执行控制流方向自上而下,采用pull的方式。

Push执行模型

第三种模型是目前比较热门的模型——PUSH执行模型。每一个执行节点定义两个函数

  • Produce函数

Produce函数:看起来像是一个执行节点tuple的生产函数,其实不然,对于非自主生产的执行节点,produce函数更像一个控制函数,它不做过多的生产的工作,想反它会立即调用子节点的produce函数。具有自主生产的执行节点(一般为叶子节点),其produce函数名副其实的生产tuple,并驱动父节点的consume函数提取数据。

  • Consume函数

Consume函数:被下层节点驱动调用,接收子节点数据,进行各种运算,并驱动其父节点的consume函数。

现在我们通过一个例子来看一下,下图中有三个节点,一个扫描节点,一个投影节点,一个Join 节点。每个节点都生成了两个函数,一个生产函数,一个消费函数。整个PUSH模型是怎么做的呢?图中的红框标注的为原发性的扫描节点,蓝框标注的是非原发性的扫描节点。非原发性的扫描节点中的生产函数并不做真正的生产工作,而更多是承担了控制工作,会调用它的子节点的生产函数。因此投影节点和Join节点会调用scan的生产函数。由于Scan是原发性的,因此会在生产并得到数据后,开始驱动数据的消耗。

PUSH模型是由下层的节点驱动上层的节点来完成的。数据流向也是自下而上的。下层驱动模型可以相对容易的转换成由数据驱动的代码。好处就是,上层的操作就会变成本节点的算子,增加代码的局部性。此外,这样的代码可以更方便进一步转换为一个纯计算代码,例如使用LLVM优化等。个人认为这种模型通用性不强,只能做一些局部的优化。

Greenplum使用的是迭代模型,但我们正在积极探索向量化模型和PUSH模型。Greenplum正在开发相应的功能,并提交到PG社区,基本思路是利用custom scan 的可定制特性,实现向量化版本的AGG节点,SORT节点,并替换原有查询执行树中的相应节点。大家对这一块感兴趣也欢迎去相应的邮件列表查看。

而Greenplum执行器面临了更大的挑战,首先Greenplum是MPP架构,意味着大规模的并行计算,每个执行节点就需要更多的处理过程。同一个执行节点就会变成多个处理过程,而数据也会被拆分。执行节点之间进行输入和输出的过程中,需要不同的计算单元进行交换。

Greenplum执行的挑战和解决方案——Motion

此外,Greenplum是一个Shared-Nothing的架构,这就意味着不同的计算单元之间的输入输出的过程会受阻。

面临这样的挑战,Greenplum的解决方案是加了一个新的名为MOTION的执行节点,用来在不同的执行节点之间移动数据。

加了Motion后,执行计划仍然是树状结构。只是在不同的节点之间加了个Motion节点,并最终通过Motion节点,将数据进行汇总。

接着我们来剖析一下并行化Plan。在下面的例子中,我们有一个Master和34个Segment节点。现在有两张表:单身男和单身女,数据分布在不同的SEGMENT上。如果我们要进行一个查询,将这两张表格中,籍贯相同的单身男和单身女进行相亲匹配,我们是如何生成一个可以被并行化执行的计划树呢?

为了更好的说明这个问题,我们可以在现实生活中进行映射,来方便大家理解。如果在现实生活中,我们会怎么办?如果这些不同户籍的单身男女在同一个省,此时处理方法就相对简单,

  • 首先把单身女找出来

  • 再把单身男找出来

  • 再把同户籍的男生女生分配到相同的会场

从而较为快速的把这些单身男女进行匹配和筛选。

如果这些单身男女并不在同一个省,而是分布在全国34个省中,此时要如何处理呢?

为了做一个最优的策略,我们会分情况来看,

1. 如果单身男女都居住在户籍所在地

  • 可以由各省独自举办相亲会

  • 针对本省的单身男女组织相亲

  • 将结果返回总部

对应到Greenplum上,是这样的

2. 对于单身女居住在户籍所在地,而单身男生分散在全国各地。此时采取的策略可以是,

  • 各省的分部独自举办相亲会:
  • 将每个省的单身男青年找出来,并将他们通过火车派送回原户籍所在地
  • 由每个省接待这些男青年,并在本省找出女单身青年,对他们进行相亲配对。

如果女生数量很少,此时可以采用的策略是

  • 找到本省所有适龄单身女青年,并为其买好34个省份的车票,每个省份都去一趟。

  • 每个省接待这些单身女青年,并安排其与生活在本省的男青年相亲,找出户籍一致的配对。

对应到Greenplum上,是这样的

3. 如果单身男女随机分布在全国各地,此时有两种策略策略1:在总部举办相亲会,各省把单身男女通过火车派送回总部,总部接待并安排相亲配对。但由于总部资源有限,一般都不会采取这种策略;策略2:

  • 各分部举办相亲会:

  • 各省找出居住在本省的适龄单身男,并按户籍派送到相应的省。

  • 各省找出居住在本省的适龄单身女,并按户籍派送到相应的省。

  • 各省接待全国归来的男女,进行相亲配对。

对应到Greenplum上,就是这样的:

在进行相亲策划后,我们得出了以下经验总结:

  • 人多力量大的原则,尽量利有各省的分部

  • 要首先分析当前男女青年的地域分布

  • 必要时使用交通工具来打破地域的限制

其实在Greenplum里,也采用了类似的处理方式。每一张表都会有数据分布信息,Greenplum支持三种分布策略:键值分布(按列分布)、随机分布、复制分布(数据在所有的segment上都保留了一份数据)。

Greenplum内部采用更通用的Locus信息来表示分布信息,所有的数据集合都会有数据分布状态的。

Greenplum通过Motion来打破物理上的隔离。包括下图中的四种Motion。Redistribute Motion是通过键值把Tuple在多个节点间进行重分布。Gather/Gather Merge Motion是把不同Segment上的数据聚集到一个节点上,Gather Merge保证了一个有序的收集过程。Broadcase Motion顾名思义就是广播,每个节点都发送一份。Explict Redistribute Motion常用于Update/Delete操作,该类操作需要在数据原来所在的节点上进行更新或删除,保证数据分布不会出现不一致。gp segment id隐藏列保存了数据所在原来节点信息。

并行化Plan

Motion会引起数据的迁移,带来执行代价,所以Greenplum会对需不需要做Motion进行代价评估,评估依据主要是当前数据集合的数据分布状态和在当前数据集合上将要执行的操作。

现在我们通过一个分布式Join的例子来巩固一下。下面是一个简单的inner join。A、B都是按照Hash分布的键值表。也就是数据被分散在各个Segment上,而每个Segment上只有部分数据。要做到A inner join B的完整数据集,就需要把B表全部复制到所有的segment上,和A的部分数据Join。得到的Plan就如下图所示。前面我们提到,在Join完成后,也会有个数据分布。本例中,在Join完成后,还是会通过Hash分布。接着,由于QD会直接和Client进行交互,因此需要把所有的数据Gather到QD上,再由QD发送给Client。而其中的优化过程,会在本《深入浅出Greenplum内核》系列直播后续的课程中细讲,请大家关注。

如果A是一个键值表,B是一个复制表。前面的Broadcast就不需要做了,可以直接进行Join。每个并行处理单元处理下图中的计划树,再Gather到QD即可。

如果A是键值表,而B是general的数据分布。B会在每个segment上都能产生1-10的数据,就能满足Join的需求。

如果A不变,而B是一个子查询,是SingleQE的数据分布,即在一个segment上提供这样的数据。其中一种策略就是,把分布各个Segment上的A的数据都Gather到一个Segment上执行。此时Join后的数据模型就会变成SingleQE的数据分布。

如果在Inner Join时加个条件,就可以将Broadcast Motion换成Redistribute Motion。让c2这一列按照c1这个Hash重新分布到其他segment上,从而减少数据的移动。

我们再来看一个要AGG操作的例子,在下面的例子中,对A进行AGG操作,计算c1的count值。此时,我们只需要在每个Segment上做AGG,再Gather到QD即可。

如果A表是按照C2做分布的(非两阶段),则前面的策略便不可用了。此时,我们可以将A可以按照C1做Redistrbute Motion,在前面提到的操作即可。

Dispatcher

讲完分布式Plan的产生,我们再来看一下Greenplum中为了支持分布式plan而设计的模块。第一个就是Dispatcher。上面提到的相亲的策略,

  • 各省的分部独自举办相亲会。

  • 首先每个省的单身男青年找出来,并将他们通过火车派送回原户籍所在地。

  • 然后每个省接待这些男青年,并在本省找出女单身青年,对他们进行相亲配对。

具体实施起来是怎么样的呢?

对应到Greenplum上,有了分布式plan,一堆计算资源是如何分配调度和执行起来的呢?

Dispatcher首先要做的就是分配QE资源。从plan的角度来看,会将计划做成SliceTable,SliceTable中会告知Slice2从34个segment来分配资源,而Slice3只需要Segment2来提供资源即可。

Dispatcher从SliceTable中得到信息后,会去分配资源。它会向CdbComponentDatabases这个component来申请资源,并将得到的资源回写到SliceTable中。原本,SliceTable中只包括了需要在哪几个Segment上起QE资源的较模糊的指令,但在分配完后,每个SliceTable就会得到QE资源具体的节点信息,包括地址和端口等。

Dispatcher分配QE资源通过调用allocateGang()函数完成。GANG大小的分配非常灵活,最小可以只分配一个QE资源,而一般为segment的个数,甚至可以支持大于segment的个数的QE资源,即每个segment可以为一个gang分配多于一个的QE资源。此外QE资源闲置后,并不会被马上回收,而是可以被后续的查询重用,减少了重复分配QE带来的开销。

Dispatcher第二个功能是分发任务。CdbDispatchPlan可以分发并行性化plan的任务,SliceTable也会连同这个分布式plan一起发给QE。这样的话所有的QE通过SliceTable可以找到自己预先被分配属于哪个Gang,以及它的父节点的Gang是哪些以便于建立节点间通信。通过Parent Gang具体的QE描述符,我们就可以知道要把数据传送到哪个端口。也可以分发纯文本的、两阶段提交、查询树的任务。

Dispatcher的第三个功能就是协调功能,通过cdbdisp_checkDispatchResult函数来控制QE的状态。有下面四种等待模式。

下图就是一个典型的Dispatcher程序。Greenplum内的代码基本都会遵循这样的逻辑:分配上下文-分配资源-发送任务-等待发送的完成-等待QE的状态-销毁上下文。

Interconnect

第二个模块就是Interconnect。Greenplum是通过网络在QE之间移动数据,这个网络模块就是Interconnect。在Motion节点被初始化时,发送端和接收端就会建立Interconnect网络连接。在Motion节点执行时,就会通过Interconnect来发送数据。

下图是Interconnect的分层介绍。从应用层来说,主要任务是发送数据。Interconnect会对Tuple进行包装,将其包装成一个个Chunk。有些Tuple很大,就会进行切割,将其切成多个Chunk。Chunk通过数据包发送给receiver端。应用层还有一些数据流控制的包,包括EOS包,STOP包等。所有的包都会通过系统传输层中的UDPIFC和TCP IC进行传输。

UDPIFC是Greenplum自己实现的一种RUDP(Reliable User Datagram Protocol)协议。基于UDP协议开发的,为了支持传输可靠性,实现了重传,乱序处理,重传处理,不匹配处理,流量控制等功能。GPDB当初引入UDPIFC主要为了解决复杂OLAP查询在大集群中使用连接数过多的问题。UDPIFC实际上是一种线程模型。

后续,我们也可能会增加一些新的Interconnect类型,包括QUIC协议,Proxy协议等,欢迎大家的关注。

关于Hashjoin的内容,由于时间原因,本次分享就不做详细的讲解,如果大家对这一块感兴趣,可以反馈给我们社区,我们可以在后面添加专门的讲解。大家可以参考一下之前Greenplum中文社区公众号发布的关于Hashjoin的文章来了解相关内容。

Greenplum小测试第二期

(ask.greenplum.cn/exam)

参加活动即可获得“青梅称号”,截图分享至朋友圈还有机会获得Greenplum变色杯!

我知道你

在看

greenplum 存储过程_揭秘!Greenplum并行执行引擎到底是如何工作的?相关推荐

  1. 揭秘!Greenplum并行执行引擎到底是如何工作的?

    本文转载自:Greenplum社区 首先我们先来了解一下什么是执行器.简单来讲,执行器是处理一个由执行计划节点组成的树,并返回查询结果.那么什么是执行计划节点呢?从本质上讲,一个执行计划节点,实际上就 ...

  2. greenplum 存储过程_如何使用Greenplum提升PB级数据处理能力

    作者 个推高级数据研发工程师 糖炒栗子 前言:近年来,移动互联网.物联网.云计算的快速发展,催生了海量的数据.在大数据处理方面,不同技术栈所具备的性能也有所不同.如何快速有效地处理这些体量庞大的数据, ...

  3. mysql 读写引擎_揭秘MySQL存储引擎spider

    转自:兴趣部落​buluo.qq.com 导读: Spider是为MySQL/MariaDB开发的一个特殊引擎,具有内嵌分片功能.现在它已经被集成到MariaDB10.0及以上版本中,作为MariaD ...

  4. 揭秘捷码运行引擎到底是如何工作的?

    问题1:捷码运行引擎是什么?如何部署.更新? 回答:运行引擎是用户将捷码应用部署到客户服务器时必不可少的工具.运行引擎为捷码应用正常运行,提供所必须的服务环境. 引擎部署:用户在服务器上使用引擎自带脚 ...

  5. db2 删除存储过程_蚂蚁金服OceanBase挑战TPCC | TPCC基准测试之存储优化

    蚂蚁金服自研数据库 OceanBase 登顶 TPC-C 引起业内广泛关注,为了更清楚的展示其中的技术细节,我们特意邀请 OceanBase 核心研发人员对本次测试进行技术解读,共包括五篇: 1)TP ...

  6. 目标跟踪:卡尔曼滤波(Kalman Filter)到底是怎么工作的?

    Kalman filter到底是怎么工作的? 本文主要参考的文章:https://www.bzarg.com/p/how-a-kalman-filter-works-in-pictures/,图片也基 ...

  7. Spring MVC 到底是如何工作的

    转载自  Spring MVC 到底是如何工作的 这篇文章将深入探讨Spring框架的一部分--Spring Web MVC的强大功能及其内部工作原理. 这篇文章的源代码可以在GitHub上找到. 项 ...

  8. How browsers work -Behind the scenes of modern web browsers 浏览器到底是怎么工作的、浏览器的工作原理(完整中文翻译)

    How browsers work -Behind the scenes of modern web browsers 有空翻译一下这篇必读的文章 -浏览器到底是怎么工作的.浏览器的底层原理是啥.浏览 ...

  9. Disruptor本地线程队列_实现线程间通信---线程间通信工作笔记001

    Disruptor本地线程队列_实现线程间通信---线程间通信工作笔记001 看到同事用这个东西了,这个挺好用的说是,可以实现,本地线程间的通信,好像在c++和java中都可以用 现在没时间研究啊,暂 ...

最新文章

  1. Google VC投资SDN初创公司Plexxi
  2. 大脑只需单个神经元就可进行XOR异或运算,Science新研究揭开冰山一角,引发热议...
  3. java synchronized 使用_Java中synchronized的使用实例
  4. 推荐几款热门的敏捷开发工具
  5. python 判断数字连续_关于python:检测列表中的连续整数
  6. java升级后nc不能用_用友NC系统使用过程中常见问题和解决方法2017
  7. 线性回归2——正则化(含代码)
  8. qtxlsx读写 excel
  9. matlab chan算法定位,chan算法定位 matlab
  10. 7-10 愿天下有情人都是失散多年的兄妹 (25分)
  11. c语言程序设计小球弹跳,C语言之1 实现弹跳小球
  12. Hive 中的时间加减暨间隔函数INTERVAL
  13. 首出集团:超级推荐引爆流量,6步店铺跨越到第六层级
  14. 视频教程-微信小程序系统教程[2/3阶段]_核心技术-微信开发
  15. 电脑各种中英文信息对照及错误信息总汇 系统出错信息及解决方案
  16. markdown设置锚点
  17. Window Server 2022 无法安装网卡驱动 1219-v
  18. 做一粒不浮躁的好“种子”
  19. 【技法操作】用PS制作个性时钟图标,UI设计教程
  20. 多种方法(聚类、衍生变量、多重筛选、损失函数)解决解决异常值识别效果不佳问题(含2022年全国服务外包大赛实例)

热门文章

  1. java递归老鼠走迷宫_递归算法求老鼠走迷宫(C语言)
  2. 银河麒麟通过命令行安装软件没有安装上
  3. Python实现AES加密进行PKCS5Padding的填充
  4. java运算符试题,编程语⾔⾯试题之新版javase基础语法篇之运算符
  5. python流量实时统计_Python实现获取nginx服务器ip及流量统计信息功能示例
  6. python深度优先_python数据结构之图深度优先和广度优先实例详解
  7. 在c语言中数组下标的最小值,数组元素下标的上限_c语言中,数组元素的下标下限为...
  8. linux软件读取不到空间,Linux下Oracle软件、数据文件等所在的磁盘分区空间不足的解决思路...
  9. 重启计算机后桌面顺序是反的,Win10系统为什么重启电脑之后桌面上的图标排列顺序被打乱该如何处理...
  10. django项目如何连接前端_工作笔记前端小白如何搭建前端项目