理论+示例,详解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
配置示例参见下图: