GaussDB(DWS)的query_band负载识别与应用

举报
门前一棵葡萄树 发表于 2023/04/12 16:04:38 2023/04/12
【摘要】 GaussDB(DWS)实现了基于query_band的负载识别和优先级调度,一方面提供了更为灵活的负载识别手段,不再局限于依据“用户-资源池”的映射关系将作业路由至对应资源池,提供了“键值对-资源池”的路由方式;另一方面实现了作业优先级调度,出现排队时按照优先级调度作业。

query_band概述

GaussDB(DWS)实现了基于query_band的负载识别和优先级调度,一方面提供了更为灵活的负载识别手段,不再局限于依据“用户-资源池”的映射关系将作业路由至对应资源池,提供了“键值对-资源池”的路由方式;另一方面实现了作业优先级调度,出现排队时按照优先级调度作业

管理员用户可根据业务场景及作业类别配置query_band关联的资源池和优先级等实现更为灵活的负载管理。如果业务未配置query_band或用户未将query_band关联行为时,作业会默认使用用户关联的资源池和默认优先级(Medium)。

query_band是什么?

query_band是一个USERSET级别(支持会话内设置)的GUC参数,本身是符串类型,支持任意形式字符组合。query_band用于负载识别时,为了便于区分、解决无意义字符串难以理解的问题,仅支持识别键值对形式的字符串。query_band键值对有以下限制:

  • 支持识别键值对形式的字符串,即:“key=value”;
  • 有效字符:数字0~9、大写字母A~Z、小写字母a~z以及部分符号(‘.’‘-’‘_’ 以及‘#’);
  • 单个键值对最大长度1024
  • 支持多个键值对组合,键对之间使用分隔;
  • 示例:SET query_band = ‘JobName=abc;AppName=test;ApplicationName=jdbc’

query_band负载识别

GaussDB(DWS)提供的资源管理功能,从资源池维度实现了资源隔离管控和查询调度,借此实现了不同业务间的资源隔离。资源池作为资源管控和查询调度的基本单位,查询运行前需要确定使用哪个资源池,在查询调度和查询运行过程中使用该资源池资源(计算资源/并发等)。

查询是由用户发起运行的,而且一般情况下用户都是按业务划分的,因此理所当然地就想到将用户和资源池关联起来,以此实现用户的查询在对应资源池运行的效果。GaussDB(DWS)提供了用户-资源池关联的能力,默认情况下用户关联默认资源池,可根据业务需求创建自定义资源,并将用户关联至自定义资源池,用户查询依据“用户-资源池”的关联关系将查询路由至对应资源池执行,以此实现对查询并发、内存及CPU资源的管控。从而实现对不同业务之间的资源限制和隔离,满足数据库混合负载需求,保证查询执行时资源调度的有序可控。

“用户-资源池”提供的用户和资源池的关联关系,对于用户和业务混合交叉(多个用户均对应多个业务)的场景就不适用了。此外一个资源池内不同用户的作业可能有不同优先级,此时就需要给不同用户或业务配置不同优先级,实现优先级调度。因此就需要提供一种能力,一方面不再局限于“用户-资源池”的关联方式,一方面还可以实现资源池内的优先级调度。这种情况下,query_band负载识别应运而生。

query_band负载识别提供了两方面能力:

  • 一方面提供了更为灵活的负载识别手段,不再局限于依据“用户-资源池”的映射关系将作业路由至对应资源池,提供了“键值对-资源池”的路由方式;
  • 另一方面实现了优先级调度,支持为不同用户或业务设置不同的优先级,实现资源池内的优先级调度。

query_band功能实现

工作原理

query_band负载识别以键值对为单位,用户使用的键值对可能有很多,但实际上关联负载行为的键值对只有很少的一部分,为方便后续理解,这里按是否关联负载行为,将键值对分为有效键值对和无效键值对:

有效键值对:有关联负载行为;

无效键值对:未关联任何负载行为。

会话内设置的query_band可能包含多个键值对,不同场景下可能要使用不同的键值对进行负载识别,以实现负载控制(分时/分天)。当query_band内包含唯一有效键值对时,使用该键值对进行负载识别;当query_band内包含多个有效键值对时,按以下规则选择有效键值对进行负载识别:

  • 键值对匹配顺序不同时,优先选择匹配序号最小的键值对进行负载识别;
  • 所有键值对匹配顺序相同时,按照先后顺序选择靠前的键值对进行负载识别

示例:假设set query_band='b=1;a=3;c=1'中所有键值对匹配顺序都一样,则选择b=1进行负载识别;假设set query_band=‘b=1;a=3;c=1’ ,其中b=1顺序为-1,a=3顺序为4,c=1顺序为1,则选择c=1进行负载识别。

识别能力

管理员用户根据业务场景和负载变化,调整业务(不同业务对应不同query_band键值对)使用的资源池和调度优先级。业务运行过程中负载识别与query_band工作机制如下:

  1. 会话内设置query_band,示例:SET query_band='JobName=abc;UserName=elk';
  2. 负载管理模块解析query_band,判断其中是否包含有效键值对;
  3. query_band内不包含有效键值对,则使用"用户-资源池"的方式将作业路由至对应资源池运行,同时设置作业优先级为Medium;
  4. query_band内包含有效键值对,则使用“键值对-资源池”的方式将作业路由至对应资源池运行,同时设置作业优先级为键值对关联优先级;
  5. 作业在对应资源池,按照设置的优先级进行排队,等待查询调度。

优先级调度

query_band支持高中低(High/Medium/Low)三个优先级,同时提供Rush作为特殊优先级(VIP通道),默认优先级为Medium。实践过程中,建议大部分作业使用Medium优先级,优先级较低作业使用Low优先级,特权作业使用High优先级,High作业不建议过多。Rush优先级作为特殊场景下应急使用,平时不建议使用

调度时优先调度高优作业,高优作业全部调度完才调度低优作业,GaussDB(DWS)包含多个优先级队列。除动态负载管理场景下,CN全局并发控制队列不支持优先级调度外,以下队列均支持优先级调度(按优先级顺序调度):

  • 静态负载管理场景下,CN全局并发控制队列;
  • 动态负载管理场景下,CCN全局内存管控队列;
  • 资源池并发控制和内存管控队列。(动态静态均支持)

作业运行过程中可通过pgxc_session_wlmstat/pg_session_wlmstat视图查询作业优先级,视图中优先级显示为INT类型,数字和优先级对应关系如下:

视图显示数字 0 1 2 4 8
对应优先级 不管控 LOW MEDIUM HIGH RUSH

query_band对外接口

gs_wlm_set_queryband_action

提供FUNCTION:gs_wlm_set_queryband_action(query_band cstring, action cstring, order int4)用于设置query_band负载行为,函数返回值类型为bool,表示函数调用是否成功,包含三个入参,含义如下:

  • query_band:query_band键值对
  • action:负载行为
  • order:匹配顺序(序号),缺省参数,默认值-1

应用示例:设置query_band键值对“UserName=elk”关联资源池p1、优先级Rush、匹配顺序为1。

SELECT * FROM gs_wlm_set_queryband_action('UserName=elk','respool=p1;priority=rush',1);

应用示例:取消设置的query_band行为,将query_band行为设置为默认即为取消关联的行为:

SELECT * FROM gs_wlm_set_queryband_action('UserName=elk','respool=NULL;priority=medium',-1);

gs_wlm_set_queryband_order

提供FUNCTION:gs_wlm_set_queryband_order(query_band cstring, order int4)用于修改query_band匹配顺序,函数返回值类型为bool,表示函数调用是否成功,包含两个入参,含义如下:

  • query_band:query_band键值对
  • order:匹配顺序(序号),缺省参数,默认值-1

除-1外,不允许两个query_band键值对使用相同匹配顺序,设置query_band键值对匹配顺序时,如果存在query_band持有该匹配顺序,则其顺序自动+1,重复上述步骤直至无相同匹配顺序的query_band键值对存在。匹配顺序中-1最大,代表匹配优先级最低,最小值为0,代表匹配优先级最高。

应用示例:假设query_band键值对“UserName=elk”的匹配顺序为1,“UserName=bin”的匹配顺序为2,“UserName=yagao”的匹配顺序为3,此时设置query_band键值对“UserName=on”匹配顺序为1。

SELECT * FROM gs_wlm_set_queryband_order('UserName=on',1);

设置完成后,query_band键值对匹配顺序如下:

query_band键值对 UserName=on UserName=elk UserName=bin UserName=yagao
匹配顺序 1 2 3 4

系统表pg_workload_action

query_band支持多种负载行为,使用系统表pg_workload_action存储不同query_band键值对对应的负载行为。为了后续扩展性(新增负载行为不需要新增字段),系统表设计采用一行对应一个负载行为的方式存储,当一个query_band键值对关联多个负载行为时,每个负载行为存储一行数据。系统表包含四个字段:

  • qband:键值对
  • class:负载行为类别
  • object:负载行为名称
  • action:关联的负载行为

query_band目前支持以下负载行为,其中query_band键值对的匹配顺序(序号)也作为一种负载行为存储在系统表中。

类别 行为名称 负载行为 默认值
workload respool 对应资源池 null
workload priority 优先级 Medium
order 无效字段 序号 -1

备注:默认值不需要存储在系统表中;资源池保存的是OID。

示例:假设已经设置query_band键值对“UserName=elk”关联资源池p1、优先级Rush、匹配顺序为1;“UserName=on”关联资源池p1、优先级Medium、匹配顺序为-1。查询pg_workload_action结果如下:

postgres=# select * from pg_workload_action order by 1,2;
    qband     | classname | objname  | action
--------------+-----------+----------+--------
 UserName=elk | order     | respool  | 1
 UserName=elk | workload  | respool  | 16722
 UserName=elk | workload  | priority | rush
 UserName=on  | workload  | respool  | 16722
(4 rows)

pg_queryband_action视图

pg_workload_action系统表用于存储query_band键值对负载行为,查询query_band行为可以直接查询该表,但是随着每一个负载行为显示一行的方式易用性较差,因此我们提供了pg_queryband_action用于查询所有query_band键值对的负载行为,每一行对应一个键值对的所有负载行为。

示例:假设已经设置query_band键值对“UserName=elk”关联资源池p1、优先级Rush、匹配顺序为1;“UserName=on”关联资源池p1、优先级Medium、匹配顺序为-1。查询pg_queryband_action结果如下:

postgres=# select * from pg_queryband_action;
    qband     | respool_id | respool | priority | qborder
--------------+------------+---------+----------+---------
 UserName=on  |      16722 | p1      | Medium   |      -1
 UserName=elk |      16722 | p1      | rush     |       1
(2 rows)

query_band应用

基础应用

创建资源池respool_1,并创建用户user_1关联资源池respool_1、respool_2。不设置query_band负载行为场景下,使用user_1用户运行作业,此时user_1作业全部路由至respool_1运行,优先级为Medium。

设置query_band键值对"JobName=elk"的负载行为为关联资源池respool_2,优先级为Medium;设置query_band键值对"JobName=on"的负载行为为优先级High。user_1用户分别设置不同的query_band运行作业,不同作业运行方式、关联资源池及作业优先级如下表所示:

作业运行方式 资源池 优先级
作业1:会话内不设置query_band,运行作业 respool_1 Medium
作业2:会话内set query_band='JobName=elk',运行作业 respool_2 Medium
作业3:会话内set query_band='JobName=on',运行作业 respool_1 High

扩展应用(用户优先级调度)

创建资源池respool_1,并创建用户user_1、user_2、user_3关联资源池respool_1。不设置query_band负载行为场景下,使用user_1、user_2和user_3用户运行作业,此时user_1、user_2和user_3作业全部路由至respool_1运行,优先级均为Medium。

设置query_band键值对"UserName=elk"的优先级为High;设置query_band键值对"UserName=on"的优先级为Low。

备注:“UserName=elk”、“UserName=on”只用于用户标识,没有特殊含义,用户可按需配置。

按以下方式设置用户默认query_band:

ALTER USER user_2 SET query_band='UserName=elk';
ALTER USER user_3 SET query_band='UserName=on'; 

会话内不单独设置query_band,使用user_1、user_2和user_3用户运行作业,此时user_1作业优先级为Medium(默认优先级),user_2作业优先级为High(对应键值对“UserName=elk”),user_3作业优先级为Low(对应键值对“UserName=on”)。

此外,用户还可设置包含多个键值对的query_band,在不同场景下(或不同时间段),按照不同键值对进行负载识别,实现更为灵活的负载控制,这里就不再赘述了。

多维度负载识别-应用示例

下面以现网实际应用中的一个场景为例,演示query_band多维度负载识别应用配置:

XX局点业务全部使用一个用户执行,用户希望将入库和查询进行资源隔离,但是无法将入库和查询业务划分至不同用户执行,此时就需要用到query_band的多维负载识别能力。

应用query_band前,集群内只有一个用户(user_elk)使用默认资源池。按以下步骤配置资源隔离:

  1. 创建资源池respool_select(具体配置略),并将用户user_elk关联至资源池respool_select(默认情况下用户所有SQL路由至respool_select);
  2. 创建资源池respool_upsert(具体配置略);
  3. 配置query_band,将入库路由至资源池respool_upsert运行:
    postgres=# SELECT * FROM gs_wlm_set_queryband_action('Jobname=copy_upsert', 'respool=respool_upsert');
     gs_wlm_set_queryband_action
    -----------------------------
     t
    (1 row)
  4. 修改用户业务,入库业务会话内设置query_band:SET query_band='Jobname=copy_upsert';--执行业务;--作业执行完重置query_band:reset query_band;示例:
    postgres=> SET query_band='Jobname=copy_upsert';
    SET
    postgres=> INSERT INTO t1 SELECT generate_series(1,10000);
    INSERT 0 10000
    postgres=> RESET query_band;
    RESET
  5. pg_queryband_action,确认query_band配置成功:
    postgres=# select * from pg_queryband_action;
            qband        | respool_id |    respool     | priority | qborder
    ---------------------+------------+----------------+----------+---------
     Jobname=copy_upsert | 2147483648 | respool_upsert | medium   |      -1
    (1 row)
  6. 查询TopSQL实时视图,确认query_band是否生效
    postgres=# SELECT username, query_band, resource_pool, substr(query, 1, 30) FROM pgxc_wlm_session_statistics WHERE query_band IS NOT NULL;
     username |     query_band      | resource_pool  |             substr
    ----------+---------------------+----------------+--------------------------------
     user_elk | Jobname=copy_upsert | respool_upsert | INSERT INTO t1 SELECT generate
    (1 row)

按照以上步骤配置完成资源隔离后,即可实现入库业务和查询业务的资源隔离。具体资源池配置已省略,可按照实际场景配置并发/内存/CPU隔离参数,参考:https://support.huaweicloud.com/mgtg-dws/dws_01_07233.html

优先级调度-应用示例

上文中提到,query_band支持高中低(High/Medium/Low)三个优先级,同时提供Rush作为特殊优先级(VIP通道),默认优先级为Medium。默认情况下作业优先级均为Medium,作业排队时按照FIFO规则进行调度。混合负载场景下,不同业务可能有不同优先级,此时就需要用到query_band优先级调度。假设集群内有一个用户bin,关联资源池respool_bin,bin同时运行以下几类业务:入库、查询、API接入,其中查询优先级最高,入库优先级次之,API接入优先级最低。使用query_band配置业务优先级:

  1. 配置查询优先级为High:
    postgres=# SELECT * FROM gs_wlm_set_queryband_action('Jobname=select', 'priority=high');
     gs_wlm_set_queryband_action
    -----------------------------
     t
    (1 row)
  2. 配置API接入优先级为Low:
    postgres=# SELECT * FROM gs_wlm_set_queryband_action('Jobname=api', 'priority=low');
     gs_wlm_set_queryband_action
    -----------------------------
     t
    (1 row)
  3. 修改查询业务,会话内设置query_band:SET query_band='Jobname=select';--执行业务;--作业执行完重置query_band:reset query_band;示例:
    postgres=> SET query_band='Jobname=select';
    SET
    postgres=> SELECT COUNT(1) FROM t1;
     count
    -------
     20000
    (1 row)
    
    postgres=> RESET query_band;
    RESET
  4. 修改API接入业务,会话内设置query_band:SET query_band='Jobname=api';--执行业务;--作业执行完重置query_band:reset query_band;示例:
    postgres=# SET query_band='Jobname=api';
    SET
    postgres=# SELECT COUNT(1) FROM (SELECT wt1.c1, wt1.c2 FROM wt1, wt2 WHERE wt1.c2 = wt2.c2);
     count
    -------
     20000
    (1 row)
    
    postgres=# RESET query_band;
    RESET
    
  5. 查询pg_queryband_action,确认query_band配置成功:
    postgres=# select * from pg_queryband_action;
            qband        | respool_id |    respool     | priority | qborder
    ---------------------+------------+----------------+----------+---------
     Jobname=api         |          0 | NULL           | low      |      -1
     Jobname=select      |          0 | NULL           | high     |      -1
    (2 rows)
  6. 查询TopSQL实时视图和负载管理视图,确认query_band优先级调度是否生效:
    postgres=# select s.usename,s.priority,a.query_band,substr(s.query,1,30) from pgxc_session_wlmstat s, pgxc_wlm_session_statistics a where s.threadid=a.pid;
     usename | priority |   query_band   |             substr
    ---------+----------+----------------+--------------------------------
     usr1    |        4 | Jobname=select | SELECT COUNT(1) FROM t1;
     usr1    |        2 |                | INSERT INTO t1 SELECT generate
     usr1    |        1 | Jobname=api    | select count(1) from (select w
    (3 rows)
  7. 821及以上版本也可以查询gs_query_monitor视图,显示效果更好:
    postgres=# select usename,priority,query_band,substr(query,1,30) from gs_query_monitor;
     usename | priority |   query_band   |             substr
    ---------+----------+----------------+--------------------------------
     usr1    | High     | Jobname=select | SELECT COUNT(1) FROM t1;
     usr1    | Low      | Jobname=api    | select count(1) from (select w
     usr1    | Medium   |                | INSERT INTO t1 SELECT generate
    (3 rows)


参考文档:

资源池创建修改用户指南:https://support.huaweicloud.com/mgtg-dws/dws_01_07233.html

GaussDB(DWS)资源管理排队原理与问题定位:https://bbs.huaweicloud.com/blogs/386595 

GaussDB(DWS)网络调度与隔离管控能力:https://bbs.huaweicloud.com/blogs/393327

GaussDB(DWS)的CPU资源隔离管控能力:https://bbs.huaweicloud.com/blogs/355346

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。