理论+示例,详解GaussDB(DWS)资源管理
Posted 华为云开发者社区
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了理论+示例,详解GaussDB(DWS)资源管理相关的知识,希望对你有一定的参考价值。
摘要:合理地管理和分配系统资源,是保证数据库系统稳定高效运行的关键。
本文分享自华为云社区《GaussDB(DWS)资源管理能力介绍与应用示例》,作者: 门前一棵葡萄树 。
一、资源管理能力
1.1 概述
数据库运行过程中使用的公共资源包含:系统资源(CPU、内存、网络等)和数据库共享资源(锁、计数等)。作业运行过程中总是希望获得更多的公共资源,以获得最好的执行性能。但是公共资源的滥用可能导致数据库系统的不稳定,引发资源过载,影响高优业务的QoS(服务质量),甚至阻塞业务运行。因此,合理地管理和分配系统资源,是保证数据库系统稳定高效运行的关键。
资源管理的目标:
- 防止资源过载,引发系统级故障;
- 实现高优业务的优先调度,保证高优业务QoS;
- 实现业务之间的资源隔离,防止业务之间资源争抢严重;
- 实现业务的错峰分时调度,防止瞬时高并发影响系统稳定性;
- 快速识别异常查询,保证正常业务稳定运行。
1.2 基本原理
资源池是一种用于对系统资源进行划分的技术,通过为资源池设置资源上限的方式,实现对其内运行作业的资源管控。资源池可以帮助系统管理员更好地管理和分配系统资源,提高系统的可用性和稳定性。
GaussDB(DWS)提供了资源管理功能,借助资源池实现业务之间的资源隔离和查询调度(不同业务路由至不同资源池)。GaussDB(DWS)支持两种路由策略:
- 用户-资源池:将用户关联至资源池,用户执行作业时,根据“用户-资源池”的关联关系,将作业路由至对应资源池执行。
- query_band负载识别:业务设置query_band(USERSET参数),根据query_band和资源池关联关系,将作业路由至对应资源池执行。
实际应用过程中,建议优先使用用户-资源池的路由方式;在用户-资源池的路由方式无法满足隔离诉求时,使用query_band负载识别实现业务隔离。
1.3 能力介绍
GaussDB(DWS)支持负载管理、资源管控、异常规则、查询过滤器以及负载计划等资源管理能力,不同的资源管理能力有不同的使用场景,实际应用中可能会用到其中1~N个资源管理能力。
1.3.1 负载管理
支持基于并发和估算内存的查询调度,防止并发过大引发资源争抢严重、导致查询堆积。多CN场景下,CN之间互相不感知负载情况,因此无法精确控制整个集群的并发和内存使用,可能触发内存不足报错。因此为保证多CN场景下的并发和内存可控,设计实现CCN用于查询的统一调度。CM在第一次集群启动时,通过集群部署形式,选择编号最小的CN作为CCN,CCN故障之后,由CM选择新的CCN进行替换。
虽然CCN管控可以实现更为精准的管控,但是CCN管控逻辑更为复杂且涉及CN-CCN间通信,通信延迟(10ms~1s之间)和复杂的管控逻辑可能导致作业性能不稳定,此外CCN还可能成为提高系统并发的瓶颈。因此设计实现“短查询加速”功能,实现对简单查询和复杂查询的分别管控。复杂查询执行时间长、内存消耗大,CCN管控对其性能影响有限;简单查询执行时间短、内存消耗小,CN管控可以降低管控对其的性能影响。CCN管控的主要目的是防止内存不足报错,因此我们根据估算内存对查询进行分类:
- 简单查询:估算内存小于32MB;
- 复杂查询:估算内存大于等于32MB。
为提升简单查询性能,默认情况下简单查询只进行并发控制,而不进行内存和CPU管控。实际应用场景下,优先级低的业务可能性能不敏感,而且需要精准管控其使用的CPU和内存资源,此时简单查询也需要进行资源管控。为适应更多的使用场景,短查询加速功能支持开启和关闭:
- 开启短查询加速:简单查询在CN进行管控,复杂查询在CCN管控;
- 关闭短查询加速:不区分简单查询和复杂查询,所有查询均在CCN进行管控。
为了便于区分,我们将CN管控称为快车道,CCN管控称为慢车道。快车道只在CN上进行并发控制,不支持内存和CPU管控;慢车道在CCN上进行并发和内存控制,同时支持CPU管控。其中,快车道并发对应资源池max_dop参数,慢车道并发对应资源池active_statements参数,慢车道内存对应资源池mem_percent参数。
1.3.2 CPU资源管控
GaussDB(DWS)基于cgroups实现了两种CPU管控能力:基于cpu.shares的共享配额管控和基于cpuset的专属限额管控。
专属限额限制资源池内作业可以使用的CPU核,隔离更为彻底,用于防止低优作业占用过多CPU,影响高优作业性能。
共享配额仅在CPU繁忙时生效,不同资源池之间按照配额比例轮询占用CPU,不同业务之间存在CPU争抢,可能影响业务性能。
1.3.3 网络管控(821以上版本支持)
GaussDB(DWS)支持基于SP+DWRR算法的网络调度与基于令牌桶的网络流控,实现资源池之间按比例的网络调度的同时,实现了网络欠佳SQL的降级与流控。
1.3.4 空间管控(非本文重点)
空间管控主要有两层目的:一是防止磁盘满,一是对业务使用磁盘空间进行限制。GaussDB(DWS)支持以下空间管控能力:
数据库只读:CM每10分钟检测一次数据盘使用率,使用率超过阈值时,设置数据库只读;使用率低于阈值时,解除数据库只读。数据库只读情况下,只允许只读作业执行。数据库只读后,通过读写事务内执行DROP/TRUNCATE清理磁盘空间: " START TRANSACTION READ WRITE;DROP/TRUNCATE TABLE;COMMIT; "。
用户空间管控:限制用户在单个CN/DN上可以使用的空间上限,根据表的属主(owner)进行管控,而不管执行插入的用户是谁。相关语法:CREATE ALTER USER xxx PERM SPACE ‘xxx G/M/K’。
Schema空间管控:提供Schema级别的单实例空间管控能力,相关语法:CREATE/ALTER SCHEMA xxx WITH PERM SPACE \'xx G/M/K\'。
1.3.5 异常规则
异常规则用于预防单个作业占用资源过多、执行时间过长,防止单个作业长时间大量占用资源,导致系统整体吞吐下降、影响其他作业性能。GaussDB(DWS)支持以下异常规则:
1.3.6 查询过滤器
GaussDB(DWS)查询过滤器提供查询过滤功能,对加入黑名单的作业进行过滤,禁止执行。主要应用场景包含以下两种:
- 异常熔断机制:配置异常规则后,作业频繁触发异常规则,对于触发异常规则次数达到阈值的查询自动加入黑名单进行过滤。
- 紧急拦截:作业引发CORE、hang或性能大幅下降等问题时,需要紧急规避时,可以将作业加入黑名单进行过滤。
1.3.7 资源管理计划
用户在不同时间需要重点保障的业务可能不一样,每个业务所需的并发和资源在不同时间段也可能不相同,因此用户在不同时间所需的资源管理配置可能就有所不同。资源管理计划支持在指定时间自动切换资源管理配置,用户可按需创建多个资源管理计划。创建资源管理计划、配置计划生效时间并启动计划后,GaussDB(DWS)将在计划生效时间自动切换资源配置。
1.4 能力边界(注意点)
首先,需要明确的一点是资源管理不是万能的,并不是所有的资源类问题资源管理都能解决,大部分资源不足类问题资源管理基本都解决不了。 其次需要清楚资源管理有两个主要目的:其一是为了避免资源的无序使用,从而防止系统级故障的发生,同时避免查询堆积的情况出现;其二是为了实现业务之间的资源隔离,防止不同业务之间因为资源争抢而导致高优业务性能下降,从而影响高优业务的QoS。明确了以上几点,我们再来看资源管理能干什么、不能干什么,可能就更好理解了:
- 资源管理可以对业务并发进行限制,实现流量削峰。但是限制并发也就意味着吞吐量的下降,如果业务并发持续走高,限制并发可能导致业务运行不完,不限制并发又会影响其他业务,此时可能就需要考虑其他方法提升业务性能(扩容/升配/SQL优化)。
- 资源管理并不能提升系统整体吞吐量,相反,资源隔离很有可能降低系统整体吞吐。例如:应用资源管理前,CPU持续飙高在90%以上,查询堆积严重,业务运行不完。这种情况下对低优业务进行CPU限额隔离后,很有可能可以大幅降低CPU使用率;但是相应的低优业务可能大面积报错或无法完成。
- 资源管理可以实现资源隔离与管控,但是相较于无背景压力,隔离管控后业务性能可能还是有所损耗。例如:有些用户只对低优业务进行了CPU限额管控,而没有对高优业务进行CPU管控。此时高优业务和低优业务很可能使用相同CPU,此时CPU使用率可能不到100%、甚至不足90% 。但是相对无背景压力,同一时刻请求同一CPU的线程会更多,因此CPU调度时延也就越大。想要完成隔离CPU对性能的影响,需要对两个业务都进行CPU限额管控,但是进行限额管控后,相对无背景压力使用所有CPU性能可能也是有所下降的,此处不再展开。
- 资源管理并不能提升作业性能。有些用户业务并发大、资源需求高,但是系统资源却很少。业务串行可能都难以正常运行结束,此时想通过资源管理保障业务正常运行,基本是不可行的,最好的办法还是扩容/升配/SQL优化。
二、应用示例
2.1 确认业务场景
资源管理的目的是对业务进行隔离管控,因此设计资源管理方案前,首先需要确认用户业务场景:业务分类、业务优先级、业务类型、业务并发情况、业务执行时间段以及业务高峰时间段。
- 确认业务分类,才能确定应该划分几个资源池;
- 确认业务优先级,才能确定应该给哪个资源池多预留资源和并发;
- 确认业务并发和业务类型,才能确定是否需要进行并发控制和异常规则;
- 确认业务执行时间段,才能确认是否需要使用资源管理计划;
- 确认业务高峰时间段,才能确认预留多少资源和并发合适。
为了避免过多的资源池对整体吞吐率产生负面影响,同时为了简化资源管理方案,建议将资源池数量控制在5个以下,最好是3个及以下。如果业务分类较少(3个及以下),可以为每个业务分类创建一个资源池,以便更好地进行分类管理。如果业务分类较多,可以将优先级相同的业务归为同一类,并使用同一个资源池来管理。
业务优先级一般分为以下几类:
- 性能敏感的高优业务:该类业务一般执行时间短、业务并发不大,对性能非常敏感,一般不接受性能抖动;
- 无时效性要求的低优业务:该类业务对执行性能没有要求,一般只要能出结果就行,包括但不限于:外围应用查询、自助分析业务等;
- 其他有一定性能要求的业务:该类业务普遍并发较大、执行时间较长,对性能有一定要求,但是可以有性能抖动,比如:标准报告、实时入库等。
2.2 明确管控诉求
确认业务场景后,下一步就需要和用户明确管控诉求。第一步确认业务场景后,其实已经可以形成初步资源管理方案,比如:应该创建几个资源池、限制低优业务并发和资源使用(限额)、是否使用资源管理计划等。
示例:
业务场景:用户业务包含:入库、查询和外部接入。其中入库和查询使用同一用户(user1),外部接入使用一个用户(user2);入库优先级略低于查询且入库不能影响查询性能,外部接入优先级很低、接受报错和长时间不出结果;入库并发较大、消耗CPU较高。
对于以上业务场景,有以下基本诉求和初步资源管理方案:
- 有三类业务且优先级各不相同,且各业务间有隔离管控诉求,因此需要创建3个资源池;
- 所有业务全部使用自建资源池,资源池进行并发控制,因此单CN并发上限(max_active_statements)可以设置一个较大值(建议300/500);
- 外部接入优先级低,因此考虑外部接入并发设置小一些,CPU核分配少一些,同时考虑到对其进行严格的CPU管控,因此关闭短查询加速;
- 入库和查询使用同一用户,因此需要用到query_band负载识别,用于区分入库和查询业务;
- 入库优先级略低于查询且入库不能大幅影响查询性能,因此考虑对入库和查询均进行CPU限额管控,同时关闭短查询加速;
- 查询估算内存可能存在偏差,当估算过大时可能导致异常排队,因此建议设置查询估算内存上限。
初步资源管理方案资源池配置如下:
单CN并发上限:max_active_statements = 300/500 ??
其中,参数值后有“??”的表示参数大小为初步预估,需要与用户沟通确认参数最终大小。
形成初步资源管理方案后,与用户针对资源管理方案进行讨论,确认管控诉求:
- 资源池:确认资源池数量是否合适,业务与资源池对应关系是否合适(可能存在多个业务对应一个资源池的情况);
- 并发控制:各业务是否需要并发控制,并发上限是否合适;(资源管理上线前并发上限较难预估,一般前期会给一个比较大的值,后续上线后根据实际运行效果调整)
- 内存管控:业务是否需要内存管控,内存大小设置是否合理;(内存资源充足、业务间内存争取不严重的场景下不需要内存管控;内存设置过小,内存管控可能导致不必要的排队,影响系统吞吐)
- 查询估算内存限制:可以通过TopSQL历史记录中作业估算内存和实际使用内存判断是否合理;(估算内存上限设置过小可能影响作业性能,设置过大可能因为估算偏差导致异常排队,需要综合业务性能和内存使用情况考虑)
- CPU管控:通过资源管理上线前,CPU使用率情况确认是否存在CPU瓶颈,同时确认后续是否有新业务上线;(存在CPU瓶颈或者后续可能上限大批新业务情况下建议提前配置好CPU管控,预防业务上线后大幅影响高优业务性能)
- 资源管理计划:业务高峰时间段不同的情况下,可能需要用到资源管理计划,在不同时间段重点保障不同业务;
- 其他管控诉求:确认用户是否有其他管控诉求,比如:设置异常规则,防止查询堆积和资源争抢严重(虽然进行了资源隔离,但是烂SQL可能影响本业务内其他作业)。
以上只是列举了常见的管控诉求讨论点,实际应用中可以多发散。
三、 配置资源管理
以上一章节中资源管理方案为例,说明如何配置资源管理方案。
3.1 配置资源池
如下图所示,以respool_select资源池为例,按照用户指南添加资源池中步骤添加资源池。名称填写“respool_select”;CPU资源选择专属限额,限额50%;内存资源限额50%;查询并发(特指慢车道并发)上限100。填写完成后点击确认,完成资源池添加。资源池操作说明详见:添加资源池、修改资源池、删除资源池。
添加资源池完成后,显示下图所示界面。刚刚配置完成的参数在资源配置标签内显示;短查询加速默认开启且不限制简单语句并发上限;中间位置显示资源池关联的异常规则,默认情况下关联有两个默认异常规则:单DN平均消耗CPU占比不超过50%,单DN算子下盘不超过数据盘的1/10,超过限制后作业报错退出;最下方显示资源池关联的用户,点击关联用户按钮将“查询用户”关联至该资源池。同理创建另外两个资源池,并将“外部接入用户”关联至respool_other资源池。
注:对于需要设置自定义异常规则的资源池,在下方异常规则标签栏点击编辑即可配置异常规则。
3.2 短查询加速配置
在资源池下拉列表中选择刚刚添加的资源池respool_select,点击短查询配置右上方的编辑,修改简单语句并发为150,修改完成后点击保存。
对于另外两个资源池,需要关闭短查询加速,在资源池下拉列表中选择对应资源池后,点击短查询配置中“短查询加速”开关,关闭短查询加速。
3.3 查询估算内存设置
查询估算内存上限暂时还不支持在界面配置,可以通过DAS执行SQL直接修改:
3.4 配置query_band
1. 修改用户入库业务,入库业务会话内设置query_band:SET query_band=\'Jobname=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
2. 配置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)
3. 查询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)
4. 运行入库作业过程中,查询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)
3.5 其他配置
1. 需要使用资源管理计划的,可以参考资源管理计划操作配置资源管理计划。
2. GaussDB(DWS) 8.2.1及以上版本支持网络资源管控,假设三个资源池网络带宽权重配比为respool_select:respool_upsert:respool_other = 5:4:1,使用DAS执行以下SQL配置网络管控:
ALTER RESOURCE POOL respool_select WITH(WEIGHT=5); ALTER RESOURCE POOL respool_upsert WITH(WEIGHT=4); ALTER RESOURCE POOL respool_other WITH(WEIGHT=1);
配置示例参见下图:
假设外部接入业务运行超过20min,且网络带宽占用超过128MB降级:
CREATE EXCEPT RULE bandwidth_rule1 WITH(bandwidth=128, ELAPSEDTIME=1200, action=\'penalty\'); -- 创建异常规则 ALTER RESOURCE POOL respool_other WITH(EXCEPT_RULE=\'bandwidth_rule1\'); -- 将异常规则关联至资源池respool_other
配置示例参见下图:
一文详解GaussDB(DWS) 的并发管控和内存管控
摘要:DWS的负载管理分为两层,第一层为cn的全局并发控制,第二层为资源池级别的并发控制。
本文分享自华为云社区《GaussDB(DWS) 并发管控&内存管控》,作者: fighttingman。
1背景
这里将并发管控和内存管控写在一起,是因为内存管控实际是通过限制语句的并发达到内存管控的目的的。内存管控是基于语句的估算内存的前提下进行管控的,通俗的说就是语句有个估算内存,当资源池的剩余内存小于语句的估算内存时,这个语句就会排队等待,等资源池内的语句执行完,资源池有足够的剩余内存的时候,才会让这个语句执行。所以内存管控的实际效果和语句的估算内存有很大关系,估算的大了就会造成大量语句排队,实际没有使用那么多内存,造成内存资源浪费,相反估算的小了,就会有很多语句下发,实际内存使用就会变多,就有语句报内存不足的错误风险。
数据库系统的并发控制,在整个系统中起着很重要的作用,比如很多用户的业务压力过大时,有时会导致连接数量被占满,有时会导致某种计算资源被占满,有时会导致存储空间被占满,这些情况都会导致整个集群进入异常甚至不可用的状态:正在执行的作业互相争抢CPU,会导致大家都不能好好执行;大量作业执行时,占用大量内存,很容易触发到内存瓶颈,造成作业内存不可用问题,导致业务报错等等。在不进行并发控制的情况下,这些情况都很可能会出现,影响到正常业务。
2 总体介绍
DWS的负载管理分为两层,第一层为cn的全局并发控制,第二层为资源池级别的并发控制。在通过第一层控制的时候,会继续向前走到第二层资源池控制,根据资源池当前的负载资源情况决定作业继续执行或者排队。
基于DWS并发控制逻辑看出,实际作业执行中,可能会在两种队列中排队:
一种是全局队列(global queue)这种队列不区分简单和复杂作业,也不区分是DDL或者是普通语句,这种是每个cn生效。
一种是资源池队列(resource pool queue),用户下发的一般语句会根据资源消耗估算以及复杂程度在这里进行判断是否排队。
在两层队列的过滤下,DWS会筛选出当前能执行的语句,使其正常运行,运行时也会受到其所属资源池资源的限制(只能使用资源池配置的CPU、内存、IO配额)。
3 全局排队
这里介绍几个常用视图以及SQL语句,可以迅速判断目前的业务出现问题的原因,受限根据以下视图可以看到目前的作业是不是在排队,之后要迅速分析为什么在排队,是因为负载管理各个参数配置问题,还是因为正在执行的语句占据了过多的资源导致的排队。
pgxc_stat_activity (活跃视图)
查询当前执行时间最长的语句的排队状态,query_id(数据库中作业的唯一标识),以及详细的语句信息。
select coorname,usename, current_timestamp-query_start as duration, enqueue,query_id,query from pgxc_stat_activity where state='active' and usename <> 'Ruby' order by duration desc;
根据该语句可以迅速判断出哪些语句执行时间很长,是什么样的语句执行很慢以及该语句的query_id,便于迅速进入下一步排查。
该视图中enqueue字段中如果显示waiting in global queue就代表在全局排队。全局排队是受GUC参数max_active_statements参数控制的,是单cn生效的,也就是每个cn都可以支持这么大的并发量。比如集群中有3个cn实例,GUC参数max_active_statements参数设置为60,也就是说每个cn都支持60个语句并发执行,集群全局支持3 * 60 = 180并发执行作业。当下发作业大于这个cn设置的max_active_statements的时候就会进行全局排队,在pgxc_stat_activity视图中enqueue字段就会显示waiting in global queue。
4 资源池排队
4.1 静态负载管理
当GUC参数enable_dynamic_workload设置为off的时候就代表是静态负载管理模式。静态负载管理的情况下,pgxc_stat_activity视图中enqueue字段只会有waiting in respool queue。并发控制参数为资源池的max_dop(简单作业)和active_statements(复杂作业)。
1)简单作业和复杂作业的定义
在静态负载管理中,简单作业是估算代价cost值小于GUC参数parctl_min_cost值的作业。反之则判定为复杂作业。该GUC参数默认为10W,
当parctl_min_cost为-1时,或者作业估算代价小于10时,作业都判定为简单作业。
2)简单作业并发限制
ALTER RESOURCE POOL resource_pool_a1 WITH (max_dop=10);
通过设置资源池的max_dop参数设置简单作业并发,关联资源池resource_pool_a1的用户都受到这个参数的控制。当所有关联这个资源池的用户的所有作业数量之和大于这个参数的时候,就会进行资源池排队,活跃视图enqueue字段就会显示waiting in respool queue。
3)复杂作业并发限制
ALTER RESOURCE POOL resource_pool_a2 WITH (active_statements=10);
通过设置资源池的active_statements参数控制复杂作业的并发数,关联资源池resource_pool_a2的用户都受到这个参数的控制。
- 当MEM_PERCENT参数数值为0时,ACTIVE_STATEMENTS为x(1~INT_MAX),该资源池上的作业并发数不大于x。
- 当ACTIVE_STATEMENTS参数数值为-1且MEM_PERCENT为正值时,并发由运行作业的内存估值和MEM_PERCENT的取值决定。
- 当MEM_PERCENT参数数值为正值且ACTIVE_STATEMENTS为x(1~INT_MAX)时,并发由运行作业的内存估值和MEM_PERCENT的取值决定,且并发不能大于x。
- 当MEM_PERCENT参数数值为0且ACTIVE_STATEMENTS为-1时,资源池并发不受限。
资源池使用并发点数的计数方式来计算可执行的复杂作业并发数量,并发点数计算公式为
作业使用内存点数:active_points = (query_mem/respool_mem) * active_statements * 100
作业使用并发点数:active_points = 100
资源池总点数:total_points = active_statements * 100
单位点数: 100
4)相关说明
- 资源池分快慢车道,快车道管控简单作业,慢车道管控复杂作业
- MAX_DOP对快车道并发进行限制,取值范围为-1 ~ INT_MAX,默认为-1,表示不管控。
- ACTIVE_STATEMENTS取值范围为 -1 ~ INT_MAX, 默认值为10,建议使用该默认值。当取值设置为0或者-1时,慢车道并发不受ACTIVE_STATEMENTS限制。
- MEM_PERCENT取值范围为0~100,当取值设置为0时,慢车道并发不受MEM_PERCENT限制。
- 慢车道并发受ACTIVE_STATEMENTS和MEM_PERCENT限制,同时点数由ACTIVE_STATEMENTS决定。当ACTIVE_STATEMENTS=-1或0时,total_points=90。total_points点数耗尽后,慢车道查询会触发排队操作,队列满足先进先出。
- query_mem为优化器估算的作业内存大小,即PG_SESSION_WLMSTAT视图中的statement_mem;作业无估算内存数值时,不进行并发控制。
- respool_mem为资源池的实际内存。
4.2 动态负载管理
当GUC参数enable_dynamic_workload设置为on的时候就代表是动态负载管理模式。动态负载管理的情况下,pgxc_stat_activity视图中enqueue字段会有waiting in respool queue和waiting in global queue。
1)简单作业和复杂作业的定义
动态负载管理下优化器估算内存大于32M认为是复杂作业,反之认为是简单作业。
运行中的作业复杂简单情况可以通过PG_SESSION_WLMSTAT中的attribute字段查看。
2)动态负载管理相关说明
- 集群有一个CN会作为中心协调节点(CCN),用于收集和调度作业执行,该节点可以通过cm_ctl query -Cv查询到,Central Coordinator State会显示其状态。当CCN不存在时,作业不再受动态负载管理控制。
- CCN上包含全局内存管控队列和资源池队列,目前暂不支持跨队列优先级,在以下场景下优先级低的作业可能优先下发:如果优先级高的作业在全局内存管控队列排队,优先级低的作业在资源池队列排队,则优先级低的作业会优先下发。
- 单CN上依然受到max_active_statements参数限制,但不是强制限制,实际运行的作业可能稍微大于该数值。
- 简单查询作业(估算值<32MB)、非DML(即非INSERT、UPDATE、DELETE和SELECT)语句,不走自适应负载,需要通过max_active_statements来进行单CN的上限控制。
- 默认work_mem数值为512MB,在自适应负载特性下,该数值不能变大,否则会引起内存不受控(例如未做Analyze的语句)。
- 作业估算内存小于等于0时,如果强制将作业指定为慢车道管控,作业不会发往CCN管控将直接运行。
- 以下场景或语句由于内存使用特殊性和不确定性,可能导致大并发场景内存不受控,如果遇到需要降低并发数。
- 单条元组占用内存过大的场景,例如,基表包含超过MB级别的宽列。
- 完全下推语句的查询。
- 需要在CN上耗费大量内存的语句,例如,不能下推的语句,withhold cursor场景。
- 由于计划生成不当导致hashjoin算子建立的hash表重复值过多,占用大量内存。
- 包含UDF的场景,且UDF中使用大量内存的场景。
3)短查询加速(默认开启,建议开启)
混合负载场景下,复杂查询可能会长时间占用大量资源,虽然简单查询执行时间短、消耗资源少,但是因为资源耗尽,简单查询不得不在队列中等待复杂查询执行完成。为提升执行效率、提高系统吞吐量,GaussDB(DWS)的“短查询加速”功能,实现对简单查询的单独管理。
- 开启短查询加速后,简单查询与复杂查询分开管理。
- 关闭短查询加速后,简单查询与复杂查询执行相同的工作负载管理。
虽然单个简单作业资源消耗少,但是大量简单作业并发运行还是会占用大量资源,因此短查询加速开启情况下,需要对简单查询进行并发管理;资源管理可能会影响查询性能,影响系统吞吐量,因此简单查询不进行资源管理,异常规则也不生效。
设置方法:
- 通过GUC参数wlm_query_accelerate设置
- 通过资源池alter resource pool query_pool with(short_acc='f');
4.3 资源池内存管理
资源池的内存管理是基于语句的估算内存进行管理的。
1)资源池可用内存设置方法
ALTER RESOURCE POOL resource_pool_a1 WITH (MEM_PERCENT=20);
- 当MEM_PERCENT参数取值设置为0时,表示查询作业的内存不受限。
- 当MEM_PERCENT参数取值设置为"x"(1<=x<=100)时,表示设置资源池使用的内存大小为可用内存大小的"x%",查询作业将使用给定的内存来运行。
2)资源池作业估算内存限制设置方法
ALTER RESOURCE POOL resource_pool_a1 WITH (MEMORY_LIMIT="300MB");
- 当MEMORY_LIMIT参数取值设置为unlimited时,表示作业内存受数据库内存限制。
- 当MEMORY_LIMIT参数取值设置为default时,表示作业内存限制为资源池内存的1/2。
- 当MEMORY_LIMIT参数取值设置为x kB/MB/GB时,表示作业内存限制为xkB/MB/GB。
- 当memory_limit配置小于256M时,为防止估算内存过小导致问题,作业估算内存上限为256MB。
5 资源管理相关视图
GaussDB(DWS)对外提供诸多系统视图,可以用来辅助资源管理及资源使用相关问题的分析定位,常用视图及用法说明如下表所示。(☆代表常用程度)
除过上述常用视图,资源管理问题定位过程需要根据实际场景,结合实例日志、集群状态等共同分析定位。
6 推荐配置
因为并发的配置和业务的复杂程度和集群的规格配置有很大的关系,本推荐仅做参考。推荐基于3CN 12DN,每个dn实例最大可使用64G内存情况下推荐的
在813内核版本及以上版本推荐配置如下。
GUC参数:
- max_active_statements 60 (每个cn的最大并发数,控制全局队列排队)
- enable_dynamic_workload on (开启动态负载)
- wlm_query_accelerate -1 (开启短查询加速)
资源池参数:
- ALTER RESOURCE POOL resource_pool_a1 WITH (MAX_DOP=50) (简单作业数50并发)
- ALTER RESOURCE POOL resource_pool_a1 WITH (active_statements=10) (复杂作业10并发)
7 并发控制常用定位方法及解决措施
7.1 排队问题
出现业务阻塞、性能下降、查询无响应等类似现网问题时,通过以下方法可以排查是否排队问题并定位排队原因,同时根据排队原因给出相应规避措施。
7.1.1 确认是否排队
首先确认是否排队问题,其次排查排队原因,确认是否属于正常排队:
- 813及以上版本查询资源池监控视图
select rpname,slow_run,slow_wait,slow_limit,used_cpu,cpu_limit,used_mem,estimate_mem from gs_respool_resource_info;
- 老版本查询作业负载视图
select resource_pool,attribute,lane,status,enqueue,sum(statement_mem) as stmt_mem,count(1) from pgxc_session_wlmstat where status!='finished' and attribute!='Internal' and usename!='Ruby' group by 1,2,3,4,5;
通过视图可以获取到各资源池快慢车道作业运行信息,据此可以判断是否排队问题:
如果有作业处于排队状态,则可能是排队导致的问题,否则排除排队问题;可能的排队原因包括:
- 单CN全局并发排队;
- 快车道并发排队;
- 静态慢车道并发排队;
- 静态慢车道内存排队;
- 动态CCN全局内存排队;
- 动态CCN慢车道并发排队;
- 动态CCN慢车道内存排队。
排查排队原因
常见排队原因及解决措施
1)全局并发排队
单CN实际运行作业数≥全局并发上限,则全局并发排队正常;
单CN实际运行作业数长时间小于全局并发上限,则可能存在计数泄露。
2)快车道排队
快车道实际运行作业数≥快车道并发上限,则快车道并发排队正常;
快车道实际运行作业数长时间小于快车道并发上限,则可能存在计数泄露。
3)静态慢车道排队
慢车道实际运行作业数≥慢车道并发上限,则慢车道并发排队正常;
慢车道实际运行作业累计估算内存≥慢车道内存上限,则慢车道内存占用达到上限导致排队,关注是否有查询估算内存过大;
如果慢车道并发和内存占用长时间达不到上限,则可能存在计数泄露。
4)动态CCN排队
如果查询在CCN排队,则需要查询CCN开发者视图确认排队原因:
select * from pg_stat_get_workload_struct_info();
CCN上可能的排队原因:
- CCN全局可用内存不足导致排队,此时需特别关注是否有查询估算内存过大;
- 资源池实际运行作业数≥慢车道车道并发上限,资源池并发上限,正常排队;
- 资源池实际运行作业累计估算内存≥慢车道内存上限,则慢车道内存占用达到上限导致排队,此时需特别关注是否有查询估算内存过大;
- 资源池实际运行作业数或占用内存与记账值不符,则可能存在计数泄露BUG;
- 队首作业在CCN哈希中不存在,说明队首作业残留导致查询不能正常下发;
- CN/CCN处于recover状态或收集DN内存信息失败(多CCN)导致所有查询等待5s下发,现象为所有查询排队时间均为5~6s。
8 常见案例
8.1 CCN排队
1)查询资源池监控视图,确认是否正常排队(813及以上版本)
下面以单CN下发作业为例,多CN下发作业需查询pgxc_respool_resource_info视图。
select rpname,slow_run,slow_wait,slow_limit,used_cpu,cpu_limit,used_mem,estimate_mem from gs_respool_resource_info;
- 如果slow_wait不等于0,说明有查询在CCN排队,否则无查询排队;
- 如果slow_run大于等于slow_limit,说明达到慢车道并发上限导致排队,否则说明不是并发过大导致排队;
- 如果estimate_mem大于资源池内存上限,说明内存不足导致排队,否则说明不是内存不足导致排队;
- 如果used_mem长时间远小于estimate_mem,说明该资源池上运行作业估算内存过大,可以尝试analyze;
- 如果used_mem大于estimate_mem,则查询可能触发内存二次扩展(默认资源池)或查询内存不可控;
- 如果used_cpu长时间接近甚至大于等于cpu_limit,说明资源池分配CPU过少,可能导致作业大量堆积;
通过该查询可以直观的观察各资源池作业负载信息,如果资源池running作业并发、内存长时间无法达到资源池上限,则考虑是否存在排队异常。
2)查询作业负载视图(813以下版本)
813及以上版本建议使用上边方法确认是否有排队异常,当然也可以使用以下方法确认存在排队异常,排除特性BUG影响。
813以下版本仅有pg_session_wlmstat视图,没有pgxc视图,可通过以下语句创建临时pgxc视图:
CREATE OR REPLACE VIEW pgxc_session_wlmstat_tp AS
SELECT * FROM pg_catalog.pgxc_parallel_query('cn', 'SELECT pg_catalog.pgxc_node_str(), * FROM pg_catalog.pg_session_wlmstat') AS (
nodename name,
datid oid,
datname name,
threadid bigint,
processid integer,
usesysid oid,
appname text,
usename name,
priority bigint,
attribute text,
block_time bigint,
elapsed_time bigint,
total_cpu_time bigint,
cpu_skew_percent integer,
statement_mem integer,
active_points integer,
dop_value integer,
control_group text,
status text,
enqueue text,
resource_pool name,
query text,
is_plana boolean,
node_group text,
lane text
);
查询集群内各资源池在所有CN上的作业运行、排队统计信息:
select resource_pool,attribute,lane,status,enqueue,sum(statement_mem) as stmt_mem,count(1) from pgxc_session_wlmstat where status!='finished' and attribute!='Internal' and usename!='Ruby' group by 1,2,3,4,5;
通过该查询可以直观的观察各资源池作业负载信息,如果资源池running作业并发、内存长时间无法达到资源池上限,则考虑是否存在排队异常。
确认是否存在排队异常
如果经过前两个步骤分析,怀疑可能存在排队异常,可能的原因有以下几种:
- 大批作业一开始运行就报错退出,依靠CCN周期任务完成作业同步和唤醒;
- CCN全局内存排队导致资源池并发、内存长时间无法达到资源池上限。
以上是关于理论+示例,详解GaussDB(DWS)资源管理的主要内容,如果未能解决你的问题,请参考以下文章