暂无图片
暂无图片
3
暂无图片
暂无图片
暂无图片

Greenplum查询处理流程详解

原创 chirpyli 2023-05-22
1637

前言

Greenplum是最成熟的开源分布式分析型数据库,拥有广泛的用户群体,并于2015年正式开源。其基于MPP架构,具有良好的弹性和线性扩展能力,内置并行存储、并行通信、并行计算和并行优化功能,兼容SQL标准,具有强大、高效的PB级数据存储、处理和实时分析能力。这里就将对这款强大的Greenplum数据库的架构、数据存储与分布、并行执行计划以及查询处理流程进行深入分析,加深我们对这款数据库的理解。

架构

Greenplum采用无共享的MPP架构,无共享架构的特点是整个系统使用多个处理单元协作完成任务。每个处理单元拥有自己的操作系统、内存和磁盘等资源,不同节点之间通过网络进行通信。具体的,在Greenplum中,这个相对独立的处理单元就是PostgreSQL实例,也就是说Greenplum实际上是由多个PostgreSQL实例协作完成数据处理的,在功能划分上,可分为Master节点(或称为Coordinator节点),Segment节点,以及通信组件Interconnect,他们协作完成数据处理任务。

  • Master节点是Greenplum数据库的主节点,作为数据库的入口,主要负责接收客户端连接请求,对SQL语句生成执行计划,并将执行计划分发给所有的Segment节点完成查询执行。
  • Segment节点存储用户数据同时参与计划执行工作。
  • Interconnect,它是Greenplum数据库的网络层,主要负责查询执行过程中所有Segement实例之间以及Segment与Master之间的数据通信。

Master节点并不存储用户数据,用户数据全部存储在Segment节点上(一个Segment节点可以部署多个Segment实例),也就是说存储和查询执行任务主要是在Segment节点上,Master节点主要起到计划分发,聚合Segment节点运算结果上,正常情况下Master节点不会成为系统瓶颈,但也应在使用时注意合理选择分布键以及对SQL语句进行优化,尽量将计算任务下发给Segment节点完成,减少在Master节点的计算任务,避免成为系统瓶颈。

greenplumarchiture.png

MPP的架构设计,使得Greenplum具有良好的弹性和线性扩展能力,用户可根据自己的业务需求灵活进行部署。基于开源的PostgreSQL作为独立的处理单元,可以在兼容PostgreSQL生态的同时引入强大开源社区的力量,通过不断的升级Greenplum中PostgreSQL内核,实现性能的提升以及功能的增强。同时让Greenplum聚焦于AP能力以及HTAP能力的提升,不断提高产品能力。

数据存储与分布

数据存储分布化是分布式数据库面临的第一个问题,是后续如何进行查询处理,如何生成高效并行执行计划的基础。在Greenplum中,用户数据可按某种策略分布到不同节点的Segment实例中,每个实例都有自己独立的数据目录,以磁盘文件的方式存储用户数据。为了更好的AP性能,Greenplum在支持行存储的基础上,支持列存储。同时为了适应更多的应用场景,支持Appendonly表与外部表。用户可根据需要灵活进行选择,采用不同的存储策略保存不同时间的数据,比如最近三个月的数据使用堆表存储,更老的数据使用列存储,一年以前的数据使用外部表的方式存储在HDFS中。

greenplunstorage.png

Greenplum通过将数据分布存储在多个Segment节点中,一方面解决了海量数据存储的问题,另一方面也为处理并行化奠定了基础。通过集群中所有节点同时进行并行处理,解决单节点数据处理能力受限的问题。但是如果数据分布不均出现数据倾斜,受制于MPP架构,整个系统的性能将会和最慢的节点相同,因而数据分布是否合理对Greenplum整体性能影响巨大。对此,Greenplum提供了以下三种分布策略:

  • 哈希分布:Hash分布是Greenplum最常用的数据分布方式,根据用户的分布键计算后的哈希值将数据分布到某个Segment上。分布键的选择非常重要,好的分布键应将数据均匀分布到各Segment上,同时在用户查询时尽量减少重分布。
  • 随机分布:采用循环的方式将一次插入的数据存储到不同的节点上,应尽量减少这种分布方式,除非不能确定一张表的哈希分布键或者不存在合理的能够避免数据倾斜的分布键。
  • 复制表:即整张表在每个节点上都有完成的数据。一般适用于小表,这样可以减少查询执行过程中进行重分布或者广播。

在使用时应选择合理的数据分布方式,避免因分布不合理而影响性能。

并行执行计划

Greenplum执行计划与PostgreSQL十分类似,但由于Greenplum数据库分布式架构的特点,其执行计划与PostgreSQL也有着较大的不同,引起这个不同的最大原因就是数据分布方式。分布式数据库相对集中式数据库的一个重要的不同就是数据的分布,在分布式数据库中,数据是分布在多个节点上的,需要用户在建表的时候就指定分布策略以及分布键,数据将会按分布策略和分布键分布在多个Segment实例上,每个segment实例拥有一部分数据,而集中式数据库中,数据库实例拥有全部的数据。这样在Greenplum中,原有的PostgreSQL执行计划已无法实现完整的查询,必须重新实现并行执行计划(或称为分布式执行计划),并行查询计划就是在数据分布的基础上确定如何高效地实现计算的并行化以及如何让计算更加贴近数据,即尽可能的在Segment节点上进行计算,避免在master上进行计算,从而保证提供最好的查询性能。

为了理解Greenplum中的执行计划,我们先看一个示例,创建表,表student采用哈希分布,分布键为id,表class采用随机分布,后对表进行关联查询,生成执行计划如下:

greenplumplan.png

可以看到相比PostgreSQL的执行计划,其多了Redistribute Motion以及Gather Motion节点。前者含义为重分布,后者则是聚合,除了这两个节点还有一个广播节点Broadcast Motion。这三种Greenplum新增的节点是实现并行执行计划的关键。

  • Gather Motion节点的主要作用是运行在Master节点上,将所有Segment实例上的查询执行的结果聚合起来。比如上面的例子中,由Master节点汇集所有Segment实例的哈希连接的结果,最终返回给客户端。
  • Redistribute Motion节点则是对数据进行重分布。在分布式架构下,一个Segment实例仅存储一部分用户数据,不同Segment实例间的数据没有交集。比如在上面的查询执行过程中,当一个Segment实例需要根据关联键id执行哈希连接操作时,由于class表是随机分布,不能保证与student表id关联的数据都在同一个Segment实例上,所以需要对class表以关联键id为分布键进行哈希分布,将所有与当前Segment实例上student表的id值相关联的所有class表的数据都重分布到此Segment实例上。即按照新的数据分布规则将表中的数据通过网络(Interconnect)重新分发到各个Segment实例上。
  • Broadcast Motion节点是将当前Segment实例操作的数据发送给其他Segment实例,这样,每个Segment实例都能得到这个表所对应的全局数据,顾名思义,广播。当一个Segment实例需要得到其他Segment实例的数据时,有两种方法,其一是上面提到的重分布,另一种就是通过广播,得到这个表的全部数据,所以,采用这种方式的表一般都是较小的表,同时优化器会计算广播与重分布两种方式各自的代价,选择代价低的方式进行。

有了上面的3种Motion节点,就有了构造并行执行计划的基础。Greenplum数据库在查询执行过程中,为了增加查询执行的并行度,会将执行计划切分成多个Slice,每一个Slice可以视为单机可执行的执行计划片段,其所对应的数据或者是本地数据,或者是通过计划树下层Motion节点传递过来的数据。所以,在Greenplum并行执行计划中,每一个Motion节点都会生成一个Slice,每一个Slice由一个进程来执行对应此部分的执行计划。通过Slice将执行计划并行化,即可加快执行速度,又可以充分提高系统CPU等资源的利用率。

在Greenplum并行执行计划中,每个Motion节点均有两个属性:sliceID和segments。sliceId是这个Slice在并行执行计划里的唯一标识,segments是参与执行该Slice的Segment实例数量,要么是1,对应Master节点,要么是N,对应整个Greenplum集群中Segment实例总数。所有Segment实例上执行同一sliceId操作的一组进程称为一个Gang。在一个规模为N的Greenplum集群中,Gang的大小或者是N,或者是1。N-Gang通常对应运行在Segment实例上的普通操作。1-Gang通常对应运行在Master节点上的Gather Motion。

greenplummotion.png

继续以上面的例子为例,我们假设集群由一个Master节点,2个Segment节点,每个Segment节点各部署一个Segment实例。在上面的例子中,2个Segment实例各自启动一个进程执行对class表的扫描操作,并通过Motion节点将表扫描的元组数据按新的分布键重分布分别发送给2个Segment实例的Motion Receiver节点。重分布后,每个Segment实例进行哈希连接操作,并将结果通过Motion Sender节点发送给Master节点。Master节点汇集2个Segment实例的执行结果最终将结果返回给客户端。

查询处理过程

在理解了Greenplum架构以及分布式数据库执行计划后,接下来我们将探究Greenplum数据库查询处理的过程。前面提到,Greenplum将节点分为Master节点与Segment节点,在执行查询的过程中,同样有QD、QE的概念。

  • QD(Query Dispatcher 查询调度器):Master节点上负责处理用户查询请求的进程称为QD。QD收到用户发来的SQL请求后,进行解析、重写和优化,将优化后的并行执行计划分发给每个Segment上执行,并将最终结果返回给用户。此外还负责整个SQL语句涉及到的所有QE进程间通讯控制和协调。
  • QE(Query Executor 查询执行器):Segment上负责执行QD分发来的查询任务的进程称为QE。Segment实例本身也是一个PostgreSQL,所以对于QE而言,QD是一个PostgreSQL的客户端,它们之间通过libpq协议进行通信。对于QD而言,QE是负责执行其查询请求的PostgreSQL Backend进程。

Greenplum中处理查询请求的过程如下图所示:

greenplumexecuteflow.png

主要步骤如下:

  1. 客户端通过libpq协议首先连接到Master节点的Postmaster进程。
  2. Master节点的Postmaster进程产生一个后端Postgres进程QD,QD与客户端进行连接,执行客户端请求认证。认证通过后,QD等待客户端发送查询请求。
  3. 客户端将查询请求发送给QD进程。
  4. QD生成并行执行计划,并根据执行计划中的Slice数量,通过libpq与每个Segment实例上的Postmaster进程连接以启动QE进行查询执行。
  5. QD将执行计划分发给所有Segment实例上所有的QE进程。
  6. 每个QE进程根据执行计划执行属于自己的Slice,不同Slice间QE的数据通信通过Interconnect完成。
  7. 所有负责执行最后一个Slice的QE将执行的结果返回给QD。
  8. QD汇总查询结果,返回给客户端,并等待下一个查询语句的到来。

Greenplum数据库通过以上流程完成了分布式架构下的查询处理过程。

结语

通过以上对Greenplum数据库的架构、数据存储与分布、并行执行计划以及Greenplum数据库查询处理流程的深入分析,我们对这款数据库有了深入的理解。其采用大规模无共享处理架构,将多台服务器组成一个强大的计算平台,实现高效海量并行计算。可支持1000个以上的集群,管理的数据规模从100T到数PB,可以满足大多数企业的数据处理需求。认识Greenplum数据库对我们进行分析型数据库的选型以及后续的使用有重要意义,值得我们深入学习。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论