VictoriaMetrics vmanomaly Writer 组件详解:VmWriter 配置、指标格式化与多租户写入实践
【免费下载链接】VictoriaMetricsVictoriaMetrics: fast, cost-effective monitoring solution and time series database项目地址: https://gitcode.com/GitHub_Trending/vi/VictoriaMetrics
VictoriaMetrics Anomaly Detection(vmanomaly)通过 Reader、Models、Scheduler、Writer 等组件构成完整的异常检测闭环,其中 Writer 组件负责将模型产出的异常分数(anomaly score)等结果序列写回 VictoriaMetrics,是整个流水线的"出口"。本文以仓库文档 docs/anomaly-detection/components/writer.md 为主体,结合组件总览、模型输出定义、自监控指标与部署示例,系统讲解 VmWriter 的全部配置参数、metric_format指标命名规则、多租户写入行为与 mTLS 保护,帮助你在生产环境中正确配置并验证异常检测结果的落库链路。
Writer 在 vmanomaly 组件体系中的定位
vmanomaly服务在启动时会解析配置文件,其中writer是必需的配置段之一(详见 docs/anomaly-detection/components/README.md)。整个数据流可以概括为:
- Reader从 VictoriaMetrics 的
/query_range等端点按调度器(Scheduler)拉取历史与增量数据; - Models在 fit / infer 阶段对每条时间序列计算异常分数与预测区间;
- Writer将模型输出序列(
anomaly_score、yhat、yhat_lower、yhat_upper、y等)写回 VictoriaMetrics,供 Grafana 仪表盘、vmalert 告警规则等下游消费。
Writer 的核心设计目标是平滑地对接 VictoriaMetrics 生态:它在写入结果时保留输入数据自带的标签集(labelset),并可选地附加额外的标签(如查询别名、配置来源等),使异常检测结果能够与原始指标天然关联、便于按维度聚合与告警。官方文档同时说明,未来版本会引入更多数据导出方式,但目前vmanomaly主要采用 VmWriter 完成数据导出。
VM writer 概述
VmWriter是vmanomaly内置的、面向 VictoriaMetrics / Prometheus 兼容写入协议的结果导出器。它默认使用 VictoriaMetrics 的导入接口(/api/v1/import,该参数自 v1.19.2 起已被弃用,默认路径自动生效),将模型输出以 Prometheus 文本协议(NDJSON 序列化)批量提交,并具备连接重试、批量拆分、跨周期前缀缓存等生产级能力。
组件类名支持短别名引用:自 v1.13.0 起,
writer.vm.VmWriter可以简写为vm;在更早的版本中必须书写完整类名。如果配置中省略class字段,VmWriter是默认选项。
配置参数总览
下表汇总了VmWriter的全部配置参数(以 docs/anomaly-detection/components/writer.md 为准):
| 参数 | 示例 | 说明 |
|---|---|---|
class | writer.vm.VmWriter或vm | 启用写入 VictoriaMetrics / Prometheus 所需的类名。自 v1.13.0 起支持短别名vm;未指定时默认使用VmWriter |
datasource_url | http://localhost:8481/ | 数据源(写入目标)URL 地址 |
tenant_id | 0:0、multitenant | 仅适用于 VictoriaMetrics Cluster 版本。租户由accountID或accountID:projectID标识;自 v1.16.2 起支持multitenant端点,用于跨多个租户写入(详见下方多租户支持一节) |
metric_format | __name__: "vmanomaly_$VAR" | 输出指标的命名与标签模板。必须包含__name__键,且其值必须包含$VAR占位符以区分不同输出序列。支持占位符:$VAR(模型提供的变量)与$QUERY_KEY(查询别名);其余键为用户自定义标签(详见指标格式化一节) |
import_json_path | /api/v1/import | 可选,用于覆盖默认导入路径。自 v1.19.2 起已弃用 |
health_path | /health | 可选,探测数据源可用性的绝对或相对 URL 路径,用于覆盖默认的/health |
user | USERNAME | BasicAuth 用户名 |
password | PASSWORD | BasicAuth 密码 |
timeout | 5s | 请求超时时间,以字符串形式传入 |
verify_tls | false | 是否校验 TLS 证书。False时不校验;True时使用系统 CA 存储校验;传入 CA 捆绑文件路径(如ca.crt)时使用该 CA 捆绑校验 |
tls_cert_file | path/to/cert.crt | 客户端证书文件路径(如client.crt),自 v1.16.3 起可用,用于 mTLS |
tls_key_file | path/to/key.crt | 客户端证书私钥文件路径(如client.key),自 v1.16.3 起可用,用于 mTLS |
bearer_token | token | 以标准格式通过请求头传递的令牌:Authorization: bearer {token} |
bearer_token_file | path_to_file | 存放令牌的文件路径,同样以Authorization: bearer {token}请求头传递,自 v1.15.9 起可用 |
connection_retry_attempts | 1 | 连接失败时的重试次数,自 v1.29.2 起可用,默认1 |
batch_max_series | 1000 | 单次 VictoriaMetrics 导入请求中输出时间序列的最大数量,自 v1.30.3 起可用;更大的推理输出会被拆分为多个请求,默认1000 |
batch_max_bytes | 4194304 | 单次导入请求序列化后的最大字节数(软上限),自 v1.30.3 起可用;单条不可分割的 NDJSON 时间序列可能超过此软界,默认 4 MiB(4194304) |
metric_prefix_cache_max_entries | 10000 | 跨写入周期保留的预构建指标-标签前缀缓存条目数上限,自 v1.30.3 起可用;设为0可禁用跨周期前缀缓存,默认10000 |
完整配置示例
以下为官方给出的VmWriter配置示例,可直接放入vmanomaly配置文件的writer段:
writer: class: "vm" # or "writer.vm.VmWriter" until v1.13.0 datasource_url: "http://localhost:8428/" tenant_id: "0:0" metric_format: __name__: "vmanomaly_$VAR" for: "$QUERY_KEY" run: "test_metric_format" config: "io_vm_single.yaml" import_json_path: "/api/v1/import" health_path: "health" user: "foo" password: "bar" connection_retry_attempts: 2 # if not specified, it will be 1 by default batch_max_series: 1000 # maximum series per VictoriaMetrics import request batch_max_bytes: 4194304 # soft maximum serialized request size (4 MiB) metric_prefix_cache_max_entries: 10000 # set to 0 to disable cross-cycle caching其中datasource_url指向接收写入的 VictoriaMetrics 单机实例(如http://victoriametrics:8428/);在 Docker Compose 部署中,通常直接使用服务名作为主机名(见 deployment/docker/vmanomaly/vmanomaly-integration/compose.yml 中的 vmanomaly 服务)。
提示:
batch_max_series与batch_max_bytes用于控制写入请求的粒度。当模型输出时间序列规模很大时,vmanomaly会按这两个边界自动拆分请求,避免单个导入请求过大导致写入端内存压力或超时;metric_prefix_cache_max_entries则通过跨周期缓存预构建的指标前缀来降低重复序列化的开销,在高基数场景下可根据内存预算调优。
Metrics formatting 指标格式化
metric_format是 Writer 配置中最核心的业务字段,它决定了模型输出序列在写回 VictoriaMetrics 时使用什么指标名与标签。配置中必须设置两个必填参数:__name__和for。
__name__: PREFIX1_$VAR for: PREFIX2_$QUERY_KEY其作用机制如下:
__name__(指标名模板):$VAR占位符会被替换为模型输出的变量名,例如PREFIX1_anomaly_score、PREFIX1_yhat_lower、PREFIX1_yhat、PREFIX1_yhat_upper、PREFIX1_y等。这些变量名的完整定义见 docs/anomaly-detection/components/models.md 的 "vmanomaly output" 小节,其中anomaly_score是主指标(0.0 ~ 1.0 表示正常,大于 1.0 通常判定为异常,告警阈值可另行调整);yhat为预测期望值,yhat_lower/yhat_upper为预测下/上边界,y为查询返回的原始值。不同模型还可能提供额外输出(如 Prophet 的trend、seasonality,Seasonal Trend Decomposition 的resid等),这些变量同样可通过$VAR映射。for(查询标签模板):$QUERY_KEY占位符会被替换为查询别名,即 reader 配置queries段中定义的 key。例如 reader 中定义了queries: {query_name_1: ..., query_name_2: ...},则输出会带上标签for="PREFIX2_query_name_1"、for="PREFIX2_query_name_2",从而把异常分数与具体的输入查询关联起来。
除了以上两个必填模板,你还可以指定任意自定义标签键值对:
custom_label_1: label_name_1 custom_label_2: label_name_2一个完整的metric_format示例及其效果:
metric_format: __name__: "PREFIX1_$VAR" for: "PREFIX2_$QUERY_KEY" custom_label_1: label_name_1 custom_label_2: label_name_2假设输入数据自带标签cpu=1, device=eth0, instance=node-exporter:9100(这些标签来自 docs/anomaly-detection/components/reader.md 中queries返回的指标),则最终写回的指标形如:
{__name__="PREFIX1_anomaly_score", for="PREFIX2_query_name_1", custom_label_1="label_name_1", custom_label_2="label_name_2", cpu=1, device="eth0", instance="node-exporter:9100"} {__name__="PREFIX1_yhat_lower", for="PREFIX2_query_name_1", custom_label_1="label_name_1", custom_label_2="label_name_2", cpu=1, device="eth0", instance="node-exporter:9100"} {__name__="PREFIX1_anomaly_score", for="PREFIX2_query_name_2", custom_label_1="label_name_1", custom_label_2="label_name_2", cpu=1, device="eth0", instance="node-exporter:9100"} {__name__="PREFIX1_yhat_lower", for="PREFIX2_query_name_2", custom_label_1="label_name_1", custom_label_2="label_name_2", cpu=1, device="eth0", instance="node-exporter:9100"}可以看到:输入指标自带的标签(cpu、device、instance)被完整保留,同时叠加了模板标签(__name__、for)与自定义标签。这一特性使得 Grafana 仪表盘与 vmalert 告警规则可以直接沿用原始指标的维度体系对异常分数做切片分析。官方建议为metric_format添加for标签,以获得更平滑的异常分数仪表盘可视化体验(见 docs/anomaly-detection/QuickStart.md 的配置建议)。
多租户支持
多租户写入仅适用于VictoriaMetrics Cluster 版本。租户由accountID或accountID:projectID标识;自 v1.15.9 起支持multitenant端点,可在单个 Writer 配置下将数据写入多个租户(详细的多租户概念可参考仓库中 docs/victoriametrics/Cluster-VictoriaMetrics.md 的多租户章节)。
根据writer.tenant_id取值与结果标签集中是否携带多租户标签,实际行为分为四种情况:
writer.tenant_id != 'multitenant'(如"0:0")且reader.tenant_id != 'multitenant'(可为不同但合法的值,如"0:1")vm_account_id标签在 Reader 侧不会被创建、不会持久化到 Writer,也不会出现在输出中;- 结果:数据正常写入,无日志、无报错。
writer.tenant_id = 'multitenant'且标签集中存在vm_project_id- 这通常发生在
reader.tenant_id也设为multitenant时——Reader 查询返回的结果中会携带vm_account_id标签; - 结果:一切按预期工作,数据正常写入,无日志、无报错。
- 这通常发生在
writer.tenant_id = 'multitenant'但标签集中缺少vm_account_id(例如 Reader 侧做了聚合、或查询中缺少keep_metric_names)- 结果:数据仍会写入默认租户
"0:0",但会抛出如下警告:
The label `vm_account_id` was not found in the label set of {query_result.key}, but tenant_id='multitenant' is set in writer. The data will be written to the default tenant 0:0. Ensure that the query retains the necessary multi-tenant labels, or adjust the aggregation settings to preserve `vm_account_id` key in the label set.- 结果:数据仍会写入默认租户
writer.tenant_id != 'multitenant'(如"0:0")但标签集中存在vm_account_id- 结果:写入被允许,但会抛出如下警告:
The label set for the metric {query_result.key} contains multi-tenancy labels, but the write endpoint is configured for single-tenant mode (tenant_id != 'multitenant'). Either adjust the query in the reader to avoid multi-tenancy labels or ensure that reserved key `vm_account_id` is not explicitly set for single-tenant environments.
简而言之:vm_account_id/vm_project_id是保留标签,其语义必须与writer.tenant_id的配置模式保持一致。在multitenant模式下,务必让 Reader 的查询保留多租户路由标签(避免聚合吞掉它们);在单租户模式下,则不要显式设置vm_account_id。这一行为在 docs/anomaly-detection/components/monitoring.md 的 Reader / Writer 日志章节中也有对应描述——The label vm_account_id was not found警告即意味着multitenantWriter 将回退到租户0:0。
mTLS 保护
自 v1.16.3 起,vmanomaly的 VmWriter 等组件支持mTLS(双向 TLS),用于与启用了 mTLS 的 VictoriaMetrics Enterprise 实例建立安全通信,实现客户端与服务端之间的双向证书身份校验,防止未授权访问。
mTLS 相关的配置参数为:
verify_tls:若传入字符串,其作用等价于 VictoriaMetrics 的-mtlsCAFile命令行参数,指定 CA 捆绑文件;设为True则使用系统默认证书存储;tls_cert_file:客户端证书路径,等价于 VictoriaMetrics 的-tlsCertFile;tls_key_file:客户端证书私钥路径,类似-tlsKeyFile。
配置示例(完整参数解析见 docs/anomaly-detection/components/reader.md 的 mTLS protection 一节,该节对 Reader / Writer / Monitoring 各组件给出了一致的配置原则):
writer: class: "vm" datasource_url: "https://your-victoriametrics-instance-with-mtls" tenant_id: "0:0" verify_tls: "path/to/ca.crt" # path to CA bundle for TLS verification tls_cert_file: "path/to/client.crt" # path to the client certificate tls_key_file: "path/to/client.key" # path to the client certificate key需要注意的是,verify_tls的三种取值语义分别对应:False(不校验证书)、True(使用系统 CA 存储校验)、CA 文件路径(使用指定的 CA 捆绑校验)。
写入行为的自监控指标
VmWriter 会暴露一组健康与行为指标(详细定义见 docs/anomaly-detection/components/monitoring.md 的 Writer behaviour metrics 小节),用于观测写入链路的状态。自 v1.17.0 起,这些指标统一增加了scheduler_alias与preset标签以适配多调度器场景,且请求耗时类指标由Summary改为Histogram以支持分位数计算:
| 指标 | 类型 | 说明 |
|---|---|---|
vmanomaly_writer_request_duration_seconds | Histogram | 向 VictoriaMetricsurl发起写请求的总耗时(秒),按query_key、scheduler_alias、preset标注;自 v1.30.1 起,成功的与已处理失败的尝试(含连接重试)均会被观测 |
vmanomaly_writer_responses(旧名vmanomaly_writer_response_count) | Counter | 按 HTTP 状态码code统计的响应计数;code也取值connection_error、timeout、ssl_error、io_error |
vmanomaly_writer_sent_bytes | Counter | 向 VictoriaMetrics 发送的总字节数 |
vmanomaly_writer_request_serialize_seconds | Histogram | 数据序列化耗时(秒) |
vmanomaly_writer_datapoints_sent | Counter | 发送的总数据点数量 |
vmanomaly_writer_timeseries_sent | Counter | 发送的总时间序列数量 |
这些指标可通过monitoring.pull(暴露/metrics端点)或monitoring.push(周期性推送到指定 URL)两种方式采集。从源码结构看,写入请求的序列化耗时与预处理的序列数量在请求失败前就已记录,而sent_bytes与datapoints仅在成功响应后累加——这意味着监控指标能如实反映"成功写入"与"尝试写入"的差别,便于区分因重试导致的指标波动。对应地,Writer 日志中Cannot write N points for QUERY前缀的报错会附带 SSL / 连接 / 超时 / I/O 原因,Connection error while writing ... reinitializing session and retrying则代表一次可重试的连接失败。
实战:在 vmanomaly 中配置并验证 Writer
将上述知识点落到部署层面,完整的vmanomaly配置(含 Reader、Models、Scheduler 与 Writer)可以参考 docs/anomaly-detection/components/README.md 与 docs/anomaly-detection/QuickStart.md 中的示例。一个最小的 Writer 段只需指定写入目标与指标模板:
writer: class: 'vm' # use VictoriaMetrics as a data destination datasource_url: "http://victoriametrics:8428/" # [YOUR_DATASOURCE_URL] # optional tenant ID # tenant_id: "0:0" metric_format: __name__: $VAR for: $QUERY_KEY部署与验证步骤建议如下:
- 用
--dryRun校验配置:vmanomaly在启动时会做配置校验(自 v1.7.2 起)。官方推荐在正式启动前使用--dryRun标志(该参数仅做解析、合并与 schema 校验,无需 license),可尽早发现writer段中如metric_format缺__name__、datasource_url笔误等问题。命令行参数细节见 docs/anomaly-detection/QuickStart.md 的 command-line arguments 小节。 - Docker Compose 部署:仓库提供了一整套 vmanomaly + vmagent + VictoriaMetrics + vmalert + Grafana 的集成示例(见 deployment/docker/vmanomaly/vmanomaly-integration/compose.yml),其中 vmanomaly 服务将配置文件挂载为
/config.yaml,命令形如["/config.yaml", "--licenseFile=/license"],并将 8490 端口暴露给 UI / API。 - 查询验证写入结果:启动后,可在目标 VictoriaMetrics 上用 MetricsQL 查询由
metric_format生成的序列(如vmanomaly_anomaly_score),结合for、自定义标签与原始标签做过滤,确认异常分数已正确落库;同时可通过vmanomaly_writer_datapoints_sent等自监控指标确认写入计数持续增长。 - (可选)开启热加载:配合
--watch参数与-configCheckInterval(默认 30s 的内容轮询),可在不重启服务的情况下调整writer等配置段,vmanomaly_config_reloads_total指标会以status="success"或status="failure"记录每次重载结果。
小结
Writer(VmWriter)是vmanomaly异常检测流水线的收尾环节,它决定了异常检测结果以什么名字、什么标签、以怎样的传输策略进入 VictoriaMetrics。掌握metric_format的$VAR/$QUERY_KEY占位符与自定义标签用法,理解tenant_id多租户语义与 mTLS 证书配置,并善用batch_max_series、batch_max_bytes、connection_retry_attempts等传输调优参数,以及vmanomaly_writer_*自监控指标,就能构建一条可靠、可观测、可扩展的异常检测结果落库链路。
【免费下载链接】VictoriaMetricsVictoriaMetrics: fast, cost-effective monitoring solution and time series database项目地址: https://gitcode.com/GitHub_Trending/vi/VictoriaMetrics
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考