人大金仓分析型数据库资源队列(一)

一、简介

        使用数据库的工作负载管理根据业务需求对查询按照优先权分配资源,并且在资源不可用时阻止查询执行。资源队列是用来管理数据库系统中并行程度的工具。可以使用CREATE RESOURCE QUEUESQL声明创建资源队列这一数据库对象,用资源队列来管理可能并行执行的活动查询, 控制它们的内存使用量,以及队列中的相对排序。资源队列同时也可以防止查询消耗太多资源进而降低系统性能。每个数据库角色都与一个单个资源队列关联;多个角色可以共享同一个资源队列,使用RESOURCE QUEUE 中的CREATE ROLE或ALTER ROLE来将角色分配到资源队列中。如果没有指定资源队列,则角色将会自动被关联到默认资源队列pg_default。

        当用户提交了一个要执行的查询时,资源队列会根据其限制对查询进行评估,若该查询所需的资源没有超过限制,它将会立即执行;若超过了限制(例如,如果目前所有活动声明槽位都已被占用),该查询则必须等到队列资源有空闲时才能执行。对查询的评估将遵从先进先出的原则。如果启用了查询优先权,则将会预估系统当前的负载并根据查询优先权进行资源分配。拥有SUPERUSER属性 的角色将会不受资源队列限制的限制,无论何时,超级用户的查询都会无视其所在资源队列的限制并立即执行。

        资源组特性:

  • MEMORY_LIMIT:队列中所有查询所使用的的内存的量。例如,对ETL查询设置2GB的MEMORY_LIMIT,这样每个实例里的ETL查询最多使用2GB的内存
  • ACTIVE_STATEMENTS:队列中活跃查询的数量;一个队列中最大可并行数,当所有槽位都占用时,新的查询必须等待。默认每个查询使用 等量的内存
  • PRIORITY:查询使用的相对CPU使用量,可以设置为以下级别:LOW、MEDIUM、HIGH 和MAX。默认级别是MEDIUM,查询优先权的机制会监控系统中所有正在运行的查询的CPU使用量,并根据其优先权别来调整其CPU使用量。
  • MAX_COST:查询计划消耗限制。数据优化器会为每个查询分配数字型消耗,如果该消耗超过了资源队列的MAX_COST的值,该查询就会被拒绝。

         当基于资源队列的资源管理系统激活时,会使用MEMORY_LIMIT和ACTIVE_STATEMENTS限制资源,而不是配置基于消耗的限制。数据库系统默认配置有一个默认资源队列,名为pg_default,pg_default资源队列的ACTIVE_STATEMENTS 设置数值为20,没有MEMORY_LIMIT和MAX_COST,PRIORITY。这意味所有查询都会被接受并立即执行,没有优先权划分和内存限制;但是并行的查询最多是20个。

        一个资源队列所允许的并行查询的数量由是否有设置MEMORY_LIMIT决定:

  • 如果一个资源队列没有设置MEMORY_LIMIT的话,每个资源所分配到的内存大小就是statement_mem的服务器配置参数,一个资源队列的可用内存大小是根据statement_mem和ACTIVE_STATEMENTS的计算结果
  • 当资源队列有设置MEMORY_LIMIT时,资源队列中可以并行执行的查询数将会受到该队列的可用内存限制

        并不是所有提交到资源队列的SQL语句都会受到队列限制的评估,默认只会评估SELECT、SELECT INTO、CREATE TABLE AS SELECT和 DECLARE CURSOR语句。如果服务器配置的resource_select_only参数为off,那么INSERT、UPDATE 和DELETE语句也会受评估。与此同时,在执行EXPLAIN ANALYZE命令期间跑的SQL语句也会被资源队列排除。

二、资源队列示例

        默认资源队列pg_default允许最多20个活动查询平分内存以并行执行。一般来说这是不足以满足生产环境下的资源需求的。为了确保系统能够满足性能期望,用户可以定义查询的组并对其分配拥有相应的并行量、内存以及CPU的资源队列。如下展示了一个数据库系统的资源队列的配置:

资源队列名
活跃数量
内存限制 每个查询的内存
ETL
3
2GB
667MB
报告
7
3GB
429MB
执行
1
1.4GB
1.4GB

三、优先权限制

         资源队列的PRIORITY设置与MEMORY_LIMIT和ACTIVE_STATEMENTS设置不同,后两者决定一个查询是否将被准许进入该队列并且最终被执行。PRIORITY设置对于活动查询适用。活动查询会按照其所在资源队列的优先权设置来共享可用的CPU资源。当一个来自高优先权队列的语句进入到活动运行语句分组中时,它可以得到可用CPU中较高的份额,同时也降低了具有较低优先权设置队列中已经在运行的语句得到的份额。查询的相对尺寸或复杂度不影响CPU的分配。如果一个简单的低代价的查询与一个大型的复杂查询同时运行,并且它们的优先权设置相同,它们将被分配同等份额的可用CPU资源。当一个新的查询变成活动时,CPU份额将会被重新计算,但是优先权相等的查询仍将得到等量的CPU。

        当一个查询进入到运行语句组中时,CPU使用会被调整以说明其最大优先权设置。它可能是一个报表查询的简单查询,但直到它完成前,它都将要求最大份额的CPU。  

四、内存限制

        一个资源队列上的MEMORY_LIMIT为一个实例设置通过该队列提交的所有活动查询可以消耗的最大内存量。给一个查询的内存量是队列内存限制除以活动语句限制(将内存限制与基于语句的队列而不是基于代价的队列)。例如,如果一个队列的内存限制是2000MB而活动语句限制是10,每个通过该队列提交的查询会默认拿到200MB内存。可以以每个查询为基础使用statement_mem服务器配置参数覆盖默认的内存分配(最高到队列内存限制)。一旦一个查询开始执行,它会在队列中保持分拨给它的内存直至完成,即便在执行中它实际消耗的内存比分配到的内存少也是如此。用户可以使用 statement_mem 服务器配置参数来覆盖当前资源队列设置的内存限制。在会话级别,用户可以增加statement_mem,最高到资源队列的MEMORY_LIMIT。这将允许个别查询使用分配给整个队列的所有内存而不影响其他资源队列。 

        statement_mem的值会被max_statement_mem配置参数(是一个超级用户参数)覆盖。对于一个设置有MEMORY_LIMIT的资源队列中的查询,statement_mem的最大值是min(MEMORY_LIMIT, max_statement_mem)。当一个查询被允许进入时,分配给它的内存会被从MEMORY_LIMIT中减去。如果MEMORY_LIMIT被耗尽,同一个资源队列中的新查询必须等待。即使ACTIVE_STATEMENTS还没有达到时也会发生这种事情。如果在一个队列上没有设置MEMORY_LIMIT,查询都被准许进入,直到所有的ACTIVE_STATEMENTS槽被用尽,并且每个查询可以设置一个任意高的statement_mem这可能导致资源队列使用无限量的内存。

        经实践发现设置了低statement_mem参数(比如1-3MB的范围内)的低内存需求的查询会有更好的性能表现。在单个查询的基础上使用statement_mem服务器配置参数来覆盖队列的设置。例如:

SET statement_mem='2MB';

你可能感兴趣的:(数据库)