首页 > 其他分享 >理解TiDB集群的P99计算方式

理解TiDB集群的P99计算方式

时间:2023-11-10 14:37:32浏览次数:35  
标签:P99 le TiDB bucket server 集群 tidb query


一、背景简介

在学习prometheus时,会遇到一个histogram_quantile()函数,用于对histogram类型的指标进行分位数计算,实际上这个函数就是histogram这个指标类型最常用的函数。

此函数在tidb的监控图表中有一个比较明显地方使用:计算P99/P999 Duration等延迟指标。

新人们对此函数的理解是可能是一个较漫长的过程,而我观察到很多解释此函数的博主们在解释这个函数的应用场景和原理时非常容易陷入 “知识诅咒” 的陷阱,即,写作者自身非常了解这个领域的知识,但潜意识中很容易忽略读者可能对该主题或领域不了解的事实。于是在涉及某些较为简单的专有名词时会一笔带过,在涉及某些较为核心的逻辑时容易高屋建瓴的做出解释但读者却一头雾水。

不同的人认知水平不同,而即便是同一个人的认知水平也随时间增长,因此所有人都不可避免的陷入知识诅咒的陷阱,为此本文因此尝试从另一种通俗的角度来理解,希望对读者有所帮助,同时也可以极大加深自己的理解。



二、基础知识

在介绍这个函数之前,简单的介绍一下prometheus的几种指标类型:官网: Prometheus指标类型

  1. Counter:理解为一个单调递增的数字即可,适合进行请求数、错误数等累计监控,例如t1时间request_count为0,t1+10s时间计数为100,则容易得到过去10s内的请求速度约为10个/s
  2. Gauge:理解为一个非单调递增的数字即可,适合进行瞬时值监控,例如当前温度、内存使用量等,由于上报频率不可能设置的很高,因此相比Counter可能会丢失一些信息,但应用场景也很广
  3. Histogram:直方图,可以搜一下网上的直方图图片,即prometheus将位于同一范围内的数字归类到一个柱状体(bucket)内进行计数,形成一个向量(线性代数名词,这里理解为数组)除此之外还会记录实际的指标总数和总值,即一个Histogram包含一个直方图向量和2个类似Counter的指标(Prometheus server并不区分指标类型,对server来说只有time series)
  4. Summary:略,Histogram的进阶版本,不过一些编程语言的驱动可能并没有很好的支持这种类型,使用Histogram可以覆盖他的使用场景。

上述简短的解释不能真正展示4种数据类型的实质,但他们不是本篇重点因此不多说了。



三、从P99计算开始

首先列出tidb计算P99的查询语句,可以从tidb grafana中获取到:

理解TiDB集群的P99计算方式_直方图

histogram_quantile(0.99, sum(rate(tidb_server_handle_query_duration_seconds_bucket{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster"}[1m])) by (le))

因为同一个集群下的这俩标签都是一样的,我们将其简化为:

histogram_quantile(0.99, sum(rate(tidb_server_handle_query_duration_seconds_bucket[1m])) by (le))

使用postman可以快速查出他的结果:

GET /api/v1/query?query=histogram_quantile(0.99, sum(rate(tidb_server_handle_query_duration_seconds_bucket[1m])) by (le)) HTTP/1.1
Host: x.x.x.x:9090
{ 
	"status": "success", 
	"data": { 
		"resultType": "vector", 
		"result": [ 
			{ 
				"metric": {}, 
				"value": [ 1691657038.265, "0.051201495327102595" ] 
			} 
		] 
	} 
}

可以知道当前集群的P99指标约为51ms。

但是这个计算过程看起来较为繁琐,先是使用rate对tidb_server_handle_query_duration_seconds_bucket计算了过去1min的速率,然后使用sum by (le)进行了求和,最后才使用histogram_quantile函数计算99分位数。

该如何理解这种计算方式?



四、流程解析

首先思考一个问题,当我们想要获取一个P99值时,一个最直观的存储监控值的办法是什么?

当然是tidb每处理一个请求都把耗时以Gauge形式存起来,然后等prometheus来收集!

然后我们发现这种办法是在是太差了,qps高的时候监控代理和prometheus都容易爆炸。

再来分析一下实际需求,我们实质上并不是要看所有请求的耗时,只是想了解一下某个时间点(或某一段时间内)数据库中99%的请求都低于多少ms,即P99。

然后发现我们似乎不用存储具体的耗时值,我们只需要先创建一个直方图(一个包含多个bucket的容器),例如:

{
	"耗时低于1s": 0,    // bucket 1, 标签 {le: 1}
	"耗时低于10s": 0,   // bucket 2, 标签 {le: 10}
	"耗时低于100s": 0,  // bucket 3, 标签 {le: 100}
	...                // bucket n, 标签 {le: ......}
}

然后每当有请求耗时需要存储时,在对应的bucket中计数+1,这样只要bucket的设置合理一些我们就可以轻易获得一个执行耗时的分布图。在此基础上计算P99就比较容易了。

当然,除了上述的向量之外,histogram还会存储一个总耗时值和总请求次数的计数器,不过计算P99用不到。

直方图指标有了,我们把他叫做tidb_server_handle_query_duration_seconds_bucket,prometheus每个收集间隔过来取一次即可。

接下来呢?

可以看到每个bucket其实也都是一个计数器,计数器的瞬时值一般没有多少意义,因此我们需要使用rate()函数进行速率计算: rate(tidb_server_handle_query_duration_seconds_bucket[1m]

tidb_server_handle_query_duration_seconds_bucket如之前所说,他其实是一个向量值,向量值和标量值(60s)进行除法这个了解一些线代基础的可以知道结果是一个每个元素都除以60s的新向量。这个新向量的label和以前一样,都是{le: 1}, {le: 10}这种。

而tidb的请求类型很多,有select,update,insert还有analyze table,begin,commit等,我们希望统一进行计算,因此执行一个sum() group by le的操作,即:sum(rate(tidb_server_handle_query_duration_seconds_bucket[1m])) by (le)

同样的其结果依然是一个向量,我们只是按le进行了一次sql_type的聚合,至此我们终于可以使用histogram_quantile(φ scalar, b instant-vector)函数啦。这个函数接收2个参数,一个分位数值(例如0.99,0.999等),一个瞬时向量(这里就是rate处理之后的_bucket指标)。

至此我们就得到了tidb的P99。至于histogram_quantile内部如何计算99分位数这里不再解释,因为为了更贴近真实结果有一些小的tricks解释起来需要多些几句,这不是本文重点。

标签:P99,le,TiDB,bucket,server,集群,tidb,query
From: https://blog.51cto.com/tidb/8298759

相关文章

  • TiDB 源码编译之 TiProxy 篇
    作者:ShawnYanTiProxy简介TiProxy是一个基于Apache2.0协议开源的、轻量级的TiDB数据库代理,基于Go语言编写,支持MySQL协议。TiProxy支持负载均衡,接收来自应用程序的请求,然后将其发送到TiDB集群。支持自动故障转移,当后端TiDBServer发生故障,可以自动将连接转移到......
  • K8S基础:搭建K8S集群(v1.27.6)
    Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。Kubernetes拥有一个庞大且快速增长的生态,其服务、支持和工具的使用范围相当广泛。准备节点主机名IP系统&内核配置master01k8s0110.70.5.190Centos7.9,Kernel5.4.259-1.el7.el......
  • 手把手教你在虚拟机中部署Kubernetes集群(K8S)
    我们在上面:VM部署CentOS并且设置网络 部署好了服务器。接下来需要准备三个服务器分别为master节点:master  192.168.171.7node节点:node1  192.168.171.6node节点:node2  192.168.171.4此步骤需要启动三台虚拟机,并且使用xshell进行连接使用执行多个的命令来在每个服务器同步......
  • 使用rancher rke快速安装k8s集群
    概述RancherKubernetesEngine(RKE)是一个用于部署、管理和运行Kubernetes集群的开源工具。旨在简化Kubernetes集群的部署和操作。RKE具有以下特点和功能:简化的部署过程RKE提供了一个简单的命令行界面,使您可以轻松地部署一个完整的Kubernetes集群。您只需提供少量的配置信息,RKE......
  • Kubernetes常用命令及yml文件、集群网络 Kubernetes组件介绍及环境搭建
    Kubernetes常用命令及yml文件、集群网络Kubernetes组件介绍及环境搭建Kubernetes组件介绍及环境搭建一、kubernetes常用命令说明:因为k8s的命令都是通过kubectl组件接收的,这个组件只在master节点有,所以k8s的命令都是在master节点中执行kubectlgetnodes#查看当前集群中......
  • Oracle集群RAC DG日常检查指令
    目录操作系统进程检查Pmon检查负载检查数据库检查查看数据库打开状态和相关信息查找主库判断集群正常与否判断会话等待查看连接数并与数据库配置对比判断集群和DG状态RACDG操作系统进程检查Pmon检查pmon(ProcessMonitorprocess)用于监控其他后台进程。负责在连接出现异常中止......
  • Redis分片集群
    搭建分片集群主从和哨兵可以解决高可用、高并发读的问题。但是依然有两个问题没有解决:●海量数据存储问题●高并发写的问题使用分片集群可以解决.上述问题,分片集群特征:●集群中有多个master,每个master保存不同数据●每个master都可以有多个slave节点●master之间通过ping监测彼......
  • 集群中几种session同步解决方案的比较
    在集群中session安全和同步是个最大的问题,下面是收集到的几种session同步的方案,希望能通过分析其各自的优劣找出其适应的场景。1.客户端cookie加密简单,高效。比较好的方法是自己采用cookie机制来实现一个session,在应用中使用此session实现。问题:session中数据不能太多,最好只有......
  • Redis哨兵集群
    ●slave节点宕机恢复后可以找master节点同步数据,那master节点宕机怎么办?哨兵的作用Redis提供了哨兵(Sentinel)机制来实现主从集群的自动故障恢复。哨兵的结构和作用如下:●监控:Sentinel会不断检查您的master和slave是否按预期工作自动故障恢复:如果master故障,Sentinel会将一个......
  • Kurator v0.5.0发布,打造统一的多集群备份与存储体验
    本文分享自华为云社区《Kuratorv0.5.0正式发布!打造统一的多集群备份与存储体验》,作者:云容器大未来。Kurator是由华为云推出的开源分布式云原生套件。面向分布式云原生场景,Kurator旨在为用户提供一站式的解决方案,帮助用户快速构建自己的分布式云原生平台。在最新发布的v0.......