理解TiDB集群的P99计算方式

原文来源: https://tidb.net/blog/c38dd8ac

一、背景简介

在学习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中获取到: image.png

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解释起来需要多些几句,这不是本文重点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/58118.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jq插件:jqgrid和validform的二次封装

做久了vue和react框架项目,偶尔也需要做做原生的项目。不可否认vue的双向绑定机制确实很香,但是也是建立在原生js基础上。所以,只有做更多的原生js项目,才能更加了解vue框架的底层原理。在日常开发中,也会不可避免的会…

mybatis:动态sql【2】+转义符+缓存

目录 一、动态sql 1.set、if 2.foreach 二、转义符 三、缓存cache 1. 一级缓存 2. 二级缓存 一、动态sql 1.set、if 在update语句中使用set标签&#xff0c;动态更新set后的sql语句&#xff0c;&#xff0c;if作为判断条件。 <update id"updateStuent" pa…

jmeter+ant+jenkins接口自动化测试框架

大致思路&#xff1a;Jmeter可以做接口测试&#xff0c;也能做压力测试&#xff0c;而且是开源软件&#xff1b;Ant是基于Java的构建工具&#xff0c;完成脚本执行并收集结果生成报告&#xff0c;可以跨平台&#xff0c;Jenkins是持续集成工具。将这三者结合起来可以搭建一套We…

火山引擎云调度GTM“同城容灾”与“异地多活”实践

随着企业不断推进数字化进程&#xff0c;高并发业务和海量数据的挑战也随之而来。在现实生活中&#xff0c;除了地震、台风、挖光纤这种小概率事件&#xff0c;还有很多人为造成的高概率数据丢失事件&#xff0c;比如人为操作失误、硬件故障、网络攻击等等&#xff0c;故障容灾…

vue可编辑表格

内容包含:校验。下拉框。输入框。日期控件 效果图 1.代码目录 2.index.js import SjjEditable from ./src/editable.vue // import Vue from vueSjjEditable.install = function (Vue) {Vue.component(SjjEditable.name, SjjEditable) }export default SjjEditable 3.util…

【进阶篇】MySQL 存储引擎详解

文章目录 0.前言1.基础介绍2.1. InnoDB存储引擎底层原理InnoDB记录存储结构和索引页结构InnoDB记录存储结构&#xff1a;InnoDB索引页结构&#xff1a; 3. MVCC 详解3.1. 版本号分配&#xff1a;3.2. 数据读取&#xff1a;3.3. 数据写入&#xff1a;3.4. 事务隔离级别&#xff…

【ubuntu】 20.04 网络连接器图标不显示、有线未托管、设置界面中没有“网络”选项等问题解决方案

问题 在工作中 Ubuntu 20.04 桌面版因挂机或不当操作&#xff0c;意外导致如下问题 1、 Ubuntu 网络连接图标消失 2、 有线未托管 上图中展示的是 有线 已连接 &#xff0c;故障的显示 有线 未托管 或其他字符 3、 ”设置“ 中缺少”网络“选项 上图是设置界面&#xff0c…

【Cesium创造属于你的地球】实现地球展示、灵活进行坐标转换、视角切换

大家好&#xff0c;我是AIC山鱼&#xff01;&#x1f449;这是我的主页 &#x1f40b;作为CSDN博主和前端优质创作者✍&#xff0c;我致力于为大家带来新颖、脱俗且有趣的内容。 &#x1f431;我还创建了山鱼社区&#xff0c;这是一个独特的社区&#x1f3e0;&#xff0c;&…

供水营业收费管理系统:智慧水务的得力助手

随着我国经济的快速发展&#xff0c;城市化进程不断加快&#xff0c;供水行业的需求也不断增长。为满足人们日益增长的用水需求&#xff0c;提高供水企业的管理水平和服务质量&#xff0c;供水营业收费管理系统应运而生&#xff0c;成为智慧水务的得力助手。 一、供水营业收费管…

【Hadoop】HDFS读写流程和客户端命令使用

&#x1f341; 博主 "开着拖拉机回家"带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——&#x1f390;开着拖拉机回家_Linux,Java基础学习,大数据运维-CSDN博客 &#x1f390;✨&#x1f341; &#x1fa81;&#x1f341; 希望本文能够给您带来一定的…

ChromeOS 的 Linux 操作系统和 Chrome 浏览器分离

科技媒体 Ars Technica 报道称&#xff0c;谷歌正在将 ChromeOS 的浏览器从操作系统中分离出来 —— 让它变得更像 Linux。虽然目前还没有任何官方消息&#xff0c;但这项变化可能会在本月的版本更新中推出。 据介绍&#xff0c;谷歌将该项目命名为 "Lacros"—— 代表…

python爬虫12:实战4

python爬虫12&#xff1a;实战4 前言 ​ python实现网络爬虫非常简单&#xff0c;只需要掌握一定的基础知识和一定的库使用技巧即可。本系列目标旨在梳理相关知识点&#xff0c;方便以后复习。 申明 ​ 本系列所涉及的代码仅用于个人研究与讨论&#xff0c;并不会对网站产生不好…

Hadoop Hdfs基本命令

0目录 1.hadoop安装问题处理 2.hdfs基本命令 3.上传/下载文件和文件夹 1.hadoop安装问题处理 如果安装有进程无法启动&#xff0c;如下图 重新检查6个配置文件 Core-site.xml \ hdfs-site.xml \ hadoop-env.sh \ yarn-site.xml \ workers \ yarn-site.xml 来到hadoop313目录…

SpringBoot 跨域问题和解决方法

Spring Boot 是一种用于构建独立的、生产级别的Java应用程序的框架。在开发Web应用程序时&#xff0c;经常会遇到跨域资源共享&#xff08;CORS&#xff09;问题。本文将详细介绍Spring Boot中的跨域问题以及相应的解决方法。 目录 什么是跨域&#xff1f;1. 使用Spring Boot…

Matlab论文插图绘制模板第109期—特征渲染的标签气泡散点图

在之前的文章中&#xff0c;分享了Matlab标签散点图的绘制模板&#xff1a; 特征渲染的标签散点图&#xff1a; 进一步&#xff0c;再来分享一下特征渲染的标签气泡散点图的绘制模板&#xff0c;从而可以再添加一个维度的信息。 先来看一下成品效果&#xff1a; 特别提示&…

运用亚马逊云科技Amazon Kendra,快速部署企业智能搜索应用

亚马逊云科技Amazon Kendra是一项由机器学习&#xff08;ML&#xff09;提供支持的企业搜索服务。Kendra内置数据源连接器&#xff0c;支持快速访问Amazon S3、AmazonRDS、AmazonFSX以及其他外部数据源&#xff0c;帮助用户自动提取文档并建立索引。Kendra支持超过30多种多国语…

人工智能会成为人类的威胁吗?马斯克、扎克伯格、比尔·盖茨出席

根据消息人士透露&#xff0c;此次人工智能洞察论坛将是一次历史性的聚会&#xff0c;吸引了来自科技界的许多重量级人物。与会者们将共同探讨人工智能在科技行业和社会发展中的巨大潜力以及可能带来的挑战。 埃隆马斯克&#xff0c;特斯拉和SpaceX的首席执行官&#xff0c;一直…

无涯教程-Python机器学习 - Analysis of Silhouette Score函数

剪影得分的范围是[-1,1]。其分析如下- 1分数-接近1 剪影分数表示样本距离其邻近簇很远。 0分数-0 剪影分数表示样本在将两个相邻聚类分隔开的决策边界上或非常接近。 -1分数-1 剪影分数表示样本已分配给错误的聚类。 Silhouette得分的计算可以使用以下公式完成 $$剪影得…

没有 JavaScript 计时器的自动播放轮播 - CSS 动画

先看效果&#xff1a; 再看代码&#xff08;查看更多&#xff09;&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>计时器</title><style>* {padding: 0;margin: 0;box-siz…

JAVA JNA 调用C接口的三种方式

文章目录 1. 准备一个共享库文件2. JNA姿势1—继承Library接口3. JNA姿势2—直接NativeLibrary.getInstance3. JNA姿势3—Native方法 1. 准备一个共享库文件 test.c #include <stdio.h> int test(char *input){printf("input:%s\n",input);return 0; }libtes…