摘要:GaussDB(DWS)提供了资源管理功能,用户可以根据自身业务情况对资源进行划分,将资源按需划分成不同的资源池,不同资源池之间资源互相隔离。

本文分享自华为云社区《GaussDB(DWS)资源管理排队原理与问题定位》,作者: 门前一棵葡萄树 。

一、内存管控原理

GaussDB(DWS)提供了资源管理功能,用户可以根据自身业务情况对资源进行划分,将资源按需划分成不同的资源池,不同资源池之间资源互相隔离。再通过用户关联资源池的方式将数据库用户关联至不同的资源池,用户查询依据“用户-资源池”的关联关系将查询路由至对应资源池执行,以此实现对查询并发、内存及CPU资源的管控。从而实现对不同业务之间的资源限制和隔离,满足数据库混合负载需求,保证查询执行时资源调度的有序可控,防止烂SQL影响整个集群。

1.1 自适应内存

传统内存管理场景下,使用work_mem限制算子可以使用的内存上限,通常复杂查询的执行计划中包含多个算子,每个算子可能需要使用的内存并不相同,但是每个算子可用的内存上限均为work_mem,很难找到一个最优的work_mem取值,一方面保证查询性能满足预期,一方面还需要保证不会导致内存报错。在查询并发场景下,静态内存管理的work_mem及并发上限就更难设置了。单查询算子数量从0~N不等,设置work_mem后无法实现语句级内存资源使用的控制,多并发场景下可能会导致内存资源不受控,进而导致OOM。

针对传统内存管理的弊端,GaussDB(DWS)设计实现了内存自适应技术:

  • 解除对work_mem的依赖,优化器依据统计信息对查询使用内存进行估算;
  • 执行器执行SQL过程中,如果使用内存超过估算内存即触发下盘;
  • 资源管理依据优化器估算的查询内存,对查询进行调度和管控。

另外,为保证多CN场景下的内存可控,设计实现CCN用于查询的统一调度,以此保证所有CN上运行的查询使用内存之和不会超过内存上限,进而导致内存不足,引发报错。CM在第一次集群启动时,通过集群部署形式,选择编号最小的CN作为CCN,CCN故障之后,由CM选择新的CCN进行替换。

CCN管控与CN管控间差异及优劣:

  • CN管控查询由各CN单独调度,各CN间互相不感知负载情况,无法准确感知和控制整个集群并发,内存管控效果有限,有可能出现内存报错;
  • CCN管控查询由CCN统一调度,结合DN内存负反馈机制,CCN可以感知集群整体负载,内存管控更加精准,可以消除内存不足报错;
  • CCN管控涉及CN与CCN之间的通信,通信延迟可能带来查询性能的不稳定;通信延迟与网络环境及查询并发度有关,大概10ms~ 1s不等;
  • CCN管控相对CN管控逻辑更加复杂,除涉及资源池内存/并发管控外,还包含CCN全局内存管控,在作业管控和唤醒时都需要进行两层逻辑判断;
  • CCN管控因为所有查询都需要由CCN统一调度,因此管控时发生所冲突的可能性就更大。

综上所述,CN管控对查询性能影响较小,但是内存管控效果有限,CCN管控对查询性能影响可能较大,但是可以实现内存精准管控,消除内存不足报错。

为实现更为精细的管控,我们根据查询预期执行时间和资源消耗,将查询划分为执行时间长、资源消耗多的复杂查询和执行时间短、资源消耗少的简单查询。简单查询和复杂查询的划分与资源消耗密切相关,同时因为查询执行前就需要划分简单/复杂查询,因此根据估算内存(代价)对查询进行划分:

  • 简单查询:估算内存小于32MB;
  • 复杂查询:估算内存大于等于32MB。

混合负载场景下,虽然简单查询本身执行时间短、消耗资源少,但是因为复杂查询可能会长时间大量占用资源,进而导致资源耗尽,使得简单查询不得不在队列中等待复杂查询执行完成。为提升执行效率、提高数据库整体吞吐量, 设计实现“短查询加速”功能,实现对简单查询的单独管控。

  • 开启短查询加速后,简单查询与复杂查询分别进行管控。
  • 关闭短查询加速后,简单查询与复杂查询一起进行管控。

虽然单个简单查询资源消耗少,但是大量简单查询并发运行还是可能占用大量资源,另外对简单查询进行CCN管控可能会影响查询性能,降低吞吐量。因此为降低对查询的性能影响,同时实现内存管控目的,我们仅对复杂查询进行CCN并发和内存管控,简单查询由各自CN单独进行并发控制。

1.2 内存管控能力

GaussDB(DWS) 内存管控分为三级,分别是:

  1. 实例级内存管控:通过max_process_memory限制CN、DN可以使用的内存上限;
  2. 资源池内存管控:通过资源池参数mem_percent限制资源池内存使用,结合优化器估算的查询内存,实现资源池之间的内存隔离;
  3. 作业内存管控:查询优化器根据统计信息估算查询执行时使用内存的最大值,查询以估算内存为准向资源管理申请内存资源,查询执行过程中使用内存超过估算内存即触发下盘。

基于优化器给出的查询估算内存,资源管理提供了两种内存管控方式:

  1. 静态内存管控(单CN管控):各CN互不感知,分别进行管控,多CN同时下发作业可能导致内存不可控;
  2. 动态内存管控(CCN管控):估算内存大于32MB的查询统一由CCN调度,结合DN内存负反馈机制,CCN感知集群整体负载,实现内存的精准管控。

特例:

  1. 静态内存管控关闭(资源池mem_percent=0)或查询估算内存为0情况下,查询执行过程中使用work_mem控制每个算子可以使用的内存上限,多算子并行可能导致内存不受控;
  2. 默认资源池支持DN上内存扩展,DN内存资源充足情况下查询可以使用更多内存,提升查询执行性能。

通过以上描述,其实不难看出内存管控的基础是优化器的内存估算,内存估算准确可以实现内存的精准管控,内存估算不准可能引起一系列的问题:

  1. 内存估算小使用大(DN内存扩展),可能导致内存报错;
  2. 内存估算大使用小,可能导致内存利用率低,吞吐量上不去;
  3. 内存估算过大,可能导致CCN/CN异常排队。

基于以上问题,资源管理做了以下功能降低估算不准带来的影响:

  1. 资源池增加参数memory_limit,用于配置单查询估算内存上限,默认情况下查询估算内存上限为资源池内存*0.4,实际场景下可按需设置该值大小,理论上查询估算内存不应超过该值;
  2. 内存负反馈:正在执行的作业查询估算内存之和超过总内存40%,实际使用内存低于估算内存60%时触发内存负反馈,按照一定比例逐步降低查询估算内存记账值,以此下发更多查询,提升内存使用率;

查询估算内存兜底机制(820-1230):在查询估算内存超过单查询估算内存上限时,对查询估算内存进行修正,按照单查询估算内存上限进行管控。

二、排队原理与问题排查

2.1 排队原理

GaussDB(DWS)可能在以下情况下发生排队:

  1. 单CN并发控制:单个CN上查询并发超过max_active_statements引发排队;
  2. 资源池快车道并发控制:资源池上简单查询并发超过资源池参数max_dop引发排队;
  3. 资源池慢车道并发控制:资源池上复杂查询并发超过资源池参数active_statements引发排队;
  4. 资源池慢车道内存管控:资源池上运行的复杂查询估算内存之和超过资源池参数mem_percent配置的资源池内存上限引发排队;
  5. CCN全局内存管控:所有CN上运行的查询内存估算内存/使用内存超过DN内存上限(max_dynamic_memory)引发排队。

特例:初始用户及白名单语句不受控。

2.2 常见视图

GaussDB(DWS)对外提供诸多系统视图,可以用来辅助资源管理及资源使用相关问题的分析定位,常用视图及用法说明如下表所示。(☆代表常用程度)

除过上述常用视图,资源管理问题定位过程需要根据实际场景,结合实例日志、集群状态等共同分析定位。

2.3 自定义视图

为方便迅速定位问题,根据现网实践经验对以上常见视图进行组合,整合了三个问题定位过程中的常用视图:资源池监控视图、用户监控视图以及作业监控视图。与上面内置视图相比,这几个视图依据现网定位经验与分布式数据库特点,对查询结果做了针对性优化,同时优化了字段显示,用户更易理解,可以作为常规监控视图使用。具体视图定义可参考附件。

2.4 排队问题排查

出现业务阻塞、性能下降、查询无响应等类似现网问题时,通过以下方法可以排查是否排队问题并定位排队原因,同时根据排队原因给出相应规避措施。

Step1 确认是否排队

首先确认是否排队问题,其次排查排队原因,确认是否属于正常排队:

  • 813及以上版本可以查询资源池监控视图
SELECT * FROM pgxc_respool_runtime_info ORDER BY 1,2,3;
  • 811及以上版本可以作业运行监控视图
SELECT
s.resource_pool AS rpname, s.node_group,
count(1) AS session_cnt,
SUM(CASE WHEN a.enqueue = 'waiting in global queue' THEN 1 ELSE 0 END) AS global_wait,
SUM(CASE WHEN s.lane= 'fast' AND a.state = 'active' AND (a.enqueue IS NULL OR a.enqueue = 'no waiting queue') THEN 1 ELSE 0 END) AS fast_run,
SUM(CASE WHEN s.lane= 'fast' AND a.enqueue = 'waiting in respool queue' THEN 1 ELSE 0 END) AS fast_wait,
SUM(CASE WHEN s.lane= 'slow' AND a.state = 'active' AND (a.enqueue IS NULL OR a.enqueue = 'no waiting queue') THEN 1 ELSE 0 END) AS slow_run,
SUM(CASE WHEN s.lane= 'slow' AND (a.enqueue = 'waiting in ccn queue' OR a.enqueue = 'waiting in respool queue') THEN 1 ELSE 0 END) AS slow_wait,
SUM(CASE WHEN (a.enqueue IS NULL OR a.enqueue = 'no waiting queue') AND a.state = 'active' THEN statement_mem ELSE 0 END) AS est_mem
FROM pgxc_session_wlmstat s,pgxc_stat_activity a
WHERE s.threadid=a.pid(+) AND s.attribute != 'Internal'
GROUP BY 1,2
  • 800版本查询作业运行监控视图
SELECT
s.resource_pool AS rpname, s.node_group,
count(1) AS session_cnt,
SUM(CASE WHEN a.enqueue = 'waiting in global queue' THEN 1 ELSE 0 END) AS global_wait,
SUM(CASE WHEN s.attribute= 'Simple' AND a.state = 'active' AND (a.enqueue IS NULL OR a.enqueue = 'no waiting queue') THEN 1 ELSE 0 END) AS fast_run,
SUM(CASE WHEN s.attribute= 'Simple' AND a.enqueue = 'waiting in respool queue' THEN 1 ELSE 0 END) AS fast_wait,
SUM(CASE WHEN s.attribute= 'Complicated' AND a.state = 'active' AND (a.enqueue IS NULL OR a.enqueue = 'no waiting queue') THEN 1 ELSE 0 END) AS slow_run,
SUM(CASE WHEN s.attribute= 'Complicated' AND (a.enqueue = 'waiting in ccn queue' OR a.enqueue = 'waiting in respool queue') THEN 1 ELSE 0 END) AS slow_wait,
SUM(CASE WHEN (a.enqueue IS NULL OR a.enqueue = 'no waiting queue') AND a.state = 'active' THEN statement_mem ELSE 0 END) AS est_mem
FROM pgxc_session_wlmstat s,pgxc_stat_activity a
WHERE s.threadid=a.pid(+) AND s.attribute != 'Internal'
GROUP BY 1,2;

某些老版本不存在pgxc_session_wlmstat视图,可以参考附件创建类似函数/视图。

  • 直接查询自定义视图

通过查询自定义视图可以获取到各资源池快慢车道作业运行信息以及作业排队信息,据此可以直接判断是否排队问题。

Step2 排查排队原因

常见排队原因及解决措施

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。

附件:自定义监控视图.rar18.11KB

点击关注,第一时间了解华为云新鲜技术~

实践丨GaussDB(DWS)资源管理排队原理与问题定位的更多相关文章

  1. GaussDB(DWS)应用实践丨负载管理与作业排队处理方法

    摘要:本文用来总结一些GaussDB(DWS)在实际应用过程中,可能出现的各种作业排队的情况,以及出现排队时,我们应该怎么去判断是否正常,调整一些参数,让资源分配与负载管理更符合当前的业务:或者在作业 ...

  2. 【数仓运维实践】关于GaussDB(DWS)单SQL磁盘空间管控

    摘要:本文主要讲解数仓运维中遇到单SQL磁盘空间管控问题的解析和方案. 本文分享自华为云社区<GaussDB(DWS)运维 -- 单SQL磁盘空间管控>,作者: 譡里个檔. [问题描述] ...

  3. 一文详解GaussDB(DWS) 的并发管控和内存管控

    摘要:DWS的负载管理分为两层,第一层为cn的全局并发控制,第二层为资源池级别的并发控制. 本文分享自华为云社区<GaussDB(DWS) 并发管控&内存管控>,作者: fight ...

  4. 十八般武艺玩转GaussDB(DWS)性能调优(三):好味道表定义

    摘要:表结构设计是数据库建模的一个关键环节,表定义好坏直接决定了集群的有效容量以及业务查询性能,本文从产品架构.功能实现以及业务特征的角度阐述在GaussDB(DWS)的中表定义时需要关注的一些关键因 ...

  5. 由两个问题引发的对GaussDB(DWS)负载均衡的思考

    摘要:GaussDB(DWS)的负载均衡通过LVS+keepAlived实现.对于这种方式,需要思考的问题是,CN的返回结果是否会经过LVS,然后再返回给前端应用?如果经过LVS,那么,LVS会不会成 ...

  6. 十八般武艺玩转GaussDB(DWS)性能调优:SQL改写

    摘要:本文将系统介绍在GaussDB(DWS)系统中影响性能的坏味道SQL及SQL模式,帮助大家能够从原理层面尽快识别这些坏味道SQL,在调优过程中及时发现问题,进行整改. 数据库的应用中,充斥着坏味 ...

  7. 十八般武艺玩转GaussDB(DWS)性能调优:路径干预

    摘要:路径生成是表关联方式确定的主要阶段,本文介绍了几个影响路径生成的要素:cost_param, scan方式,join方式,stream方式,并从原理上分析如何干预路径的生成. 一.cost模型选 ...

  8. GaussDB(DWS)中共享消息队列实现的三大功能

    摘要:本文将详细介绍GaussDB(DWS)中共享消息队列的实现. 本文分享自华为云社区<GaussDB(DWS)CBB组件之共享消息队列介绍>,作者:疯狂朔朔. 1)共享消息队列是什么? ...

  9. GaussDB(DWS)应用实战:对被视图引用的表进行DDL操作

    摘要:GaussDB(DWS)是从Postgres演进过来的,像Postgres一样,如果表被视图引用的话,特定场景下,部分DDL操作是不能直接执行的. 背景说明 GaussDB(DWS)是从Post ...

  10. 详解GaussDB(DWS) explain分布式执行计划

    摘要:本文主要介绍如何详细解读GaussDB(DWS)产生的分布式执行计划,从计划中发现性能调优点. 前言 执行计划(又称解释计划)是数据库执行SQL语句的具体步骤,例如通过索引还是全表扫描访问表中的 ...

随机推荐

  1. 命令vue inspect > output.js报错:在此系统上禁止运行脚本

    用的这个命令去看output.js文件,结果报错. 解决方案是去对应目录下删掉vue.ps1就OK了 .

  2. Pinely Round 2 (Div. 1 + Div. 2) (CF1863)

    本来开了某场远古 Div 1,然后学了一堆前置知识至今仍然不会 E.换一场写来得及吗? A. Channel 模拟,略. B. Split Sort Description 给你一个长度为 \(n\) ...

  3. 【Java集合】了解集合的框架体系结构及常用实现类,从入门到精通!

    前言 通过Java基础的学习,我们掌握了主要的Java语言基本的语法,同时了解学习了Java语言的核心-面向对象编程思想. 从集合框架开始,也就是进入了java这些基础知识及面向对象思想进入实际应用编 ...

  4. 博弈论(Nim游戏 , 有向图游戏)

    博弈论专题 Nim游戏 内容: 有 n 堆石子,每堆石子的石子数给出,甲乙两人回合制取石子,每次可以取任意一堆石子的任意多个(可以直接取完,但不能不取),每个人都按照最优策略来取(抽象),问先手必胜或 ...

  5. ASP.NET CORE MVC的一些说明

    1.ASP.NET CORE MVC 是微软公司的Web应用开发框架,结合了MVC架构的高效.简洁等优秀思想并融合了.NET的灵活性. 2.ASP.NET诞生于2002年,当时微软想保持桌面应用程序的 ...

  6. C# WebBrowser document.execCommand()解析

            //         // Summary:         //     对文档执行指定的命令.         //         // Parameters:         ...

  7. LangChain实战

    1.概述 最近,在研究LangChain时,发现一些比较有意思的点,今天笔者将给大家分享关于LangChain的一些内容. 2.内容 2.1 什么是LangChain? LangChain是一项旨在赋 ...

  8. BI 数据可视化平台建设(2)—筛选器组件升级实践

    作者:vivo 互联网大数据团队-Wang Lei 本文是vivo互联网大数据团队<BI数据可视化平台建设>系列文章第2篇 -筛选器组件. 本文主要介绍了BI数据可视化平台建设中比较核心的 ...

  9. Android 的异步消息处理机制

    前言 Android中的异步消息处理机制主要有四部分:Message.Handler.MessageQuene.Looper.这一消息处理机制也称为Handler机制.Handler机制是支撑整个An ...

  10. go基础-泛型

    概述 在强类型变成语言中,类型是确定不可变,如函数入参是确定类型.链表元素是确定类型,这极大限制了函数功能.也有些解决方案,为每种类型都实现一版函数,会导致大量重复代码:使用类型转换,使用特殊形参(如 ...