简介:作者:阿里云数据库OLAP产品部 - 子华

一 背景

AnalyticDB PostgreSQL版(简称ADB PG)是阿里云数据库团队基于PostgreSQL内核(简称PG)打造的一款云原生数据仓库产品。在数据实时交互式剖析、HTAP、ETL、BI报表生成等业务场景,ADB PG都有着独特的技术劣势,在金融、物流、泛互联网等行业都有宽泛的利用,是传统数仓上云、去O去T、替换自建Greenplum的标杆云上数据仓库产品。

数据仓库产品是数据分析系统的重要组件之一,各类线上业务对数据仓库产品的稳定性、可用性具备很高的要求。不足无效的资源管理机制会导致数据库产品的稳定性降落,产生例如连接数打满OS限度、内存不足、过程卡死等问题,从而影响产品的可用性。

Resource Queue(资源队列)是ADB PG的一种资源管理形式,可能对数据库的CPU、内存等资源进行限度,对多租户资源限度、保障数据库稳固运行具备肯定的作用。顾名思义,Resource Queue以队列模式对运行在数据库集群上的SQL进行资源管理。对于每个用户,他的所有连贯只能归属于一个队列。而对于每个队列可能治理多个用户的连贯。没有显示指定资源队列的用户,会归属于默认资源队列治理。通过限度每个队列的资源总量,咱们能够达到限度某类业务或者某个用户应用的资源总量的目标。

咱们以ADB PG某在线交易平台类客户A为例,介绍Resource Queue的应用。客户A基于ADB PG构建数据仓库,日常运行三类业务:以交易数据入库为代表的实时类业务;用于撑持决策分析的报表类业务;以及用于实时大屏展现的可视化类业务。咱们依据三类业务的不同特点,按如下策略配置资源队列。

客户A的实时类业务的典型代表是,交易数据经Kafka->Flink->ADB PG链路实时写入ADB PG。这类业务的典型特点是,峰值并发比拟大,单个SQL资源耗费小。在进行资源队列限度前,业务高峰期常常产生忽然进步的并发查问打满数据库连贯,造成高可用探活查问执行失败,引发实例不可用。对于这类业务咱们将其关联到一个高CPU权重、大并发限度(平安阈值内)、单个SQL内存份额低的队列。既保证数据的疾速入库,又避免流量洪峰造成零碎不稳固。

客户A的另一类典型业务是报表类、ETL类业务,这类业务会在实时类业务的低峰期进行调度,生成报表以提供决策反对。这类业务波及的数据量较大,耗费内存量和产生的临时文件量大。对于这类业务,咱们将其关联到低CPU权重、低并发限度,然而内存份额高的队列,在满足业务须要的同时,管制内存应用下限;

除此之外,客户还基于ADB PG数据仓库反对数据的实时可视化展现,这类可视化计划往往具备十分稳固的并发,然而对查问的延时具备肯定的要求。对于这类业务,咱们将其资源队列设定为高CPU权重,低并发限度,以及宽泛的优化器查问打算耗费份额,最大水平为其生成良好的查问打算,以保障业务稳固。

接下来,本文会具体介绍Resource Queue的应用形式、状态监控,以及它的实现机制。

二 Resource Queue简介

Resource Queue反对通过SQL配置,反对进行四种类型的资源限度:并发限度、CPU限度、内存限度和查问打算限度。用户能够通过SQL在数据库内定义多个资源队列,并设置每个资源队列的资源限度。在一个数据库中,每个资源队列能够关联一个或多个数据库用户,而每个数据库用户只能归属于单个资源队列。

另外,并不是所有提交到资源队列的SQL都会受到队列限度的限度,数据库只会限度SELECT、SELECT INTO、CREATE TABLE AS SELECT、DECLARE CURSOR、INSERT、UPDATE 和DELETE这些类型SQL的资源利用。另外,在执行EXPLAIN ANALYZE命令期跑的SQL也会被资源队列排除。

资源队列反对的资源限度配置如下:

通过SQL语句定义一个新的资源队列:

CREATE RESOURCE QUEUE etl WITH (ACTIVE_STATEMENTS=3, MEMORY_LIMIT='1GB', PRIORITY=LOW, MAX_COST=-1.0);

ACTIVE_STATEMENTS:

队列中容许同时运行的查问数,即队列中容许并发查问的最大并发值。数据库容许超出ACTIVE_STATEMENTS数目、然而少于数据库最大连接数MAX_CONNECTIONS数目的链接连贯到数据库,然而这部分SQL连贯并不会立即开始运行,而是排队期待。

MAX_COST:

查问打算Cost限度。数据库优化器会为每个查问计算Cost,如果该Cost总量超过了资源队列所设定的的MAX_COST的值,该查问就会被回绝。ADB PG的默认配置为0,即不受限制。

Memory Limit:

ADB PG能够通过设置statement_mem来决定每条SQL在每个Segment上应用的内存下限。Memory Limit既没有默认值,也能够不指定。在MEMORY_LIMIT参数没有被配置时,一个资源队列中的一条SQL所容许的内存大小,由statement_mem参数决定:

• 如果一个资源队列没有设置MEMORY_LIMIT的话,每个资源所调配到的内存大小就是statement_mem的服务器配置参数,一个资源队列的可用内存大小是依据statement_mem和ACTIVE_STATEMENTS的计算结果。
• 当资源队列有设置MEMORY_LIMIT时,单个SQL所应用的内存量会由队列中的平均分配值(MEMORY_LIMIT/ACTIVE_STATEMENTS)和statement_mem中的最大值决定,具体计算形式能够参考前面实现章节。

资源队列中能够并行执行的查问数会受到该队列的可用内存限度。举个例子:对于队列etl,设置STATEMENTS=3, MEMORY_LIMIT=2.1G;那么在没有设置statement_mem的状况下,每个查问默认应用内存700MB。

SQL1进入队列,应用内存700MB,此时队列残余内存1.4G;

SQL2进入队列,设置statement_mem为1.0GB,此时队列残余内存为0.4GB;

此时,队列残余内存无奈满足SQL3的内存应用需要(默认700GB),那么尽管队列中并行查问数没有达到队列限度,SQL3仍然无奈执行,须要排队期待。

PRIORITY:

数据库运行的SQL会依照其所在资源队列的优先权设置来共享可用的CPU资源。当一个来自高优先权队列的语句进入到流动运行语句分组中时,它能够失去可用CPU中较高的份额,同时也会升高具备较低优先权设置队列中曾经在运行的语句失去的份额。

查问的绝对尺寸或复杂度不影响CPU的调配。如果一个简略的低代价的查问与一个大型的简单查问同时运行,并且它们的优先权设置雷同,它们将被调配等同份额的可用CPU资源。当一个新的查问变成流动时,CPU份额将会被从新计算,然而优先权相等的查问仍将失去等量的CPU。

例如,管理员创立三个资源队列:streaming、etl、prod,并相应地配置为以下优先权:
• streaming — 低优先权
• etl— 高优先权
• prod — 最大优先权

当数据库中只有etl队列中有查问1和2同时运行时,它们有相等份额的CPU,因为它们的优先权设置相等:

上图中显示的百分数都是近似值。高、低和中优先权队列的CPU应用并不总是精确地用这些比例计算出来。

当一个streaming队列中的查问开始运行时,在etl队列中两个查问仍然放弃相等的CPU份额,而低优先级的query3则会以较低CPU份额运行。

而当最高优先级队列prod中有查问进入队列之后,其CPU应用会被调整以阐明其最大优先权设置。它可能是一个非常简单的查问,但直到它实现前,它都将要求最大份额的CPU。而其余查问的优先级则会被调整为较低的CPU份额。

三 Resource Queue应用

3.1 创立资源队列

ADB PG容许用户应用SQL创立资源队列,并指定各类资源限度。应用CREATE RESOURCE QUEUE命令来创立新的资源队列。

创立带有并发限度的队列

带有ACTIVE_STATEMENTS设置的资源队列会限度指派给该队列的角色所执行的并发查问数量。

CREATE RESOURCE QUEUE etl WITH (ACTIVE_STATEMENTS=3);

这意味着对于所有被调配到etl资源队列的角色,在任意给定时刻只能有三个流动查问被运行在这个零碎上。如果这个队列曾经有三个查问在运行并且一个角色在该队列中提交第四个查问,则第四个查问只有等到一个槽被释放出来后能力运行。

创立带有内存限度的队列

带有MEMORY_LIMIT设置的资源队列管制所有通过该队列提交的查问的总内存。在与ACTIVE_STATEMENTS联结应用时,每个查问被调配的默认内存量为:MEMORY_LIMIT /ACTIVE_STATEMENTS。

例如,要创立一个流动查问限度为10且总内存限度为2000MB的资源队列(每个查问将在执行时被调配200MB的Segment主机内存):

CREATE RESOURCE QUEUE etl WITH (ACTIVE_STATEMENTS=10, MEMORY_LIMIT='2000MB');

另外gp_vmem_protect_limit参数会限度一个Segment上调配的内存总大小。该参数的优先级更高,如果这个参数超标,查问可能会被勾销。

设置优先级

为了管制一个资源队列对可用CPU资源的耗费,用户能够指派一个适合的优先级。

ALTER RESOURCE QUEUE etl WITH (PRIORITY=LOW);ALTER RESOURCE QUEUE etl WITH (PRIORITY=MAX);

3.2 指派角色(用户)到资源队列

一旦创立了一个资源队列,用户必须把角色(用户)指派到它们适合的资源队列。如果没有显式地把角色指派给资源队列,它们将进入默认资源队列pg_default。
应用ALTER ROLE或者CREATE ROLE命令来指派角色到资源队列。例如:

ALTER ROLE name RESOURCE QUEUE queue_name;CREATE ROLE name WITH LOGIN RESOURCE QUEUE queue_name;

从资源队列移除角色

所有用户都必须被指派到资源队列。如果没有被显式指派到一个特定队列,用户将会进入到默认的资源队列pg_default。如果用户想要从一个资源队列移除一个角色并且把它们放在默认队列中,能够将该角色的队列指派改成none。例如:

ALTER ROLE role_name RESOURCE QUEUE none;

3.3 批改资源队列

在资源队列被创立后,用户能够应用ALTER RESOURCE QUEUE命令更改队列限度,或应用DROP RESOURCE QUEUE命令移除一个资源队列。

批改资源队列配置

ALTER RESOURCE QUEUE命令更改资源队列的限度。要更改一个资源队列的限度,能够为该队列指定想要的新值。例如:

ALTER RESOURCE QUEUE etl WITH (ACTIVE_STATEMENTS=5);ALTER RESOURCE QUEUE etl WITH (PRIORITY=MAX);

删除资源队列

DROP RESOURCE QUEUE命令能够删除资源队列。要删除一个资源队列,该队列不能有指派给它的角色,也不能有任何语句在其中期待。

DROP RESOURCE QUEUE etl;

四 Resource Queue状态监控

4.1 查看队列中的语句和资源队列状态

gp_toolkit.gp_resqueue_status视图容许用户查看一个负载治理资源队列的状态和流动。对于一个特定资源队列,它展现有多少查问在期待运行以及零碎中以后有多少查问是流动的。要查看零碎中创立的资源队列、它们的限度属性和以后状态:

SELECT * FROM gp_toolkit.gp_resqueue_status;

4.2 查看资源队列统计信息

如果想要继续跟踪资源队列的统计信息和性能,用户能够应用pg_stat_resqueues零碎视图来查看在资源队列应用上收集的统计信息。

SELECT * FROM pg_stat_resqueues;

4.3 查看指派到资源队列的角色

要查看指派给资源队列的角色,执行下列在pg_roles和gp_toolkit.gp_resqueue_status系统目录表上的查问:

SELECT rolname, rsqname FROM pg_roles, gp_toolkit.gp_resqueue_status WHERE pg_roles.rolresqueue=gp_toolkit.gp_resqueue_status.queueid;

4.4 查看资源队列的期待查问

用户能够看到所有资源队列的所有以后沉闷的以及在期待的查问:

SELECT * FROM gp_toolkit.gp_locks_on_resqueue WHERE lorwaiting='true';

如果这个查问不返回后果,那就意味着以后没有语句在资源队列中期待。

4.5 查看流动语句的优先权

查看以后正在被执行的语句并且提供优先权、会话ID和其余信息:

SELECT * FROM gp_toolkit.gp_resq_priority_statement;

4.6 重置流动语句的优先权

用户能够应用函数gp_adjust_priority(session_id,statement_count,priority)调整以后正在被执行的语句的优先权。应用这个函数,用户能够晋升或者升高任意查问的优先权。例如:

SELECT gp_adjust_priority(12, 10000, 'LOW');

在这个函数的参数中,session_id代表会话id, statement_count代表要调整的SQL在session中的序号,priority是待调整的优先级。能够通过gp_resq_priority_statement视图查问现有语句的上述信息。

select * from gp_toolkit.gp_resq_priority_statement;

五 Resource Queue实现

ADB PG数据库是MPP架构,整体分为一个或多个Master,以及多个segment,数据在多个segment之间能够随机、哈希、复制散布。在ADB PG中,Resource Queue的资源限度级别是语句级别,即在整条SQL执行的任何时刻,不论是否处于事务中,均会受到资源队列的限度。

如上文所述,Resource Group反对对并发、CPU和内存等进行限度,本节会具体介绍对这些资源进行限度的实现细节。

5.1 并发限度

ADBPG数据库是多过程模型,分布式数据库的每个节点会启动多个子过程,各个子过程通过共享内存、共享信号量、共享音讯队列的形式实现过程间通信。

Resource Queue基于分布式锁实现。在ADBPG中所有的SQL连贯首先会达到Master节点,在通过解析、优化,达到执行器层面时,会首先尝试获取ResQueueLock类型的排他锁。
在单个ADB PG节点中,同一时间只能有一个过程获取到ResQueueLock类型的排他锁,而每个过程只会蕴含单个线程。

在取得ResQueueLock类型的排他锁之后,执行SQL的后盾过程会读取及更新共享内存中的值,特地是队列中并发执行语句的计数值。若资源短缺,则会在更新完共享内存中对应资源队列中的资源使用量之后,开释ResQueueLock,开始SQL的理论执行;

若资源有余,比方以后队列中正在运行的SQL数量曾经达到了所设定的并发上限值,对应的后盾过程则会sleep排队期待其余query执行结束后开释资源。

5.2 内存限度

对于内存的限度的实现形式与对并发限度的实现形式大体是统一的,只是对于判断资源队列中是否有资源来运行提交的SQL的形式有一些区别。

对于某个Resource Queue中的SQL,可能应用的内存下限计算如下:

1)如果没有设定resource queue的memory_limit值,那么间接取数据库的statement_mem值;

2)如果设定了resource queue的memory limit值,则依据所设定的resource queue的memory_limit值,计算资源组可能应用的内存总量;用总量除以resource queue设定的并发数,失去单条SQL所能利用的上限值。再将这个上限值与statement_mem取一个最大值,作为SQL最终应用的内存上限值。

5.3 CPU限度

Resource Queue的CPU限度是一个很有意思的实现。ADB PG专门为Resource Queue CPU限度的性能拉起了一个专门的过程:sweeper过程来监控各个后盾过程的CPU应用,以及调节各个后盾过程的CPU份额。

这个过程是一个与数据库高度独立的过程,它没有加载一些缓存、资源类的货色,也无奈开启事务或者查零碎表,它的流动就是不停的读写共享内存,计算各个过程的CPU应用,更改CPU调配份额。各个理论执行SQL的后盾过程(backend)会依据所计算的CPU份额去休眠肯定的工夫,从而调节各个SQL理论的CPU使用率。

这个过程的主体流程如上,他的流程非常简单,就是一直地sweep和sleep。

各个理论执行SQL的backend过程在启动时,会在共享内存中注册一些状态,并在执行过程中执行零碎调用getrusage等,更新CPU应用状态;sweeper过程会依据这些共享内存状态,以及所设定的资源队列CPU利用值,在共享内存中更新对应backend过程的CPU份额(targetCPU)。而在backend运行过程中,则会调用BackoffBackend,依据CPU份额来进行一段时间的休眠,从而调节整体的CPU利用率。

在运行过程中,分布式数据库的每个计算节点都会有一个sweeper过程来调节每个节点的CPU调用,使资源队列的CPU配置全局无效。

六 总结

资源管理对于数据库集群的多租户治理、资源细粒度调配具备很重要的价值。Resource Queue可能对分布式数据库进行整体的资源管理和管制,在多租户隔离、保障数据库整体安稳运行具备肯定的价值。

除了Resource Queue的资源管理形式外,ADB PG还反对 Resource Group 的资源管理形式,可能进行更精密的资源管制。Resource Group现已在专有云环境提供应用,后续会逐渐在私有云提供能力。后续咱们会介绍Resource Group的根本应用和最佳实际。

原文链接
本文为阿里云原创内容,未经容许不得转载。