开发者学堂课程【PolarDB-X 开源人才初级认证培训课程:集群运维2:监控、SQL限流与索引优化】学习笔记(一),与课程紧密连接,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/1075/detail/15544
集群运维2:监控、SQL 限流与索引优化
内容介绍:
一、 PolarDB-X 架构介绍
二、课程演示
三、如何在 PolarDB-X 中优化慢 SQL
四、 PolarDB-X SQL 限流
五、 SQL 执行的过程
六、数据库优化
七、 PolarDB-X SQL Advisor 基本原理
一、 PolarDB-X 架构介绍
主要围绕 PolarDB-X 集群运维中的一些相关知识,今天的内容主要分成两个部分,第一个部分会介绍是如何对 PolarDB-X 进行监控的;第二个部分是当 PolarDB-X 系统里面遇到了一些问题的 SQL ,我们是如何通过限流的手段对其进行处理和优化,来保障目前系统上的业务稳定运行。在开始之前,首先对 PolarDB-X 这款产品做一个简单的介绍: PolarDB-X ,是阿里云上的云原生分布式数据库,这边给出了它的架构图。
从架构图中可以看到,它由四个核心的组件构成:
1. 第一个组件,是我们的计算节点 CN。 它是整个集群流量的入口,负责收到应用服务器发过来的业务 SQL ,向其进行相应分布式的计算以及路由;同时也负责了全分布式事务的一个维护以及全 区二级索引的维护。
2. 第二个组件是我们的 DN 节点。它是实际的数据存储服务节点;同时它还通过了 paxos 协议来保证了数据的强一致和高可靠。
3. 第三个组件是我们的语言数据中心 GMS。 它存储了整个 PolarDB-X 集群中的拓扑,同时也是我们分布式事务所依赖的 TSO 的授时组建。
4. 第四个组件的话是我们的 CDC ,它的主要作用是将每个间上存在的物理 binlog 汇聚成一条与 MySQL binlog 完全兼容的逻辑 binlog流。能够让我们与大下游的大数据的生态系统进行无缝的对接。
前面提到 PolarDB-X 是一款云原生的分布式数据库,既然提到云原生的话,那自然也就绕不开 K8S 这个话题。 PolarDB-X 也在积极的拥抱了 K8S 生态,在 K8S 上也构建了自己的扩展叫 PolarDB-X Operator。基于 K8S 也有像 scheduler、apiserver、controller-manager 这样的一些基础能力,构建了 PolarDB-X 自己的控制面,能够在 K8S 集群上对 PolarDB-X 数据库进行部署以及相关的运维能力。例如依赖了 Deployment 去对 CDC 和 CN 这样的无状态的组件进行管理;依赖了类似 StatefulSet 这样的方式,对 DN 节点进行管理。除了正常的一些部署和常规的运维生命周期方面的能力外,我们还提供了像弹性伸缩、高可用、备份恢复以及监控审计等一些解决的能力。今天的课程所介绍的监控,也是围绕 K8S 的 Operator 的方式去进行构建的。
二、课程演示
首先演示如何在 K8S 集群里面为 PolarDB-X 集群安装监控;然后通过 Grafana 来访问目前监控报表。
进入操作界面后,左边是PolarDB-X Operate的监控文档,右边是在阿里云上购买的一台 ECS 。会按照监控文档的操作步骤,一起为 PolarDB-X 开启监控。
首先第一步我们需要安装 PolarDB-X monitor 。这个组件是干什么的?因为 PolarDB-X 的监控是通过 Prometheus 和 Grafana 来实现的,因此我们在 PolarDB-X monitor 这个组件里面集成了 Prometheus 这个组建站。然后只要安装了这个 monitor 组件,便可以一键安装整套的 Prometheus 的软件站。
在这个过程中有一个前置的要求,首先第一步需要有一个运行中的 K8S 集群;同时已经安装好了Helm 3;另外也需要安装好 PolarDB-X 的Operator。已经前置安装好了。通过 kubectl get PolarDB-X clustrt 的方式,可以看到已经安装好了 PolarDB-X 的Operate和创建好了一个 PolarDB-X 的实例。这边的操作过程和前两天在课程中使用的云起实验室是类似的,同时这边也可以通过 kubectl get PXC 这个命令来查看 PolarDB-X 的状态。可以理解为 PXC 就是 PolarDB-X cluster 这个资源的缩写。接下来将按照监控文档中的步骤来开启监控。首先需要创建一个叫 PolarDB-X - monitor 里头的命名空间,通过 kubectl create namespace polardbx- monitor 这个命令来创建一下。创建完成,接下来,由于 PolarDB-X Operate 是直接安装的,所以说这边 monitor 的 CRD 和下面这部分是可以跳过的。
下面直接去通过 Helm Chart 仓库的方式来安装 PolarDB-X monitor 这个组件。第一步是添加一个 PolarDB-X 的 Helm仓库,我已经把它添加进来;接下来我会使用 helm instell --namespace palardbx --monitor or polardbx -monitor or polardbx/polardbx- monitor 这样一条命令来去创建的 PolarDB-X monitor 。这边有一个需要说明的地方,因为是在 ECS 上通过minikube 的方式虚拟化出了一个 K8S 的集群,而monitor 组件里面由于依赖了 Prometheus ,他默认的资源要求会相对较高一点,如果在minikube上去安装,需要将它的一个资源通过压膜文件的方式来默认调小一点,这样就会能够保证它创建成功,要不然可能会出现因为资源不够导致的创建失败。这边已经准备好了一个 values 文件,通过 -f 的参数去指定它就可以去对它进行创建。已经创建出来了,来看一下 values 文件的内容。
可以看到 values 文件里面定义了 monitor 里面的 Prometheus 组件,将它的resource的 lim RT 限制到了2c 8G,然后request的限制到了 1c2G 。这一部分的内容已经在监控文档上有了说明,可以参考监控文档,按这个操作来进行。已经看到了上面的这样的一个输出,就是表示 PolarDB-X monitor 已经安装完成了。
接下来去查看一下 PolarDB-X monitor 里面依赖的相关组件是否到了 ready 的状态。通过这样的一个命令: kubectl get pods -n polardbx- monitor 来查看 PolarDB-X monitor 这个命名空间下,所有的 pod 是否引起来。可以看到这边的所有的 pod 都已经到了 ready 的状态,它主要包括几个关键的组件,第一个是 Grafana ,是一个可视化组件;然后还有 node exporter 是我们资源采集的组件;然后还有一个最重要的 Prometheus 。这几个组件都已经进入了一个 ready 的状态。
那接下来就将 PolarDB-X 实例开启监控。已经先创建好了一个 PolarDB-X 的实例,要为他开始监控,需要创建一个叫 PolarDB-XMonitor 的对象。这个对象的内容,会通过 polardbx- monitor .yaml 的样本文件去定义。它的内容也比较简单,第一个部分就是它 kind资源类型是 PolarDB-X monitor 的类型;然后它的名字你可以随便起一个,这边直接就叫PXC dome monitor 。然后 spec 部分有三个关键的参数:第一个是我 clusterName ,它表示的是需要开启监控的 PolarDB-X 集群的名称,也就是对应的通过上面这个命令拿到的PXC的demo;下面,第二个参数是 monitor interval,它表示的是监控采集的间隔,这边我设了一个15秒;然后第三个是scrapeTimeout ,表示的是监控数据每次采集的一个超时时间。有了这样的文件,通过 kubectl apply 的方式来创建一下这个 PolarDB-X monitor 的对象。通过 kuberctl get pxm 这个命令,这个对象已经创建完成,目前正在监控的状态。
接下来来访问一下 Grafana Dashboard 查看具体的监控指标。通过这样: kubectl part-forward svc/grafana -n polardbx- monitor 3000命令将这个 Grafana 的服务转化到本地。看一下 Grafana 创建了哪些service。可以看到在 PolarDB-X monitor 空间下创建了 Grafana Service ,还有 Prometheus 的 Service 。监控报表就是在 Grafana Service 上面,所以通过这样一条命令 kubectl part-forward svc/grafana -n polardbx- monitor 3000 将端口转化到这台 ECS 上。这里有一个说明,因为需要从本地的MAC电脑来访问这台 ECS ,因此它是要从外部即时访问,需要加上一个更高address 的参数,大家可以看一下,就是要等于0.0.0,这边还没显示到,我把它拖一下---address -0.0.0,等于0.0.0。
然后对它进行一个端口的转发,接下来我通过浏览器来访问一下的监控页面。第一次访问可能要稍等一小会,转换请求断了,重新转发一次应该就好了,再重新打开。已经进入到了 Grafana 的登录页面。
默认的用户名和密码都是 admin,密码我就不重设了,直接通过 skip 的方式跳过了。这边也开启一个 sysbench 的压缩测流量来把请求打起来。也准备好了 sysbench 压测流量,直接就是把它开启。有一个叫sysbench select的 get pod 正在启动,稍等一下。他已经起来了,来看一下它的日志 kubectl logs,可以看到它的流量已经起来了,目前的 QPS 大概在四千多左右。接下来访问一下我们的监控页面,可以看到现在的监控页面已经展示出来了。
目前, QPS 在四千八左右,然后 RT 的话在1.34毫秒。
首先简单介绍一下我们的 PolarDB-X 监控页面的分布。它分成这么几个部分:
第一个部分的话是 Overview 部分,他给出了几个重要的指标的概括干情况,然后下面的话分别是我们的 GMS 、CN 、 DN 和 CDC 四个不同组件的详细的监控指标。
对 Overview 部分的两个指标做一下简单的介绍:
1. 第一个是 QPS ,可以看一下是分成了两个,一个叫逻辑 QPS 也就是 Logical QPS ,一个叫physical QPS ,就是物理 QPS 。它们两个分别代表的是什么含义?逻辑 QPS 表示的是应用服务器发送的业务 SQL 到 PolarDB-X 每秒的 SQL 数;物理 QPS 对应的是 PolarDB-X 经过相应的分布式的路由与计算,将逻辑 SQL 转化成了对应的物理 SQL ,下发到边上每秒的 SQL 数。这边可以看一下,我们的逻辑 QPS 和物理 QPS 是比较接近的,它说明的一个问题是基本上所有的业务需求都是只涉及单个 DN 分片的一个查询,属于偏点查点写的业务。那假如突然发现物理 QPS 远远高于我的逻辑 QPS ,这时候可能就是要注意,有可能我们的业务中有一些 SQL 它涉及了较多的分片查询,就需要关注是否需要对其进行优化。
2. 另外一个指标是 Response Time ,也就是 RT ,它也是分成了逻辑和物理两部分。逻辑 RT ,表示的是我应用服务器发送 SQL 到 PolarDB-X ,直到我们把所有的处理结果返回到应用服务器的时间。而物理 RT 的话表示的是 PolarDB-X 的 CN 节点把物理 SQL 发到 DN 节点,然后 DN 反馈结果给了 CN 节点的时间。通过这两个指标的话,可以帮助我们判断当前系统的瓶颈主要在哪里。例如我们发现系统的 RT 突然上升了,这时候去看发现主要的变化是物理 RT 占了大部分,这时候主要的系统的问题主要在 DN 层面;假如发现物理 RT 并没有什么变化,但是逻辑 RT 却上升的很高,那很有可能系统的瓶颈点就出现在了 CN 层。通过这两个指标能够帮助我们快速的定位系统的状态,以及可能出现问题的组件。
3. 另外这个报表里面还有很多其他的一些监控指标,可以自己去按照我们的文档操作去体验、去上面去查看。这边我就不再续一一做详细的介绍了。接下来我将继续介绍我们的内容。
首先对刚才演示的 PolarDB-X 监控能力的架构做一个简单的介绍。
监控,首先看一下监控指标的采集层,它的指标分成两种类型,一部分的话是我们的引擎相关的指标,例如像刚才说的 QPS 、 RT 等等的指标,这些指标针对一个不同的组件构建了一个 Exporters 的服务,他通过HTTP的方式来暴露监控指标, Prometheus 会定期的从这边来拿取数据,这个定期就是我们刚才在 PolarDB-X monitor 的这个对象里面填的monitor interable 这个参数决定的。对于资源层面,例如像CPU、内存这些基本的指标,是通过开源的lowder Exporter 去暴露的。
刚才在 PolarDB-X Monitor 这个命名空间下也创建好了一些 node Exporter 的这样的 pod 去负责监控的采集。采集完监控指标之后, Prometheus 会将它的监控指标存在内部的持续数据库里面,之后 Grafana 的data监控报表会通过 PromQL 这种方式来从 Prometheus 里面拿取监控数据构建一些图表,让我们了解实例的运行状况。除此之外,我们是对于 Prometheus 的 cluster ,我们是通过 Prometheus Operator 这个组件来去管理的,这样它可以帮助我们去有效的去部署和管理 Prometheus 的集群。另外对于一个 K8S 集群内,哪些 PolarDB-X 实例需要监控,然后以什么样的频率监控,那这都是刚才创建的 PolarDB-X monitor 这个对象所控制的,它会告诉 Prometheus 我需要采集哪些实例的监控指标。
这就是整个 PolarDB-X 在 K8S 上构建的监控体系的基本架构。
三、如何在 PolarDB-X 中优化慢 SQL
接下来开始下一个部分,当就是PolarDB-X 集群如果遇到了一些问题 SQL 的时候,是如何通过已有的一些手段来对它进行处理优化,来保障系统的一个稳定运行的。会介绍两个能力,一个是 SQL 限流,另外一个叫 SQL advisor ,就是索引推荐。这部分的能力,目前我们已经在云起实验室中上线了相关的课程,今天也会直接通过云起实验室的课程来进行演示。直接打开我的游戏实验室的链接,这边已经可以看到有一个实验叫做如何在 PolarDB-X 中优化慢 SQL 。
首先需要创建一下实验相关的资源,稍等一下,资源应该已经创建完成了。之后去登录,已经登录上来了。接下来会按照实验手册的步骤,一步一步的去进行操作。第一步是需要连接 PolarDB-X 集群,首先需要切换账号到 galaxykube 下面,这个已经预制在我们这台机器上了;接下来我需要通过下面这个命令: minikube start --cpus4-- memory 12288--imag -- mirror --country cn--registry -mirror -https://docker.
创建一个 minikube 的 K8S 集群,需要稍等一下。集群其实已经在这台 ECS 上准备好了,现在只是把它重新拉起来,这边已经拉起来了。接下来的话,这边其实已经提前我们这边已经提前创建好了一个 PolarDB-X 集群。正在启动中,可能需要一点时间。目前 GMS 和 DN 已经起来了,就差 CN 和 CDC 了,来看一下它 pod 的情况。因存在错误,我把刚刚这个集群删掉,重新创建一下。可能预制在 ECS 上的集群有一些问题。 K8S operter 已经把它拉起来,稍等一下。把 CN 的pod 给 delete 下。
我们的 CN 已经ready了,现在就差一个CDC了;CDC 已经ready状态,接下来按照这个命令,先拿到这个集群的登录密码,那这条命令其实就是从 K8S 里面的 SQL 的获取到 PolarDB-X 里面相关的密码。密码都是存在 SQL 的这个对象里面的,然后将其进行,进行一个 base 64的解码,就可以拿到这样的一个密码。接下来需要将这个 PolarDB-X 实例的3306端口转发到我这台机器上,通过kubectl put forward这个命令就可以实现。在这基础之上,需要再新开一个窗口,通过这边的加号命名,开了一个新的终端。之后通过 MySQL 命令行的方式来登录这个实例。然后密码是刚刚获取到的。已经登录上来了,来看一下里面数据库的情况,可以看到现在是一个空的实例。
接下来按照下一步来进行操作。首先需要启动一个 sysbench 的业务,创建一个database叫sysbench test,接下来用使用这个 sysbench test,我会use一下这个库,登录到这个数据库里面。好已,经change过来,来show tables。目前这是一个 kube 库,接下来按照第三步,需要在页面的右上角重新再创建一个新的终端三。然后切换到 Galaxy kube 这个账号下,之后到 Galaxy kube 这个账号的主目录,编辑一个 sysbench prepare 的 yaml 文件,然后这个 yaml 文件的内容,在下面这边已经给出来了,将它复制进来。它其实就是一个 K8S 的一个job,使用的镜像的话是 sysbench 的公开镜像,在参数部分我们配置了 PolarDB-X 实例的连接信息,包括连接串端口、用户名密码,同时我这边会导入一个16万行的数据,使用的是 sysbench 里面的 parallel prepare 这一个场景。
接下来把这个文件保存然后通过 kubectl apply sysbench .yaml的方式创建一下 job 对象来导入数据。看一下这个job是不是创建出来了: kubectl get jobs ,显示已经正在创建,然后来 kubectl get pods ,可以看到这边这个 sysbench prepare date 的 pod 正在创建中。它已经开始运行,看一下它的日志。通过 kubectl logs 命令就可以看到它正在导入一个16万行的数据到一个叫 sbtest1 的表里面。
数据已经导入完成,接下来我会启动一个 sysbench 的一个压测流量,这边可以看一下这个名字叫: vim sysbench -select .yaml,是通过 vim 的方式创建这个 yaml 文件。把里面的内容先粘进去,然后解释一下,它也是一个 K8S 的 job,使用的容器还是和刚刚准备数据的容器是一样的,也是 sysbench 的一个公开镜像。另外也是配置了刚刚实例的一个连接串,同时我们这边采用的压测场景是select random points,就是一个随机的点察。下面我会把这个压测流量开起来,保存好,然后通过kubectl apply的方式来创建一下这个 job :kubectl apply-f sysbench-select.yaml 。
创建完成后,通过 kubectl get pods 来查看一下这个运行中的pods 。可以看到这个 kubectl select-k 这个pods已经起来了。来观察一下他的日志,可以看到压测流量目前已经起来,现在他的 QPS 大概在六七百的样子。
接下来开始下一步,去体验 SQL 限流和SQL Advisor 的。现在假设模拟了一下 sysbench 的压测流量是一个存在问题 SQL 的业务,然后它占用了较多的资源,对线上的其他业务产生了一定的影响。接下来就需要去找到这个问题 SQL ,然后将其进行一个限流。首先的话,回到刚刚第二个终端的页面,也就是刚刚研究 sysbench test 的数据库,然后通过执行这样一条语句叫 show full processlist where info is not full 查看当前这个数据库里面执行的 SQL 情况,这边可以看到目前压测流量里有大量的 SQL 叫 SELECT id,k,c,pad ,然后它是一个基于k列的查询。假设它对我们的系统业务造成了影响,然后影响了其他的在线业务。这时候的话我可以通过 PolarDB-X 提供的SQL限流语法来快速的创建一个 SQL 限流规则,把这条 SQL 拦截起来,不让他去消耗我们的资源。
这边我把这条限流规则创建出来,解释一下这个规则:这边是 creat ccl_rul 是关键字。然后起的这个ccl_rul 的一个限流规则的名字叫 block_select ,它是对 sysbench 这个 test的数据库是生效的,然后只对select语句生效,同时会通过关键字 pad 来去进行限流,最后是 max concurryency ,限定的是0,就是说不允许这条 SQL 在我们的系统上执行。
接下来切到之前刚刚的终端里面的 sysbench 流量,看一下现在发生了什么。可以发现 sysbench 流量已经变零了,有大量的报错。这说明刚刚这个业务起来的 SQL 已经被全部拦截,不会被执行了。接下来通过左边的一条命令叫 show ccl_rules 能够查看一下我当前 SQL 限流规则的运行状况。第一个这边能看到它的一个 rule 的名字,就是刚刚创建的叫block select,接下来他给出了我目前这个规则已经 killed 的SQL请求数,目前已经 killed 了17万的数目;下面的话给出的是我们 SQL 限流的一些匹配规则,比如说只针对select的语句规则去限流,然后的话用户是 PolarDB-X rule 的,然后关键字的话是一个包含 pad 的 SQL 。这样,它就已经起到了个限流的效果,保证了我业务的稳定正常运行。把这条业务 SQL已经限流住了,恢复了正常的在线业务,下面要做的事便是要去分析一下刚刚这条 SQL 为什么会导致系统问题。首先的话对于有经验的 DBA ,可能第一件事是去看一下它的执行计划以及这张表的结构。
通过刚刚云起实验室里的命令,这边已经打出了执行计划。可以看到这条查询的话是涉及到了我们有八个分片上的查询,然后的话会下发到每一个分片上去进行这样的查询请求。而这个 k 的话,它的in值只是一个值,所以说它的最终的结果只会存在一个分片上。因此我们来看一下这张表的结构。
我们是有几个列:一个是 id ,k、c还有一个 pad 。 id 的话你可以看到它是我们的一个分库件;k的话既不是分库件也不是分表键,但是我们在上面有一个本地的索引,由于只有本地索引的存在,而没有全 区索引的存在,所以不知道 k等于10这条数据会具体落在哪几个分片上,因此我会把这条 SQL 转化成一个相应的物理 SQL 下发到所有的分片,造成一定的不必要的查询。这时候有经验的DBA 的话可能会想到的一个操作:就是我针对这个 k的列,创建一个全 区二级索引,这样就能减少不必要的分辨查询操作。 PolarDB-X 为我们已经提供好了一个很方便的工具叫 explain advisor 的命令,它能够帮助我们自动的去做一个索引推荐的操作,而不要我们去再做刚刚这样的SQL分析。
来执行一下。 explain advisor 就是关键字,后面跟的就是这条需要去分析的SQL的文本:SELECT id,k,c,pad from sbtest1 where k in(10)\G 可以看出他给出了一个推荐的索引叫 ADVISE_INDEX ,可以看到他推荐的也是创建一个关于k这个列的全区二级索引。同时这边我们还给出了我们预估创建完这个索引之后,性能提升的一个比例,看到会有一个37%的提升。另外,我们的结果里还给出一旦把这个索引创建出来后我们最新的执行计划会变成什么样的情况。
接下来将按照这个 SQL advisor 给出的建议来创建一下索引。这个已经创建完成,由于刚刚已经创建了一个 SQL 限流的规则把有问题的 SQL 给拦截了,所以要把这个限流规则给删除掉,理论上如果刚刚创建的这个全区会对那条 SQL 进行一个优化,来提高它的一个执行效率。接下来把这个刚刚的限流规则给删掉,这时候接着看一下刚刚的 sysbench 的流量。这边可以看到在前面因为有 SQL 限流规则的存在,流量跌零之后,把 SQL 限流规则给清理掉,流量已经开始恢复。另外一个现象是在最初这条 SQL 之前的 QPS 只有大概七八百的样子,等把刚才加上了刚刚的推荐出来的全区二级索引,整个的实例的QPS 已经到了2000左右,它的执行效率得到了大大的提升。这便是云起实验室里面演示的SQL adviser和SQL限流两个内容。这部分实验就演示就到这里,接下来开始对这今天实验中内容做知识的介绍。