写点什么

使用 Prometheus 和 Grafana 实现 SLO

  • 2019-02-14
  • 本文字数:4014 字

    阅读完需:约 13 分钟

使用Prometheus和Grafana实现SLO

在线服务的目标应该是提供与业务需求匹配的可用服务。此流程的关键部分应该涉及组织中的不同团队,例如,从业务开发团队到工程团队。


要验证一个服务如何符合这些目标,可以用这些目标可衡量的“成就”来定义“阈值”,例如,“服务必须在 99.9%的时间内可用”,这应该与用户的期望和业务连续性相匹配。

SLA, SLO, SLI

已经有很多关于这些话题的文章,如果你不熟悉这些术语,我强烈建议你先阅读谷歌关于 SLO(服务级别目标)的 SRE 书籍中的文章。


总而言之:


  • SLA:服务水平协议

  • 你承诺向用户提供的服务,如果你无法满足,可能会受到惩罚。

  • 例如:“99.5%”的可用性。

  • 关键词:合同

  • SLO:服务水平目标

  • 你在内部设置的目标,驱动你的测量阈值(例如,仪表板和警报)。通常,它应该比 SLA 更严格。

  • 示例:“99.9%”可用性(所谓的“三个 9”)。

  • 关键字:阈值

  • SLI:服务水平指标

  • 你实际测量的是什么,以确定你的 SLO 是否在满足目标/偏离目标。

  • 示例:错误率、延迟。

  • 关键词:指标。

SLO 关注时间

99%的可用性意味着什么?它不是 1%的错误率(失败的 http 响应的百分比),而是在一个预定义的时间段内可用服务的时间百分比。



在上面的仪表板中,服务在 1 小时内的错误率超过 0.1% (y 轴为 0.001)(错误峰值顶部的红色小水平段),从而在 7 天内提供 99.4%的可用性:



这一结果中的一个关键因素是你选择度量可用性的时间跨度(在上面的示例中为 7 天)。较短的周期通常用作工程团队(例如 SRE 和 SWE)的检查点,以跟踪服务的运行情况,而较长的周期通常用于组织/更广泛的团队的评审目的。


例如,如果你设置了 99.9%的 SLO,那么服务可以停机的总时间如下:


  • 30 天:43 分钟(3/4 小时)

  • 90 天:129 分钟(~2 小时)


另一个无关紧要的“数字事实”是,给 SLO 多加一个 9 都会产生明显的指数级影响。以下是 1 年的时间跨度的时间组成部分:


  • 2 个 9: 99%: 5250min (87hrs 或 3.64 天)

  • 3 个 9: 99.9%: 525min (8.7hrs)

  • 4 个 9: 99.99%: 52.5min

  • 5 个 9:99.999%:5min< -经验法则:5 个 9 -> 5 分钟 (每年)

输入错误预算

在服务可以停机的允许时间内,上面的数字可能被认为是错误预算,你可以从以下事件中消耗这些错误预算:


  • 计划维护

  • 升级失败

  • 意想不到的故障


实际的结果是,上面的任何一种情况都将消耗服务的错误预算,例如,意外的停机可能会耗这些预算,从而在此期间阻止进一步的维护工作。

SLI 与度量有关

从上面可以清楚地看出,必须有服务指标来告诉我们什么时候认为服务可用/不可用。有几种方法可以做到这一点:


  • RED:速率、错误、持续时间。

  • USE:利用率、饱和度和错误。

SLO 实现例子

让我们举一个具体的例子,遵循 RED 方法(因为我们现有的度量标准更适合这种方法):通过 Prmoetheus 和 Grafana 等监控工具创建警报和 dashboard,以支持 Kubernetes API 的目标 SLO。


此外,我们将使用 jsonnet 来构建规则和仪表盘文件,充分利用现有的库助手。



本文不是解释如何在服务超出阈值时发出信号,而是重点介绍如何记录服务处于这种情况的时间。


本文的其余部分将着重于创建 Prometheus 规则,以根据特定度量标准(SLI)的阈值捕获“超出 SLO 的时间”。

定义 SLO 目标和指标阈值

让我们定义一个简单的目标:


  • SLO:99%,来自以下数据:

  • SLI

  • 错误率低于 1%

  • 请求的 90%的延迟小于 200ms


以 jsonnet 的形式编写上述规范(参见[spec-kubeapi.jsonnet]):


slo:: {  target: 0.99,  error_ratio_threshold: 0.01,  latency_percentile: 90,  latency_threshold: 200,},
复制代码

找到 SLIs

Kubernetes API 公开了几个我们可以作为 SLIs 使用的指标,使用 Prometheus rate()函数在短时间内 (这里我们选择 5min,这个数字应该是抓取间隔的几倍):


  • apiserver_request_count:按verbcoderesource对所有请求进行计数,例如,获得最近 5 分钟的总错误率:


sum(rate(apiserver_request_count{code=~"5.."}[5m])) /sum(rate(apiserver_request_count[5m]))
复制代码


上面的公式放弃了所有的指标标签(例如,通过 httpverbcode)。如果你想保留一些标签,你需要做如下的事情:


sum by (verb, code) (rate(apiserver_request_count{code=~"5.."}[5m]))  / ignoring (verb, code) group_leftsum (rate(apiserver_request_count[5m]))
复制代码


  • apiserver_request_latencies_bucket:由动词表示的延迟直方图。例如,要获得以毫秒为单位的第 90 个延迟分位数: (注意,le“less or equal”标签是特殊的,因为它设置了直方图桶间隔,参见[Prometheus 直方图和摘要][promql-直方图]):


histogram_quantile (  0.90,  sum by (le, verb, instance)(    rate(apiserver_request_latencies_bucket[5m])  )) / 1e3
复制代码


在这里了解更多的:


编写 Prometheus 规则来记录所选的 SLI

PromQL是一种非常强大的语言,尽管截至 2018 年 10 月,它还不支持范围的嵌套子查询。我们需要能够计算error ratio或超出阈值的latencytime ratio


另外,作为一种良好的实践,为了减少查询 Prometheus 资源使用的时间,建议在诸如sum(rate(…))之类的预计算表达式中添加记录规则。


举一个例子来说明如何做到这一点,下面的一组记录规则是从我们的[bitnami-labs/kubernetes-grafana-dashboards]存储库中构建的,用于捕获上面的time ratio


创建一个新的kubernetes: job_verb- code_instance:apiserver_requests:rate5m指标来记录请求速率


record: kubernetes:job_verb_code_instance:apiserver_requests:rate5mexpr: |  sum by(job, verb, code, instance) (rate(apiserver_request_count[5m]))
复制代码


  • 使用上面的度量,为请求的比率(总的)创建一个新的kubernetes: job_verb-code_instance:apiserver_requests:ratio_rate5m


record: kubernetes:job_verb_code_instance:apiserver_requests:ratio_rate5mexpr: |  kubernetes:job_verb_code_instance:apiserver_requests:rate5m    / ignoring(verb, code) group_left()  sum by(job, instance) (    kubernetes:job_verb_code_instance:apiserver_requests:rate5m  )
复制代码


  • 使用上面的比率指标 (对于每个 http codeverb),创建一个新的指标来捕获错误率:


record: kubernetes:job:apiserver_request_errors:ratio_rate5mexpr: |  sum by(job) (    kubernetes:job_verb_code_instance:apiserver_requests:ratio_rate5m      {code=~"5..",verb=~"GET|POST|DELETE|PATCH"}  )
复制代码


  • 使用上面的错误率(以及其他类似创建的kubernetes::job:apiserver_latency:pctl90rate5m,用于记录过去 5 分钟内的第 90 个百分位延迟,为简单起见,未在上面显示),最后创建一个布尔指标来记录 SLO 遵从性情况:


record: kubernetes::job:slo_kube_api_okexpr: |  kubernetes:job:apiserver_request_errors:ratio_rate5m < bool 0.01    *  kubernetes::job:apiserver_latency:pctl90rate5m < bool 200
复制代码

编写 Prometheus 警报规则

上述kubernetes::job:slo_kube_api_ok最终指标对于仪表板和 SLO 遵从性的解释非常有用,但是我们应该警惕上面哪个指标导致 SLO 消失,如下面的 Prometheus 警报规则所示:


  • 高 API 错误率警告:


alert: KubeAPIErrorRatioHighexpr: |  sum by(instance) (    kubernetes:job_verb_code_instance:apiserver_requests:ratio_rate5m      {code=~"5..",verb=~"GET|POST|DELETE|PATCH"}  ) > 0.01for: 5m
复制代码


  • 高 API 延迟警报


alert: KubeAPILatencyHighexpr: |  max by(instance) (    kubernetes:job_verb_instance:apiserver_latency:pctl90rate5m      {verb=~"GET|POST|DELETE|PATCH"}  ) > 200for: 5m
复制代码


请注意,Prometheus 来自已经显示的 jsonnet 输出,阈值可以分别从$.slo.error_ratio_threshold$.slo.latency_threshold中评估得出。

以编程方式创建 Grafana 仪表板

创建 Grafana 仪表板通常是通过与 UI 交互来完成的。这对于简单的和/或“标准”仪表板(例如,从https://grafana.com/dashboards )下载)来说是很好的,但是如果你想要实现最好的 devops 实践,特别是对于gitops工作流,就变得很麻烦了。


社区正在通过各种努力来解决这个问题,例如针对jsonnetpythonJavascript的 Grafana 库。考虑到我们的jsonnet实现,我们选择了grafonnet-lib


使用jsonnet来设置 SLO 阈值和编码 Prometheus 规则的一个非常有用的结果是,我们可以再次使用它们来构建 Grafana 仪表板,而不必复制和粘贴它们,也就是说,我们为这些保留了一个真实的来源。


例如:


  • 关于$.slo.error_ratio_threshold,在我们的 Grafana 仪表板中设置 error_ratio_threshold 来设置 Grafana 图形面板的阈值属性,就像我们在前面为 Prometheus 警报规则所做的那样。

  • 记录metric.rules.requests_ratiorate_job_verb_code.record使用情况(而不是’kubernetes: job_verb_code_instance:apiserver_requests:ratio_rate5m'):


// Graph showing all requests ratiosreq_ratio: $.grafana.common {  title: 'API requests ratios',  formula: metric.rules.requests_ratiorate_job_verb_code.record,  legend: '{{ verb }} - {{ code }}',},
复制代码


你可以在dash-kubeapi.jsonnet上了解我们的实现情况,下面是生成的仪表板的屏幕截图:


总结

我们在jsonnet文件夹下的 bitnami-labs/ kubernets-grafana -dashboards 存储库中实现了上述想法。


我们构建的 Prometheus 规则和 Grafana 仪表盘文件来自 jsonnet,如下所示:



  • [spec-kubeapi.[jsonnet]:尽可能多的数据规范(阈值、规则和仪表板公式)

  • rules-kubeapi.jsonnet:输出 Prometheus 记录规则和警报

  • dash-kubeapi.jsonnet:输出 Grafana 仪表盘,通过我们选择的 bitnami_grafana.libsonnet 使用 grafonnet-lib


自从我们开始这个项目以来,社区已经创建了许多其他有用的 Prometheus 规则。点击 srecon17_americas_slides_wilkinson查看有关这方面的更多信息。如果我们必须从头开始,我们可能会使用kubernetes-mixinjsonnet-bundler


2019-02-14 09:5511921
用户头像

发布了 124 篇内容, 共 50.1 次阅读, 收获喜欢 177 次。

关注

评论 1 条评论

发布
用户头像
干货干货
2019-03-04 18:12
回复
没有更多了
发现更多内容

数智焕新| AI+人才供应链:从"岗找人"到"智配人"的升维革命

用友BIP

Web3 项目开发的技术难点

北京木奇移动技术有限公司

区块链技术 软件外包公司 web3开发

The AI Moat Pyramid:构建不可复制的 AI 护城河

Baihai IDP

人工智能 AI LLM Baihai IDP

Web3 项目的开发框架

北京木奇移动技术有限公司

区块链技术 软件外包公司 web3开发

HarmonyOS NEXT仓颉开发语言实战案例:简约音乐播放页

幽蓝计划

高德开放平台SDK鸿蒙版,助力千余家应用高效构建LBS服务

高德开放平台

鸿蒙 sdk 高德地图

闪迪创作者系列赋能插画师:从碎片化灵感到完整创作的自由之路

极客天地

Web3项目开发的安全性

北京木奇移动技术有限公司

区块链技术 软件外包公司 web3开发

由 Mybatis 源码畅谈软件设计(八):从根上理解 Mybatis 二级缓存

京东科技开发者

电商媒体必看:淘宝天猫商品详情接口指南

tbapi

淘宝商品详情接口 淘宝API 天猫商品详情接口 天猫API 电商社媒

数智焕新| AI+财务,开启企业财务效率革命与决策升级

用友BIP

Syslog 日志分析与异常检测技巧

运维有小邓

日志管理软件 Syslog日志管理

SNMP协议在设备监控中的使用

京东科技开发者

【KWDB 2025 创作者计划】_一文带你了解 KWDB 数据库

KaiwuDB

什么是 QueryGPT?智能查询工具如何重塑信息检索的未来?

镜舟科技

数据分析 StarRocks 数据查询 QueryGPT 多模态交互

HarmonyOS NEXT仓颉开发语言实现画板案例

幽蓝计划

ISO 50015能源验证标准如何落地?MyEMS用开源技术给出答案

开源能源管理系统

开源 能源管理 开源能源管理系统 ISO 50015

AI 英语背单词 App的主要功能

北京木奇移动技术有限公司

软件外包公司 AI英语学习 AI技术应用

三步根治前端缓存“顽疾”

京东科技开发者

注册转化率飙升 50%?一键登录的魔法来了

MobTech袤博科技

给Javaer看的大模型开发指南|得物技术

得物技术

大模型

MyEMS开源能源管理系统核心代码解读005

开源能源管理系统

#开源#能源管理#代码解读

AI经济(MachineFi)初探:AI代理之间如何支付?

PowerVerse

AI Agent 代理式AI

巅峰对决 · 超三十万奖金等你挑战!第十届“信也科技杯”全球 AI 算法大赛火热开赛!

猫头虎

人工智能 算法

Apache Cloudberry 2.0 前瞻:功能与改进速览

酷克数据HashData

小米AI眼镜暴露了雷军的“野心”

趣解商业

人工智能 小米 科技 AI眼镜

智慧物业综合管理解决方案

微擎应用市场

智能体(AI Agent)开发实战之【LangChain】(四)结合大模型基于RAG实现本地知识库问答和纠错

我和AI的成长

AI 人工自能 langchain AI Agent AI 智能体

运营总监的秘密武器:秒验一键登录如何提升次日留存

MobTech袤博科技

MyEMS开源能源管理系统核心代码解读006

开源能源管理系统

开源 能源管理 代码解读

使用Prometheus和Grafana实现SLO_软件工程_JUANJO CIARLANTE_InfoQ精选文章