内容简要:
一、为什么需要监控系统
二、用监控系统解决问题
三、监控系统的部署
一、为什么需要监控系统
离开监控系统管理数据库就像蒙眼开车,我们通过利用监控系统实现对数据库状态的观察与管理,下面通过两个实验举例说明。
(一)实验1:利用监控系统观测查询负载
1)使用正常连接数负载,观察系统状态
这里我们做一个实验,已有一主两从的数据库集群PG-test,为集群添加50的读写QPS,1000的只读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加上了1000的TPS,第二条命令我们给主库加上了50的TPS,从库使用4条连接,主库使用2条连接。
那么我们期待的结果总共加了1050的TPS,主库50,两个从库每人各500,从库总共1000。
如上图所示,我们可以看到整个集群的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
我们来看一下监控系统,PG Cluster Session是专门绘画关于集群相关的指标,其中的Active Clients by Instance是按照实例划分的连接数。如上图所示,通过最近5分钟的情况可以看到,之前使用的是6条连接,2主2从2从,现在使用60条,就变成20, 20,20。如果说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
如上图所示,我们回到主页可以看到,监控面板目前的负载水平已经超过100%,主库负载严重超标,两个从库也基本进入过载状态,整个系统已经爆表。当我们将负载定量重新调低后,整个系统的负载水平会逐渐回到温和状态。
以上实验反映了监控系统的基本功能,它能够如实地反映用户给集群施加的负载以及集群本身内部的状态。
(二)实验二:重启主库,观察集群领导权交接
我们通常所说的高可用,指的是当一个系统的主库宕机时,应该有一个从库自动被提升出来接管系统。如果没有监控系统的话,这个操作对我们而言是一个很抽象的事情,下面我们借助监控系统来观察一下这个操作过程。
比如我们登录到第一台主库所在的机器上,然后执行ssh –t node-1 sudo reboot,可以看到负载都开始报错。但在短短数秒内,无论是读流量还是写流量,它都自行恢复正常运行。
如上图所示,我们可以看到监控系统中原本的主库pg-test1已经被踢掉了, pg-test2被提升成新的主库了,开始承接写流量。当pg-test1重启完成之后,它是一台死掉的Primary,会尝试将自己降格为一台新的从库,重新挂在pg-test2的位置上。
同时我们可以看到,整个集群的领导权Leadership图表已经发生转移,比如说原来集群的新领导是pg-test1,现在变成pg-test2。
通过以上两个实验可以看出,监控系统对于反应系统状态来说,是一个非常实用的工具。
二、用监控系统解决一些实际问题
(一)用监控系统解决问题
1.黄金监控指标
Pigsty提供了约1200个指标,但最重要的就是这10个,这也是PG Cluster首屏上呈现出的关键指标。
数据库负值和饱和度是最重要的指标。按照Google SRE的监控最佳实践,这些指标可以分为4大类,饱和度、延迟、流量和错误,都具有很重要的参考价值。
2.PG Load 衡量数据库的负载程度
PG的负载是不是也可以采用类似于 CPU 利用率和机器负载的方式来定义?当然可以,而且这是一个极棒的主意。让我们先来考虑单进程情况下的PG负载,假设我们需要这样一个指标,当该PG进程完全空闲时负载因子为0,当该进程处于满载状态时负载为1(100%)。类比 CPU利用率的定义,我们可以使用“单个PG进程处于活跃状态的时长占比”来表示单个PG后端进程的利用率。
如上图所示,在一秒的统计周期内,PG处于活跃(执行查询或者执行事务)状态的时长为 0.6 秒,那么这一秒内的PG负载就是 60%。如果这个唯一的PG进程在整个统计周期中都处于忙碌状态,而且还有 0.4 秒的任务在排队,如那么就可以认为PG的负载为 140%。
对于并行场景,计算方法与多核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)
饱和度用于反映数据库整体资源利用率理论上应当取所有饱和度指标的最大值(PG,CPU,内存,网络,磁盘……)
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
(二)慢查询定位优化
1.什么是慢查询?
慢查询是数据库的大敌,这里我们使用PG Bench 用例模拟一个慢查询。
ALTER TABLE pgbench_accounts DROP CONSTRAINT pgbench_accounts_pkey ;
该命令会移除pgbench_accounts 表上的主键,导致相关查询变慢,系统瞬间雪崩过载。
2.定位慢查询
定位集群RT异常,定位到具体的实例和查询。首先,使用PG Cluster面板定位慢查询所在的具体实例,这里以pg-test2为例,然后使用PG Query面板定位具体的慢查询:编号为 -6041100154778468427
该查询表现出:响应时间显著上升:17us升至 280ms QPS显著下降:从500下降到7,花费在该查询上的时间占比显著增加,可以确定就是这个查询变慢了。
3.发现异常
接下来,利用PG Stat Statements面板,根据查询ID定位慢查询的具体语句。查询以aid作为过滤条件查询pgbench_accounts 表查询变慢,大概率是这张表上的索引出了问题。
分析查询后提出猜想:该查询变慢是pgbench_accounts表上aid列缺少索引,下一步,查阅PG Table Detail面板,检查pgbench_accounts 表上的访问。定位潜在问题,找出顺序扫表,建立所需索引。
4.性能优化
我们尝试在pgbench_accounts表上为aid列添加索引,看看能否解决这个问题。
CREATE UNIQUE INDEX ON pgbench_accounts (aid);
可以看到,查询的响应时间与QPS已经恢复正常,整个集群的负载水平也恢复正常,报警也平息下来。精准衡量优化效果,直观展示工作成绩,真正做到数据驱动。
(三)定位系统故障
人工时时盯着指标,是一个非常辛苦的活,更好的选择是由机器来盯着这些指标,您设定好规则,机器发现这些指标超出异常范围的时候,自动给你触发发送报警,Pigsty里面提供了一系列的报警规则,同时报警事件也可以在监控系统的面板里面看到,通过这种条状甘特图的方式,我们可以看到哪一个时间段触发了报警事件,从而有的放矢的去排查。报警系统提供了很多计算好的衍生指标,所以不用再写特别复杂的表达式,可以直接用。
(四)系统水位评估
1.水位评估: 饱和度的历史分位点
除了直观的衡量实时的数据库负载水平,还可以用来计算数据库的水位,水位就是一个长期的资源使用量指标,通常来说,如果我们的某一个数据库集群长时间处于高负载状态,我们就是说它水位比较高,我们可能就要给它扩容。如果它长时间处于低水位状态,处于闲置,那么我们就要给他缩容。
扩容和缩容的依据就是所谓的水位,水位就是过去某一个时间段饱和度的百分位点。比如说现在采用的就是过去一天里面水位的99分位点,对于那种有周期性的负载来说,一天是一个比较好的这种衡量指标,如果您的业务周期性是一周或者一月,可以使用过去一周或者一月的饱和度数据,来计算它的99分位点或者99.99分位点,来评估集群的水位。比如这里某一套集群,它的水位是30%,那么就是意味着系统在过去一天的99%的时间里面,它的资源使用率都在30%以内,我们就认为它的水位是30%。像这样的指标对于评估长时间段系统的资源利用率很有用。评估资源利用率,就可以评估成本,及时的进行优化,这是一个典型应用。
三、How 如何部署一套监控系统?
(一)开源软件
参考文档:http://pigsty.cc
(二)公开文档与演示
l 上手
基于Vagrant,快速在本机拉起演示系统。
这篇文档将介绍如何在您手头的笔记本或PC机上,基于Vagrant与Virtualbox,拉起Pigsty演示沙箱。
本教程着眼于在本地单机创建Pigsty演示环境,如果您已经有可以用于部署的机器实例,可以参考部署教程。
l 太长;不看
如果用户的本地计算机上已经安装有Vagrant、Virtualbox与Ansible,那么只需要克隆并进入本项目后,依次执行以下命令即可:
正常情况下执行结果详见参考-标准流程。
(三)快速上手
快速开始
git clone https://github.com/Vonng/pigsty
cd /tmp
make up
make ssh
sudo make
dns make init