PostgreSQL监控实战 基于Pigsty解决实际监控问题 ——冯若航

本文涉及的产品
云原生数据库 PolarDB 分布式版,标准版 2核8GB
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS PostgreSQL Serverless,0.5-4RCU 50GB 3个月
推荐场景:
对影评进行热评分析
简介: PostgreSQL监控实战基于Pigsty解决实际监控问题——冯若航

内容简要:

一、为什么需要监控系统

二、用监控系统解决问题

三、监控系统的部署

 

 

一、为什么需要监控系统

离开监控系统管理数据库就像蒙眼开车,我们通过利用监控系统实现对数据库状态的观察与管理,下面通过两个实验举例说明。

(一)实验1:利用监控系统观测查询负载

1)使用正常连接数负载,观察系统状态

这里我们做一个实验,已有一主两从的数据库集群PG-test,为集群添加50的读写QPS1000的只读QPS,利用监控系统的信息,印证我们主动施加的负载。这个负载是用PG自带的压测工具PG Bench生成的。

命令一:

while true; do pgbench -nv -P1 -c4 --select-only --rate=1000 -T10 postgres://test:test@pg-test:5434/test; done

命令二:

while true; do pgbench -nv -P1 -c4 --select-only --rate=1000 -T10 postgres://test:test@pg-test:5434/test; done

第一行命令我们用PG Bench给从库select-only加上了1000TPS,第二条命令我们给主库加上了50TPS,从库使用4条连接,主库使用2条连接。

那么我们期待的结果总共加了1050TPS,主库50,两个从库每人各500,从库总共1000

image.png

如上图所示,我们可以看到整个集群的GPS数据,主库上的TPS差不多是50左右,从库上的TPS差不多是1000,符合我们的预期。

 

2)使用十倍的连接数施加同样负载,观察系统状态

接下来我们稍微改动一下,施加同样的负载,但使用十倍的连接数量,原来我们使用了2条读写连接,4条只读连接,现在翻十倍变为20条和40条,观察连接池在这一过程中起到的作用。

命令一:

while true; do pgbench -nv -P1 -c40 --select-only --rate=1000 -T10 postgres://test:test@pg-test:5434/test; done

命令二:

while true; do pgbench -nv -P1 -c20 --rate=50 -T10 postgres://test:test@pg-test:5433/test; done

image.png

我们来看一下监控系统,PG Cluster Session是专门绘画关于集群相关的指标,其中的Active Clients by Instance是按照实例划分的连接数。如上图所示,通过最近5分钟的情况可以看到,之前使用的是6条连接,222从,现在使用60条,就变成20 2020。如果说TPS指标它是有一定抖动误差的话,那么连接数这样的指标可以算是相当精确了。

 

3)使用尽可能大的负载,观察系统在过载下的表现

我们采用没有 TPS限制的PG Bench,用最大负载把集群尽可能打满,观察系统在过载情况下的表现。

命令一:while true; do pgbench -nv -P1 -c20 -T10 postgres://test:test@pg-test:5433/test; done

命令二:while true; do pgbench -nv -P1 -c40 --select-only -T10 postgres://test:test@pg-test:5434/test; done

image.png如上图所示,我们回到主页可以看到,监控面板目前的负载水平已经超过100%,主库负载严重超标,两个从库也基本进入过载状态,整个系统已经爆表。当我们将负载定量重新调低后,整个系统的负载水平会逐渐回到温和状态。

 

以上实验反映了监控系统的基本功能,它能够如实地反映用户给集群施加的负载以及集群本身内部的状态。

 

(二)实验二:重启主库,观察集群领导权交接

我们通常所说的高可用,指的是当一个系统的主库宕机时,应该有一个从库自动被提升出来接管系统。如果没有监控系统的话,这个操作对我们而言是一个很抽象的事情,下面我们借助监控系统来观察一下这个操作过程。

比如我们登录到第一台主库所在的机器上,然后执行ssh –t node-1 sudo reboot,可以看到负载都开始报错。但在短短数秒内,无论是读流量还是写流量,它都自行恢复正常运行。

image.png

如上图所示,我们可以看到监控系统中原本的主库pg-test1已经被踢掉了, pg-test2被提升成新的主库了,开始承接写流量。当pg-test1重启完成之后,它是一台死掉的Primary,会尝试将自己降格为一台新的从库,重新挂在pg-test2的位置上。

image.png

同时我们可以看到,整个集群的领导权Leadership图表已经发生转移,比如说原来集群的新领导是pg-test1,现在变成pg-test2

 

通过以上两个实验可以看出,监控系统对于反应系统状态来说,是一个非常实用的工具。

 

 

二、用监控系统解决一些实际问题

(一)用监控系统解决问题

1.黄金监控指标

image.png

Pigsty提供了约1200个指标,但最重要的就是这10个,这也是PG Cluster首屏上呈现出的关键指标。

数据库负值和饱和度是最重要的指标。按照Google SRE的监控最佳实践,这些指标可以分为4大类,饱和度、延迟、流量和错误,都具有很重要的参考价值。

 

2.PG Load  衡量数据库的负载程度

PG的负载是不是也可以采用类似于 CPU 利用率和机器负载的方式来定义?当然可以,而且这是一个极棒的主意。让我们先来考虑单进程情况下的PG负载,假设我们需要这样一个指标,当该PG进程完全空闲时负载因子为0,当该进程处于满载状态时负载为1(100%)。类比 CPU利用率的定义,我们可以使用单个PG进程处于活跃状态的时长占比来表示单个PG后端进程的利用率。

image.png

如上图所示,在一秒的统计周期内,PG处于活跃(执行查询或者执行事务)状态的时长为 0.6 秒,那么这一秒内的PG负载就是 60%。如果这个唯一的PG进程在整个统计周期中都处于忙碌状态,而且还有 0.4 秒的任务在排队,如那么就可以认为PG的负载为 140%。

image.png

对于并行场景,计算方法与多核CPU的利用率类似,首先把所有 PG进程在统计周期(1S)内处于活跃状态的时长累加,然后除以可用的PG进程/连接数,或者说可用并行数,即可得到PG本身的利用率指标,如上图所示。两个PG后端进程分别有 20Oms + 400ms 80Oms 的活跃时长,那么整体的负载水平为:

(0.2S+0.4S+0.8S)/1S/2=70 %

 

总结一下,某一段时间PG的负载可以定义为:

pg_load=pg_active_seconds/time_eroid /parallel

l  pg_active_seconds 是该时间段内所有 PG 进程处于活跃状态的时长之和。

l  time_peroid 是负载计算的统计周期,通常为1分钟, 5分钟, 15分钟,以及实时(小于10 秒)。

l  Para11el PostgreSQL 的可用并行数,后面会详细解释.

因为前两项之商实际上就是一段时间内的每秒活跃时长总数,因此这个公式进一步可以简化为活跃时长对时间的导数除以可用并行数,即:

rate(pg_active_seconds [time_peroid ])/parallel

time_peroid 通常是固定的常量(1,5, 15分钟),所以问题就是如何获取 PG进程活跃总时长pg_active_seconds这个指标,以及如何评估计算数据库可用并行数 max_ para11el了。

 

3.黄金指标: 数据库饱和度

数据库负载 pg load= pg conn busy time / avail CPU time

数据库饱和度saturation = max(cpu_ usage, pg_load)

饱和度用于反映数据库整体资源利用率理论上应当取所有饱和度指标的最大值(PGCPU,内存,网络,磁盘……)

PG Saturation = max(PG Load, CPU Usage, xxxUsage…)

实际应用中,饱和度指标取 PG Load CPU Usage的最大值作为饱和度,当数据库使用非独占式部署,其他应用占用CPU资源时,PG Saturation比单纯的PG Load更能反映数据库整体负载水位。

- record: pg:ins:saturation0 expr: pg:ins:load0 > node:ins:cpu_usage or node:ins:cpu_usage

- record: pg:ins:saturation1 expr: pg:ins:load1 > node:ins:cpu_usage or node:ins:cpu_usage

- record: pg:ins:saturation5 expr: pg:ins:load5 > node:ins:cpu_usage or node:ins:cpu_usage

- record: pg:ins:saturation15 expr: pg:ins:load15 > node:ins:cpu_usage or node:ins:cpu_usage

image.png

(二)慢查询定位优化

1.什么是慢查询?

慢查询是数据库的大敌,这里我们使用PG Bench 用例模拟一个慢查询。

ALTER TABLE pgbench_accounts DROP CONSTRAINT pgbench_accounts_pkey ;

该命令会移除pgbench_accounts 表上的主键,导致相关查询变慢,系统瞬间雪崩过载。

image.png

2.定位慢查询

定位集群RT异常,定位到具体的实例和查询。首先,使用PG Cluster面板定位慢查询所在的具体实例,这里以pg-test2为例,然后使用PG Query面板定位具体的慢查询:编号为 -6041100154778468427

该查询表现出:响应时间显著上升:17us升至 280ms QPS显著下降:从500下降到7,花费在该查询上的时间占比显著增加,可以确定就是这个查询变慢了。

image.png

3.发现异常

接下来,利用PG Stat Statements面板,根据查询ID定位慢查询的具体语句。查询以aid作为过滤条件查询pgbench_accounts 表查询变慢,大概率是这张表上的索引出了问题。

分析查询后提出猜想:该查询变慢是pgbench_accounts表上aid列缺少索引,下一步,查阅PG Table Detail面板,检查pgbench_accounts 表上的访问。定位潜在问题,找出顺序扫表,建立所需索引。

image.png

image.png

image.png

4.性能优化

我们尝试在pgbench_accounts表上为aid列添加索引,看看能否解决这个问题。

CREATE UNIQUE INDEX ON pgbench_accounts (aid);

可以看到,查询的响应时间与QPS已经恢复正常,整个集群的负载水平也恢复正常,报警也平息下来。精准衡量优化效果,直观展示工作成绩,真正做到数据驱动。

image.png

(三)定位系统故障

人工时时盯着指标,是一个非常辛苦的活,更好的选择是由机器来盯着这些指标,您设定好规则,机器发现这些指标超出异常范围的时候,自动给你触发发送报警,Pigsty里面提供了一系列的报警规则,同时报警事件也可以在监控系统的面板里面看到,通过这种条状甘特图的方式,我们可以看到哪一个时间段触发了报警事件,从而有的放矢的去排查。报警系统提供了很多计算好的衍生指标,所以不用再写特别复杂的表达式,可以直接用。

image.png

image.png

image.png

(四)系统水位评估

1.水位评估: 饱和度的历史分位点

除了直观的衡量实时的数据库负载水平,还可以用来计算数据库的水位,水位就是一个长期的资源使用量指标,通常来说,如果我们的某一个数据库集群长时间处于高负载状态,我们就是说它水位比较高,我们可能就要给它扩容。如果它长时间处于低水位状态,处于闲置,那么我们就要给他缩容。

 

扩容和缩容的依据就是所谓的水位,水位就是过去某一个时间段饱和度的百分位点。比如说现在采用的就是过去一天里面水位的99分位点,对于那种有周期性的负载来说,一天是一个比较好的这种衡量指标,如果您的业务周期性是一周或者一月,可以使用过去一周或者一月的饱和度数据,来计算它的99分位点或者99.99分位点,来评估集群的水位。比如这里某一套集群,它的水位是30%,那么就是意味着系统在过去一天的99%的时间里面,它的资源使用率都在30%以内,我们就认为它的水位是30%。像这样的指标对于评估长时间段系统的资源利用率很有用。评估资源利用率,就可以评估成本,及时的进行优化,这是一个典型应用。

 

 

三、How 如何部署一套监控系统?

(一)开源软件

参考文档:http://pigsty.cc

image.png

(二)公开文档与演示

l  上手

基于Vagrant,快速在本机拉起演示系统。

这篇文档将介绍如何在您手头的笔记本或PC机上,基于VagrantVirtualbox,拉起Pigsty演示沙箱。

本教程着眼于在本地单机创建Pigsty演示环境,如果您已经有可以用于部署的机器实例,可以参考部署教程

 

l  太长;不看

如果用户的本地计算机上已经安装有VagrantVirtualboxAnsible,那么只需要克隆并进入本项目后,依次执行以下命令即可:

image.png

正常情况下执行结果详见参考-标准流程

 

(三)快速上手

快速开始

git clone https://github.com/Vonng/pigsty

cd /tmp

make up

make ssh

sudo make

dns make init

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
2月前
|
缓存 关系型数据库 MySQL
MySQL索引策略与查询性能调优实战
在实际应用中,需要根据具体的业务需求和查询模式,综合运用索引策略和查询性能调优方法,不断地测试和优化,以提高MySQL数据库的查询性能。
197 66
|
2月前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
346 1
|
3月前
|
NoSQL 关系型数据库 MySQL
MySQL与Redis协同作战:优化百万数据查询的实战经验
【10月更文挑战第13天】 在处理大规模数据集时,传统的关系型数据库如MySQL可能会遇到性能瓶颈。为了提升数据处理的效率,我们可以结合使用MySQL和Redis,利用两者的优势来优化数据查询。本文将分享一次实战经验,探讨如何通过MySQL与Redis的协同工作来优化百万级数据统计。
109 5
|
3月前
|
架构师 关系型数据库 MySQL
MySQL最左前缀优化原则:深入解析与实战应用
【10月更文挑战第12天】在数据库架构设计与优化中,索引的使用是提升查询性能的关键手段之一。其中,MySQL的最左前缀优化原则(Leftmost Prefix Principle)是复合索引(Composite Index)应用中的核心策略。作为资深架构师,深入理解并掌握这一原则,对于平衡数据库性能与维护成本至关重要。本文将详细解读最左前缀优化原则的功能特点、业务场景、优缺点、底层原理,并通过Java示例展示其实现方式。
132 1
|
2月前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第26天】数据库作为现代应用系统的核心组件,其性能优化至关重要。本文主要探讨MySQL的索引策略与查询性能调优。通过合理创建索引(如B-Tree、复合索引)和优化查询语句(如使用EXPLAIN、优化分页查询),可以显著提升数据库的响应速度和稳定性。实践中还需定期审查慢查询日志,持续优化性能。
131 0
|
4月前
|
监控 关系型数据库 MySQL
zabbix agent集成percona监控MySQL的插件实战案例
这篇文章是关于如何使用Percona监控插件集成Zabbix agent来监控MySQL的实战案例。
91 2
zabbix agent集成percona监控MySQL的插件实战案例
|
4月前
|
存储 监控 关系型数据库
监控 PostgreSQL 的性能指标
监控 PostgreSQL 的性能指标
198 3
|
5月前
|
SQL 关系型数据库 MySQL
干货!python与MySQL数据库的交互实战
干货!python与MySQL数据库的交互实战
|
5月前
|
存储 关系型数据库 MySQL
实战!MySQL主从复制一键搭建脚本分享
实战!MySQL主从复制一键搭建脚本分享
100 2
|
5月前
|
SQL 存储 关系型数据库
MySQL备份:mydumper 备份恢复工具生产实战
MySQL备份:mydumper 备份恢复工具生产实战

相关产品

  • 云原生数据库 PolarDB
  • 云数据库 RDS PostgreSQL 版