ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

VictoriaMetrics 核心概念深度指南:数据模型、采集模式与查询 API

VictoriaMetrics 核心概念深度指南:数据模型、采集模式与查询 API VictoriaMetrics 核心概念深度指南数据模型、采集模式与查询 API【免费下载链接】VictoriaMetricsVictoriaMetrics: fast, cost-effective monitoring solution and time series database项目地址: https://gitcode.com/GitHub_Trending/vi/VictoriaMetrics本文以 VictoriaMetrics 官方核心概念文档 keyConcepts.md 为骨架系统讲解监控系统中最基础也最重要的知识体系指标数据模型与时间序列、Cardinality基数、四种常用指标类型Counter/Gauge/Histogram/Summary、Push 与 Pull 两种数据采集模型、瞬时查询与范围查询两类查询 API以及 MetricsQL 查询语言的核心语法。读完本文你将能正确设计指标命名与标签、选型采集架构、精准调用查询接口并结合仓库源码理解 VictoriaMetrics 底层实现的关键取舍。数据模型Data Model什么是指标Metric简单来说metric指标是对某个事物的数值化度量或观测。监控系统中使用指标最常见的场景包括检查系统在特定时间段内的行为表现将行为变化与其他测量指标关联起来定位问题观察或预测趋势当指标超过阈值时触发事件告警。指标的结构以一个追踪应用处理请求数量的指标为例定义名为requests_total的指标。为了让指标更精确可以命名为requests_success_total仅统计成功请求或request_errors_total统计失败请求。指标命名非常重要它应当像编程中的变量名一样让每一位阅读者都能清楚知道度量的是什么。Labels标签每个指标都可以携带额外的元信息即「标签-值」对requests_total{path/, code200} requests_total{path/, code403}花括号内的一组labels提供了上下文——说明请求是在哪个path、以什么code被处理的。标签值对永远是string类型。VictoriaMetrics 的数据模型是无模式schemaless的无需预先定义指标名或标签用户可以随时添加或更改写入的指标。实际上指标名也是一个标签只是它的名字特殊叫__name__。自 v1.111.0 起__name__键可以省略以简化书写因此下面三种写法表示的序列是完全相同的requests_total{path/, code200} {__name__requests_total, path/, code200} {requests_total, path/, code200}标签可以由 vmagent 或 Prometheus 在采集时自动附加到时间序列上。VictoriaMetrics 支持在查询 API 上强制标签过滤来模拟数据隔离但真正的数据隔离需要借助集群版的多租户特性实现。时间序列Time Series指标名 标签组合共同定义了一条time series时间序列。例如requests_total{path/, code200}与requests_total{path/, code403}因为code标签值不同是两条不同的时间序列。时间序列的唯一数量会影响数据库资源占用。可参阅 FAQ 中关于「什么是活跃时间序列」和「什么是高 churn rate序列变更率」的说明。基数Cardinality唯一时间序列的数量称为cardinality基数。拥有过多唯一时间序列被称为high cardinality高基数它可能导致 VictoriaMetrics 资源占用上升。排查与治理手段包括Cardinality Explorer基数浏览器用于定位高基数来源以及vmestimator基数估算工具。原始样本Raw Samples每条唯一时间序列可以由任意数量的(value, timestamp)数据点即raw samples原始样本组成并按timestamp排序。VictoriaMetrics 将所有value以float64存储并施加额外压缩因此可以精确存储最多 12 位十进制数字的整数值、以及最多 12 位有效十进制数字的浮点值如果数值的有效十进制数字超过 12 位则存储时低位数字可能丢失。timestamp是毫秒精度的 Unix 时间戳。下面是 Prometheus 文本暴露格式外部资料仅作背景说明下的单个原始样本示例requests_total{path/, code200} 123 4567890requests_total{path/, code200}标识该样本所属的时间序列123是样本值4567890是该样本的可选时间戳若缺失则在写入 VictoriaMetrics 时使用当前时间戳。时间序列分辨率ResolutionResolution分辨率是指时间序列中原始样本之间的最小间隔。例如---------------------------------------------------------------------- | time series | value | timestamp | | requests_total{path/health, code200} | 1 | 1676297640 | | requests_total{path/health, code200} | 2 | 1676297670 | | requests_total{path/health, code200} | 3 | 1676297700 | | requests_total{path/health, code200} | 4 | 1676297730 | ....上例中requests_total{path/health, code200}的值每30s更新一次因此其分辨率也是30s。在 Pull 模型下分辨率等于scrape_interval抓取间隔由监控系统服务端控制在 Push 模型下分辨率是样本时间戳之间的间隔由客户端指标采集器控制。请尽量保持时间序列分辨率的一致性因为部分 MetricsQL 函数会假设它是一致的。指标类型Types of MetricsVictoriaMetrics 内部并没有「指标类型」的概念——TSDB 只能看到指标名、标签、值和时间戳。指标类型这一概念是为了帮助用户理解指标是如何被测量的。常见的指标类型有 4 种。CounterCounter计数器用于统计事件发生的次数。它的值随时间只增不减一般情况下不会下降唯一的例外是counter reset计数器重置例如服务重启后归零。因此counter指标展示的是「自服务启动以来观察到的事件总数」。在编程中counter就是每当事件发生时你执行自增操作的变量。vm_http_requests_total是典型的 counter 示例。它常被用于统计请求数、错误数、日志条数、消息数等事件。与 counter 搭配最常用的 MetricsQL 函数有rate——计算指标变化的平均每秒速率。例如rate(requests_total)表示平均每秒处理多少个请求increase——计算指标在指定时间范围方括号内内的增长量。例如increase(requests_total[1h])表示过去一小时内服务的请求总数。Counter 允许出现小数。例如request_duration_seconds_sum累加所有请求的耗时而每个耗时可能是0.5秒这样的小数所以累计和也允许是小数。建议给 counter 指标名加上_total、_sum或_count后缀便于人类快速区分其与其他指标类型。GaugeGauge仪表盘/瞬时值用于测量可升可降的数值例如process_resident_memory_anon_bytes反映应用每一时刻的内存占用会随进程分配/释放内存而频繁上下波动。在编程中gauge就是随着数值变化你不断设置新值的变量。Gauge 的典型使用场景测量温度、内存占用、磁盘占用等保存某进程的状态。例如config_reloaded_successful在配置重载成功时设为1、失败时设为0保存事件发生的时间戳。例如config_last_reload_success_timestamp_seconds保存最后一次配置重载成功的时间戳。与 gauge 最常搭配的是聚合函数和 rollup滚动函数。HistogramHistogram直方图是一组带vmrange或le标签的 counter 指标。vmrange或le标签定义了某个 bucket桶的测量边界当观测值落入某个 bucket 时对应的 counter 就会自增。直方图桶通常以_bucket后缀命名。例如 VictoriaMetrics 使用vm_rows_read_per_query直方图跟踪每次查询处理的行数分布其暴露格式如下vm_rows_read_per_query_bucket{vmrange4.084e02...4.642e02} 2 vm_rows_read_per_query_bucket{vmrange5.275e02...5.995e02} 1 vm_rows_read_per_query_bucket{vmrange8.799e02...1.000e03} 1 vm_rows_read_per_query_bucket{vmrange1.468e03...1.668e03} 3 vm_rows_read_per_query_bucket{vmrange1.896e03...2.154e03} 4 vm_rows_read_per_query_sum 15582 vm_rows_read_per_query_count 11其中vm_rows_read_per_query_bucket{vmrange4.084e02...4.642e02} 2表示自上次 VictoriaMetrics 启动以来有 2 次查询的行数落在(408.4 - 464.2]区间内。带_bucket后缀的计数器可以借助histogram_quantile函数估算观测值的任意百分位数。例如下面的查询返回过去一小时方括号中的1h内每次查询读取行数的第 99 百分位估算值histogram_quantile(0.99, sum(increase(vm_rows_read_per_query_bucket[1h])) by (vmrange))该查询的工作方式increase(vm_rows_read_per_query_bucket[1h])计算过去一小时内每个实例每个 bucket 的事件数sum(...) by (vmrange)将具有相同vmrange值的各实例 bucket 求和得到每个 bucket 的总事件数histogram_quantile(0.99, ...)基于第 2 步得到的vmrangebuckets 计算第 99 百分位数。直方图类型还暴露两个额外的_sum与_count后缀计数器vm_rows_read_per_query_sum是所有观测值的总和例如自启动以来所有查询服务的行数总和vm_rows_read_per_query_count是观测事件的总数例如自启动以来观测到的查询总数。这两个计数器可以用来计算指定回看窗口内的平均测量值。例如下面查询计算最近 5 分钟方括号中的5m内每次查询读取的平均行数increase(vm_rows_read_per_query_sum[5m]) / increase(vm_rows_read_per_query_count[5m])vm_rows_read_per_query直方图在 Go 应用中可以通过 VictoriaMetrics/metrics 客户端库这样使用// 定义直方图 rowsReadPerQuery : metrics.NewHistogram(vm_rows_read_per_query) // 在处理过程中使用直方图 for _, query : range queries { rowsReadPerQuery.Update(float64(len(query.Rows))) }每次调用rowsReadPerQuery.Update时会发生countervm_rows_read_per_query_sum增加len(query.Rows)的值countervm_rows_read_per_query_count自增 1仅当观测值落在某个vmrange定义的范围内时对应的vm_rows_read_per_query_bucketcounter 才会自增。这种 counter 组合可以用于在 Grafana 中绘制热力图Heatmap以及计算分位数。注意Grafana 无法识别带vmrange标签的 bucket因此在 Grafana 中构建热力图前必须先使用prometheus_buckets函数把vmrange标签的 bucket 转换为le标签的 bucket。直方图通常用于测量延迟分布、元素尺寸如批次大小分布等。VictoriaMetrics 支持两种直方图实现Prometheus histogram——主流指标埋点客户端库普遍支持的标准实现需要用户静态地预先定义 bucket 边界VictoriaMetrics histogram——由 VictoriaMetrics/metrics 埋点库支持自动处理 bucket 边界用户无需关心。SummarySummary摘要与 histogram 类似也用于分位数计算。主要区别在于Summary 的计算发生在客户端因此指标暴露格式中已经包含了预先计算好的分位数go_gc_duration_seconds{quantile0} 0 go_gc_duration_seconds{quantile0.25} 0 go_gc_duration_seconds{quantile0.5} 0 go_gc_duration_seconds{quantile0.75} 8.0696e-05 go_gc_duration_seconds{quantile1} 0.001222168 go_gc_duration_seconds_sum 0.015077078 go_gc_duration_seconds_count 83这种方式让 Summary 使用起来更简单但也比 histogram 有显著局限无法跨多个 summary 指标聚合计算分位数。例如sum(go_gc_duration_seconds{quantile0.75})、avg(...)或max(...)都不会返回从多实例收集的go_gc_duration_seconds的正确 75 百分位无法计算预计算分位数以外的分位数无法对任意时间范围内收集的测量值计算分位数。通常 Summary 的分位数只覆盖固定时间范围如最近 5 分钟。Summary 通常用于跟踪延迟、元素尺寸如批次大小等场景的预定义百分位数。为应用埋点Instrumenting如前所述指标类型定义的是「如何被测量」VictoriaMetrics TSDB 本身并不了解指标类型它只看到指标名、标签、值和时间戳。这些指标是什么、测量什么、如何测量完全取决于发出它们的应用。官方推荐使用VictoriaMetrics/metrics 客户端库对应用进行埋点同时也兼容各类Prometheus 客户端库其埋点格式完全兼容 VictoriaMetrics 数据模型。命名官方建议遵循 Prometheus 的指标命名规范。VictoriaMetrics 没有严格限制任何指标名和标签都会被接受但遵循规范有助于保持名称有意义、描述性强且对他人清晰易读。标签每次测量可以携带任意数量的keyvalue标签。好的实践是限制标签数量否则将难以处理携带大量标签的测量数据。默认情况下VictoriaMetrics 将每条测量数据的标签数限制为40超出部分会被丢弃该限制可通过-maxLabelsPerTimeseries命令行标志调整但官方不建议调大。从源码可以验证这些默认值在 lib/timeserieslimits/timeseries_limits.go 中定义了maxLabelsPerTimeseries 40、maxLabelNameLen 256标签名最大长度默认 256 字节、maxLabelValueLen 4 * 1024标签值最大长度默认 4KiB。当写入的样本超过任一限制时IsExceeding 会将其忽略并累加vm_rows_ignored_total{reasontoo_many_labels}、vm_rows_ignored_total{reasontoo_long_label_name}、vm_rows_ignored_total{reasontoo_long_label_value}等指标便于观测被丢弃的数据量。每个标签值可以包含任意字符串但好的实践是使用简短而有意义的标签值来描述指标的属性而不是「讲故事」。例如environmentprod是合适的而log_messagelong log message with a lot of details...则不合适。默认情况下标签值限制为 4KiB可通过-maxLabelValueLen标志修改。必须严格控制唯一标签值的数量因为每个唯一的标签值都会衍生出一条新的时间序列。应尽量避免使用 session ID、query ID 这类易变的标签值以免造成资源浪费和数据库性能下降。多租户Multi-tenancyVictoriaMetrics 的集群版支持多租户用于数据隔离。而单机版可以通过在写入路径上附加标签、并在读取路径上强制标签过滤来模拟多租户。写入数据Write Data现代监控应用中常见的两种采集模型——Push 与 Pull——VictoriaMetrics 都支持。Push 模型在 Push 模型中客户端定期将采集到的指标发送给服务端。由客户端应用决定何时、向哪里发送指标。VictoriaMetrics 支持多种数据接入协议即push protocols完整列表见单机版文档。所有协议都与 VictoriaMetrics 数据模型完全兼容可安全用于生产环境。官方推荐使用 VictoriaMetrics/metrics 客户端库向 VictoriaMetrics 推送应用指标也可以使用与上述协议兼容的既有客户端例如使用 InfluxDB line protocol 的 Telegraf。编写自定义客户端或为应用埋点写指标简单到只需要发送一个 POST 请求curl -d {metric:{__name__:foo,job:node_exporter},values:[0,1,2],timestamps:[1549891472010,1549891487724,1549891503438]} -X POST http://localhost:8428/api/v1/import指标可以推送到单节点 VictoriaMetrics、集群版组件 vminsert以及 vmagent。Push 模型的优点VictoriaMetrics 侧配置更简单——无需配置被监控应用的位置也无需复杂的服务发现机制安全设置更简单——无需为 VictoriaMetrics 配置到每个被监控应用的访问通道。Push 协议的缺点被监控应用的配置复杂度增加——每个应用都需要单独配置监控系统地址还需要配置推送间隔以及推送失败时的策略向多个监控系统投递指标的非平凡配置难以判断应用是宕机了还是仅仅停止发送指标应用可能以过短的间隔推送指标导致监控系统过载。Pull 模型Pull 模型由 Prometheus 推广开来由监控系统决定何时、从哪里拉取指标。在 Pull 模型中监控系统需要知晓所有需要监控的应用指标通过 HTTP 协议定期scrape_interval从已知应用即scrape targets抓取目标抓取。VictoriaMetrics 支持像 Prometheus 一样发现 Prometheus 兼容的目标并抓取指标详见单机版抓取文档。抓取由单节点 VictoriaMetrics 和 vmagent 支持。Pull 模型的优点更易调试——VictoriaMetrics 知道所有被监控应用scrape targets查询up 0可以立即发现不可达的抓取目标抓取目标的实际信息可在http://victoriametrics:8428/targets和http://vmagent:8429/targets查看监控系统控制指标抓取频率更容易控制自身负载应用不感知监控系统的存在无需实现指标投递逻辑。Pull 模型的缺点安全设置更复杂——监控系统需要能够访问它监控的应用需要非平凡的服务发现机制。常见的数据采集架构许多部署只使用两种模型之一也有不少部署同时使用两者。最常见的做法是两者并用引入一个额外的组件——vmagent。vmagent 是一个轻量级代理核心职责是采集、过滤、relabel重新标记并向 VictoriaMetrics 投递指标它支持上文提到的所有 push 和 pull 协议。基础的监控部署可参考仓库中的 docker-compose 示例vmagent 在 prometheus-vm-single.yml 中定义了一组抓取目标并在 compose-vm-single.yml 中把采集到的数据转发给 VictoriaMetricsVictoriaMetrics 再作为 Grafana 的数据源provisioning 配置供查询使用。VictoriaMetrics 组件还支持构建更高级的拓扑。例如多个数据中心的 vmagents 可以把指标推送到中心的 VictoriaMetrics此时中心的 VictoriaMetrics 既可以是单机版也可以是集群版vmagent 还支持把同一份数据复制到多个目标用于复制与高可用场景。查询数据Query DataVictoriaMetrics 提供 HTTP API 处理读查询该 API 被 Grafana、VMUI 等各种集成使用。API 由两个主要处理器组成分别服务于瞬时查询与范围查询。瞬时查询Instant Query瞬时查询在给定的time时刻执行query表达式GET | POST /api/v1/query?query...time...step...timeout...参数说明query——MetricsQL 表达式time——可选用于计算query的毫秒级时间戳。省略时取now()当前时间。支持多种时间格式step——可选执行查询时在过去的时间区间内搜索原始样本的间隔当指定的time处缺少样本时使用。例如/api/v1/query?queryupstep1m会在(now()-1m, now()]区间内为up指标查找最后写入的原始样本首毫秒不包含。省略时默认5mtimeout——可选的查询超时时间例如timeout5s达到超时后查询会被取消。默认取-search.maxQueryDuration命令行标志的值。从源码 app/vmselect/searchutil/searchutil.go 可以看到该标志默认值为 30 秒且可被timeout参数按查询覆盖为更小的值。单机版该标志传给单节点 VictoriaMetrics集群版传给vmselect组件。瞬时查询的结果是与query表达式中过滤条件匹配的时间序列列表。每条返回的序列恰好包含一个(timestamp, value)条目其中timestamp等于time查询参数value是query在该时刻的结果。为了理解瞬时查询的工作方式先看一组数据样本foo_bar 1.00 1652169600000 # 2022-05-10T08:00:00Z foo_bar 2.00 1652169660000 # 2022-05-10T08:01:00Z foo_bar 3.00 1652169720000 # 2022-05-10T08:02:00Z foo_bar 5.00 1652169840000 # 2022-05-10T08:04:00Z, one point missed foo_bar 5.50 1652169960000 # 2022-05-10T08:06:00Z, one point missed foo_bar 5.50 1652170020000 # 2022-05-10T08:07:00Z foo_bar 4.00 1652170080000 # 2022-05-10T08:08:00Z foo_bar 3.50 1652170260000 # 2022-05-10T08:11:00Z, two points missed foo_bar 3.25 1652170320000 # 2022-05-10T08:12:00Z foo_bar 3.00 1652170380000 # 2022-05-10T08:13:00Z foo_bar 2.00 1652170440000 # 2022-05-10T08:14:00Z foo_bar 1.00 1652170500000 # 2022-05-10T08:15:00Z foo_bar 4.00 1652170560000 # 2022-05-10T08:16:00Z以上数据包含foo_bar序列的若干样本样本间间隔从 1m 到 3m 不等。若要在2022-05-10T08:03:00Z时刻获取foo_bar的值需要发起瞬时查询curl http://victoria-metrics-addr/api/v1/query?queryfoo_bartime2022-05-10T08:03:00.000Z{ status: success, data: { resultType: vector, result: [ { metric: { __name__: foo_bar }, value: [ 1652169780, // 2022-05-10T08:03:00Z 3 ] } ] } }响应中VictoriaMetrics 为foo_bar返回了一个值为3的样本-时间戳对。但如果回看原始数据2022-05-10T08:03:00Z处并没有原始样本。当请求的时间戳处没有原始样本时VictoriaMetrics 会尝试定位请求时间戳之前最近的样本。VictoriaMetrics 为缺失样本寻找替代值的时间范围默认是5m可通过step参数覆盖。瞬时查询可以返回多条时间序列但每条序列永远只有一个数据样本。瞬时查询常用于以下场景获取最后记录的数值配合 rollup 函数如count_over_time告警与预计算规则的评估在 Grafana 中绘制 Stat 或 Table 面板。范围查询Range Query范围查询在给定的[start...end]时间范围内、以给定的step执行query表达式GET | POST /api/v1/query_range?query...start...end...step...timeout...参数说明query——MetricsQL 表达式start——query求值时间范围的起始时间戳end——query求值时间范围的结束时间戳若未设置则自动取当前时间step——范围查询返回的数据点之间的间隔。query会在start、startstep、start2*step、……、startN*step时刻执行其中N是start与end之间能容纳的整步数end仅当它恰好等于startN*step时才被包含。若未设置则默认5mtimeout——可选的查询超时时间默认取-search.maxQueryDuration标志值见上文源码出处。范围查询的结果是与query匹配的时间序列列表每条序列包含在start、startstep、……、startN*step时刻执行查询得到的(timestamp, value)结果。换句话说范围查询就是在start、startstep、……、startN*step时刻独立执行的瞬时查询唯一区别是瞬时查询不返回ephemeral临时的样本详见下文若数据库在请求时刻没有样本瞬时查询会尝试用之前的样本填充而范围查询在相应时刻与 step 下没有样本时则直接返回空。例如要获取foo_bar在2022-05-10T07:59:00Z到2022-05-10T08:17:00Z范围内的值curl http://victoria-metrics-addr/api/v1/query_range?queryfoo_barstep1mstart2022-05-10T07:59:00.000Zend2022-05-10T08:17:00.000Z{ status: success, data: { resultType: matrix, result: [ { metric: { __name__: foo_bar }, values: [ [1652169600, 1], [1652169660, 2], [1652169720, 3], [1652169780, 3], [1652169840, 5], [1652169900, 5], [1652169960, 5.5], [1652170020, 5.5], [1652170080, 4], [1652170140, 4], [1652170260, 3.5], [1652170320, 3.25], [1652170380, 3], [1652170440, 2], [1652170500, 1], [1652170560, 4], [1652170620, 4] ] } ] } }响应中VictoriaMetrics 在2022-05-10T07:59:00Z到2022-05-10T08:17:00Z区间内为foo_bar返回了17个样本-时间戳对。但原始数据只有 13 个原始样本——这正是因为范围查询本质上是瞬时查询在start到end上执行了1 (start-end)/step次。上图中蓝色虚线是瞬时查询执行时刻。由于瞬时查询保留了对缺失点返回替代值的能力图中包含两类数据点real真实的和ephemeral临时的。ephemeral数据点总是重复之前最近的原始样本见图中红色箭头。产生临时数据点的行为源于 Pull 模型的特定性指标按固定间隔抓取监控系统过载时可能跳过某次抓取网络问题可能导致抓取失败。因此范围查询假设如果缺少原始样本很可能是某次抓取被跳过于是用之前的样本填充。当step小于样本实际间隔时同理——事实上若将step1s用于同一请求响应中会有约 1 千个数据点其中绝大多数是ephemeral的。有时用于定位数据点的回看窗口不够大图表中会出现缺口。对于范围查询回看窗口并不等于step参数而是按请求时间范围内最近 20 个原始样本的间隔中位数自动计算。这样VictoriaMetrics 在自动调整回看窗口填补缺口的同时还能检测到过期序列。源码中-search.maxLookback标志的注释印证了这一点默认值 0 表示未显式设置时从时间序列数据点间隔动态检测见 app/vmselect/prometheus/prometheus.go。范围查询主要用于在指定时间范围内绘制时序数据典型场景跟踪某指标在给定时间区间内的状态关联同一时间区间内多个指标的变化观察指标变化的趋势与动态。如果需要从 VictoriaMetrics 导出原始样本请参阅单机版文档中的导出 API。查询延迟与数据可见性Query Latency默认情况下VictoriaMetrics不会立即返回最近写入的样本而是检索-search.latencyOffset命令行标志指定时间之前写入的最新结果。该标志默认偏移 30 秒对query和query_range均生效因此可能给人「数据写入 VM 有 30 秒延迟」的印象。该标志用于避免因「最后一个抓取间隔内只有部分值被抓取」而产生不一致的结果。当-search.latencyOffset设为 0 时可能出现下图所示的问题由于最新抓取到的数据不完整查询结果中的最后几个点会出现抖动或空洞。设置该标志后在整个-search.latencyOffset时长内VM 都会返回-search.latencyOffset之前收集到的最后一个指标值从而保证最近时间窗口内查询结果的稳定一致。-search.latencyOffset可以通过latency_offset查询参数按查询覆盖。从源码 app/vmselect/prometheus/prometheus.go 可以看到该标志的完整定义同时还可看到相关的-search.maxStepForPointsAdjustment默认 1 分钟控制/api/v1/query_range对接近当前时间且可能包含不完整数据的点做调整的最大 step。另外需要注意VictoriaMetrics 会把最近几秒内摄入的样本缓存在内存中再周期性刷盘。这种缓冲提升了数据摄入性能但缓冲中的样本即使-search.latencyOffset或latency_offset设为 0 也不会出现在查询结果中。可以给单节点 VictoriaMetrics或集群版的vmstorage发送 GET 请求到/internal/force_flushHTTP 处理器强制将缓冲样本刷盘使其可见。从源码 app/vmstorage/main.go 可以看到该处理器的实现它支持通过-forceFlushAuthKey设置访问鉴权app/vmstorage/main.go。该处理器仅用于调试和测试请勿在生产环境调用否则可能显著降低数据摄入性能并增加资源占用。MetricsQLVictoriaMetrics 提供专门的查询语言用于执行读查询——MetricsQL。它是一种类 PromQL 的查询语言内置针对时间序列数据的功能强大的函数集。MetricsQL 与 PromQL 向后兼容因此共享了大部分查询概念。过滤在前面的瞬时查询与范围查询章节中我们已经用 MetricsQL 查询过foo_bar指标只需直接写指标名foo_bar一个指标名可能对应多条标签集不同的时间序列例如requests_total{path/, code200} requests_total{path/, code403}要只选择具有特定标签值的时间序列在花括号中指定匹配过滤器requests_total{code200}上面的查询返回所有名为requests_total且带code200标签的时间序列。使用运算符匹配标签值负向匹配用!过滤器还支持正则正向匹配~和正则负向匹配!~requests_total{code~2.*}过滤器也可以组合requests_total{code~200, path/home}上面的查询返回所有名为requests_total、同时带有code200和path/home标签的时间序列。按指标名过滤有时需要返回多个指标名的所有时间序列。如前文数据模型所述指标名只是一个特殊的标签——__name__。因此可以对其应用正则{__name__~requests_(error|success)_total}该查询返回requests_error_total与requests_success_total两个指标的所有序列。多「or」过滤MetricsQL 支持选择至少匹配多个「or」过滤器之一的时间序列此类过滤器在花括号内用or分隔。例如下面的查询选择带{jobapp1,envprod}或{jobapp2,envdev}标签的时间序列{jobapp1,envprod or jobapp2,envdev}or组的数量任意每个or组内用,分隔的标签过滤器数量也任意组内过滤器以and语义应用同时匹配组内所有过滤器。这一功能允许把选中的序列直接传给 rollup 函数如rate()而无需使用子查询rate({jobapp1,envprod or jobapp2,envdev}[5m])如果需要对同一个标签选择匹配多个过滤器的序列从性能角度考虑用正则过滤器{label~value1|...|valueN}优于{labelvalue1 or ... or labelvalueN}。算术运算MetricsQL 支持所有基本算术运算加法、减法-、乘法*、除法/、取模%、幂^这使得可以跨多个指标进行计算。例如下面查询计算错误请求的百分比(requests_error_total / (requests_error_total requests_success_total)) * 100组合多个序列用算术运算组合多个时间序列需要理解匹配规则否则查询可能报错或产生错误结果。匹配规则的基础很简单MetricsQL 引擎会剥离算术运算两侧所有时间序列的指标名但不触碰标签对左侧每条时间序列引擎会在右侧寻找具有相同标签集的时间序列对每个数据点应用运算并返回具有相同标签集的结果序列如果没有匹配则从结果中丢弃该序列匹配规则可以通过ignoring、on、group_left、group_right修饰符增强向量匹配规则。比较运算MetricsQL 支持以下比较运算符等于、不等于!、大于、大于等于、小于、小于等于这些运算符可以像算术运算符一样应用于任意 MetricsQL 表达式比较运算的结果是只包含匹配数据点的时间序列。例如下面查询只返回内存占用超过100MB的进程对应序列process_resident_memory_bytes 100*1024*1024聚合与分组函数MetricsQL 支持对时间序列进行聚合和分组先按给定标签集对时间序列分组再对每组单独应用聚合函数。例如下面查询返回每个job的内存占用总和sum(process_resident_memory_bytes) by (job)完整的聚合函数列表参见 MetricsQL 文档。计算速率ratecounter 最常用的函数之一是rate它逐条计算每个匹配时间序列的平均每秒增长率。例如下面查询展示每个被监控的node_exporter实例暴露的node_network_receive_bytes_total指标的平均每秒数据接收速度rate(node_network_receive_bytes_total)默认情况下VictoriaMetrics 在step参数无论传给瞬时查询还是范围查询指定的回看窗口内、基于原始样本计算rate。也可以在方括号内显式指定计算rate的时间区间rate(node_network_receive_bytes_total[5m])此时 VictoriaMetrics 使用指定的回看窗口5m5 分钟计算平均每秒增长率。更大的回看窗口通常带来更平滑的曲线。rate会剥离内部时间序列的指标名但保留所有标签。如需保留指标名可在rate(..)后加keep_metric_names修饰符rate(node_network_receive_bytes_total) keep_metric_namesrate()只能应用于 counter对 gauge 应用rate()的结果是未定义的。可视化时间序列VictoriaMetrics 内置了查询与可视化指标的图形化界面——VMUI。打开http://victoriametrics:8428/vmui页面输入查询即可查看结果VictoriaMetrics 支持 Prometheus HTTP API因此也可以像查询 Prometheus 一样用 Grafana 以相同方式查询它。修改数据Modify DataVictoriaMetrics 将时间序列数据存储在类 MergeTreeLSM 树的数据结构中。这种结构对写密集的数据库非常高效但对数据更新施加了一些限制修改已写入的时间序列需要重写其所在的整个数据块。由于这一限制VictoriaMetrics 不支持直接修改数据。删除Deletion删除时间序列的方法参见单机版文档的「如何删除时间序列」章节。RelabelingRelabeling 是在时间序列写入数据库之前对其进行修改的强大机制可同时应用于 push 与 pull 两种模型。更多细节参见relabeling 文档。去重DeduplicationVictoriaMetrics 支持数据去重详见单机版文档的去重章节。降采样DownsamplingVictoriaMetrics 支持数据降采样详见单机版文档的降采样章节。小结从核心概念到实战落地本文围绕 VictoriaMetrics 的核心概念建立了一条完整的知识链路数据模型是根基——指标名 标签唯一确定一条时间序列唯一序列数量即基数cardinality它是影响资源占用与性能的最关键变量四种指标类型Counter/Gauge/Histogram/Summary决定「如何测量」而 TSDB 本身并不感知类型采集模式决定架构——Push 与 Pull 各有优劣生产中常通过 vmagent 将两者结合构建「采集 → 过滤/relabel → 转发 → 存储 → 查询可视化」的标准链路查询 API 与 MetricsQL是日常使用的核心——瞬时查询定位单点、范围查询绘制曲线理解ephemeral数据点与回看窗口机制有助于正确解读图形-search.latencyOffset与/internal/force_flush解释了「30 秒数据延迟」的真相修改数据受限于 LSM 存储模型——不支持直接更新而是通过删除、relabeling、去重与降采样等机制管理数据生命周期。阅读完本文后你可以直接结合仓库中的 keyConcepts.md、MetricsQL.md 与 Single-server-VictoriaMetrics.md 继续深入也可以对照 lib/timeserieslimits/timeseries_limits.go 与 app/vmselect/prometheus/prometheus.go 等源码从实现层面验证本文所述的各种行为与默认值。【免费下载链接】VictoriaMetricsVictoriaMetrics: fast, cost-effective monitoring solution and time series database项目地址: https://gitcode.com/GitHub_Trending/vi/VictoriaMetrics创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表