VictoriaMetrics 时序异常检测与告警实战:vmanomaly × vmalert 集成部署指南
【免费下载链接】VictoriaMetricsVictoriaMetrics: fast, cost-effective monitoring solution and time series database项目地址: https://gitcode.com/GitHub_Trending/vi/VictoriaMetrics
导读
本文是 VictoriaMetrics 生态中vmanomaly(VictoriaMetrics Anomaly Detection,时序数据异常检测服务)与vmalert(VictoriaMetrics 告警引擎)联合使用的完整实战教程。文章基于仓库中 docs/anomaly-detection/guides/guide-vmanomaly-vmalert/README.md 编写,配套的完整可运行配置存放于 deployment/docker/vmanomaly/vmanomaly-integration/。读完本文,你将掌握:如何用 Node Exporter 采集 CPU 数据写入 VictoriaMetrics,如何配置 vmanomaly 的机器学习模型自动计算 anomaly score(异常分数),如何用 vmalert 基于异常分数设置告警规则,以及如何用 Docker Compose 一键拉起整套可观测性流水线,并在 Grafana 中可视化与验证结果。
1. 前置条件
本教程需要以下组件与环境:
- vmanomaly:属于 VictoriaMetrics 企业版套件的一部分,使用前需要 license key。可通过 VictoriaMetrics 官方渠道申请试用 license 用于本教程或企业评估。
- VictoriaMetrics 组件(本教程对应版本):
- VictoriaMetrics Single-Node(v1.151.0)
- vmalert(v1.151.0)
- vmagent(v1.151.0)
- Grafana(v12.2.0):可视化工具。
- Docker 与 Docker Compose:用于编排全部服务。
- Node Exporter(v1.9.1)与Alertmanager(v0.28.1):分别用于暴露主机指标和处理来自 vmalert 的告警。
补充说明:从 vmanomaly v1.13.0 起,官方还提供了
node-exporter可观测性预设(preset),可参考 docs/anomaly-detection/Presets.md 中的 node-exporter 指南。
2. 什么是 vmanomaly?
vmanomaly(VictoriaMetrics Anomaly Detection)是一个持续扫描 VictoriaMetrics 中时序数据、并利用用户可配置的机器学习模型实时检测数据模式中异常变化的服务。所有服务参数均通过一个配置文件定义。其核心工作流程为:
- 周期性查询用户指定的指标;
- 对这些指标计算anomaly score(异常分数);
- 将计算出的anomaly score写回 VictoriaMetrics。
关于配置能力的演进(均反映在官方 changelog 中,配置示例见下文第 5 节):
- 从 v1.10.0 起,单个 vmanomaly 配置文件可以支持多种模型类型,无需再为不同模型运行多个进程实例(见 models 配置节)。
- 从 v1.11.0 起,单个配置文件中的每种模型还可以挂接到一个或多个 scheduler(调度器),实现"不同模型 × 不同调度器"的组合(见 models 与 scheduler 配置节)。
什么是 anomaly score?
Anomaly score是一个计算得到的非负数值(区间 [0, +inf))。它综合衡量数据点与预测分布的拟合程度,并考虑周期模式、趋势、季节性等因素。该数值的设计语义是:
- 当模型认为数据点遵循常规模式时,分数介于 0 与 1 之间;
- 当数据点表现异常时,分数超过 1。
随后,用户即可借助 vmalert 基于 anomaly score 启用告警规则。
3. 什么是 vmalert?
vmalert 是 VictoriaMetrics 的告警工具。它会针对配置的-datasource.url执行一组给定的告警规则或记录规则。
Alerting rules(告警规则)允许用户定义触发通知的条件,条件以查询表达式形式通过 MetricsQL 查询语言书写。例如在本教程场景中,表达式anomaly_score > 1.0表示:当计算出的异常分数超过阈值1.0时通知用户。
4. vmanomaly 与 vmalert 如何协同工作?
与经典告警规则相比,异常检测更加"自动化"且"数据感知"。经典告警要求用户预先思考并定义关键条件(即"必须提前知道要找什么");而异常检测则是寻找与历史行为的任何偏差,能捕捉到用户事先并未预期到的异常。
因此,最实用的做法就是:将 vmanomaly 生成的 anomaly score 作为告警规则的输入,并设定一个阈值。vmanomaly 负责"发现异常",vmalert 负责"当异常分数超阈值时发出告警"。
本教程将带你完成:
- 编写 docker-compose 文件,编排全部所需服务(VictoriaMetrics Single-Node、vmalert、vmagent、Grafana、Node Exporter、vmanomaly、Alertmanager);
- 逐一解读 vmanomaly 与 vmalert 的配置文件;
- 运行一套自带 Node Exporter 抓取数据的 VictoriaMetrics 数据库;
- 在 Grafana 中查看用于分析的数据;
- 查看 vmanomaly 的输出结果;
- 查看 vmalert 触发的告警。
5. 待分析的数据:Node Exporter 的 CPU 指标
本教程使用Node Exporter采集的 CPU 使用数据写入 VictoriaMetrics 数据库。Node Exporter 指标页面上的一部分输出形如:
# HELP node_cpu_seconds_total Seconds the CPUs spent in each mode. # TYPE node_cpu_seconds_total counter node_cpu_seconds_total{cpu="0",mode="idle"} 94965.14 node_cpu_seconds_total{cpu="0",mode="iowait"} 51.25 node_cpu_seconds_total{cpu="0",mode="irq"} 0 node_cpu_seconds_total{cpu="0",mode="nice"} 0 node_cpu_seconds_total{cpu="0",mode="softirq"} 1682.18 node_cpu_seconds_total{cpu="0",mode="steal"} 0 node_cpu_seconds_total{cpu="0",mode="system"} 995.37 node_cpu_seconds_total{cpu="0",mode="user"} 12378.05 node_cpu_seconds_total{cpu="1",mode="idle"} 94386.53 node_cpu_seconds_total{cpu="1",mode="iowait"} 51.22 ...在这个上下文中,node_cpu_seconds_total提供了每个 CPU 核心在各种运行模式下所耗时间的完整分解,包括user、system、iowait、idle、irq&softirq、guest、steal等模式。这八种模式互斥,各自提供对 CPU 活动的不同洞察。例如:iowait占比偏高通常提示磁盘或网络瓶颈;user或system居高则说明 CPU 利用率显著。
node_cpu_seconds_total属于counter(计数器)类型指标(参见 keyConcepts)。要分析每个 CPU 核心在各模式下花费的时长,需要借助 MetricsQL 的 rate 函数 计算每秒变化率:rate(node_cpu_seconds_total)。为了按 mode 得到更平滑、更聚合的结果,再叠加sum聚合,最终查询为:
sum(rate(node_cpu_seconds_total[5m])) by (mode, instance, job)该查询会产出8 条时序(每个 CPU 模式一条)。由于by聚合的作用,序列数量不受 CPU 核心数影响。这些序列将作为 vmanomaly 的输入——服务会对每条时序独立拟合一个所配置模型类型的实例。
6. vmanomaly 配置详解
vmanomaly 的配置文件包含4 个必需 section与1 个可选 section:
scheduler:决定模型推理与训练的频率,以及模型训练所用的时间范围。从 v1.11.0 起,单个配置中支持为每种模型挂接多个独立 scheduler。models:定义用于异常检测的模型及其专属参数。从 v1.10.0 起,单个配置中支持多种模型配置。reader:定义数据读取方式与数据源位置。writer:指定生成输出的写入目标与方式。monitoring(可选):描述如何监控并暴露 vmanomaly 自身的健康检查指标。
各 section 关键参数
schedulers(此处使用 PeriodicScheduler)
infer_every:训练好的模型对新数据执行推理的频率,决定新 anomaly score 数据点的生成间隔。格式示例:30s、4m、2h、1d(时间单位:s秒、m分钟、h小时、d天)。本质上是在问:"每隔固定间隔(如每 1 分钟),最新的数据点基于历史数据来看是否异常?"fit_every:模型重新训练的频率。注意:在线模型(online models)会从每次推理批次中学习,因此可设置一个很大的值(如1000d)使拟合仅做初始 bootstrap。若希望模型跟随行为演变,应配置模型的遗忘/反应机制,或选择有限拟合节奏以重置累积状态。格式同infer_every。fit_window:模型训练所用的数据区间。区间越长,越能捕获广泛的历史行为、季节性模式检测效果越好,但会降低模型对指标永久性变化的响应速度,并增加资源消耗。建议至少覆盖两个完整的季节周期。示例:3h表示使用三小时数据。
models
class:指定使用的模型。可选自定义模型或官方 内置模型(内置模型清单见该文档)。对于具有日历行为的运维指标,推荐使用在线Temporal Envelope(时间包络)模型。- 模型专属参数直接写在模型别名下方,见下方示例。
reader
datasource_url:数据源 URL,通常是提供/api/v1/query_range的 HTTP 端点。queries:用于异常检测的 MetricsQL(PromQL 的超集)表达式。多个查询可格式化为<QUERY_ALIAS>: "QUERY",其中 QUERY_ALIAS 会作为生成指标与异常分数中的标签。sampling_period:采样周期,即读取数据的时间步长(示例中为60s)。
writer
datasource_url:输出数据的目标端点,通常是提供/api/v1/import的 HTTP 端点。
monitoring
pull.addr/pull.port:启用/metrics端点时的监听地址与端口(示例中为0.0.0.0:8490),供 vmagent 抓取 vmanomaly 自身指标。
示例:vmanomaly_config.yml
schedulers: periodic: infer_every: "1m" fit_every: "1000d" # bootstrap-only schedule; use a finite cadence if accumulated state must be reset fit_window: "14d" # two weekly cycles for initial bootstrap models: temporal_envelope: class: "temporal_envelope" alpha: 0.005 # adapt the trend while using the bootstrap-only fit schedule loss_reactivity: 5 # allow new deviations to update the envelope seasonalities: ["hod_smooth", "dow_smooth"] provide_series: ["anomaly_score", "y", "yhat", "yhat_lower", "yhat_upper"] reader: datasource_url: "http://victoriametrics:8428/" sampling_period: "60s" queries: node_cpu_rate: expr: "sum(rate(node_cpu_seconds_total[5m])) by (mode, instance, job)" writer: datasource_url: "http://victoriametrics:8428/" monitoring: pull: # Enable /metrics endpoint. addr: "0.0.0.0" port: 8490该配置与仓库中实际可运行的 deployment/docker/vmanomaly/vmanomaly-integration/vmanomaly_config.yml 一致(仓库版本使用
fit_window: "2w"并额外提供queries: "all"、schedulers: "all"、iqr_threshold: 2等字段,可对照阅读)。fit_window: "14d"(两周)意味着初始 bootstrap 需要约两周数据来覆盖两个周周期。
7. vmanomaly 的输出指标
运行 vmanomaly 后会产出如下指标:
anomaly_score:核心指标。理想情况下,介于 0.0 与 1.0 之间视为非异常值;大于 1.0 视为异常(阈值可在告警配置中按需调整)。yhat:预测的期望值。yhat_lower:预测下边界。yhat_upper:预测上边界。y:原始查询结果值。
写入 VictoriaMetrics 的示例:
anomaly_score{for="node_cpu_rate", instance="node-exporter:9100", job="node-exporter", mode="idle"} 0.858. vmalert 告警配置
以下为 vmalert 的配置示例vmalert_config.yml(与仓库中 deployment/docker/vmanomaly/vmanomaly-integration/vmalert_config.yml 一致):
groups: - name: AnomalyExample rules: - alert: HighAnomalyScore expr: 'anomaly_score > 1.0' labels: severity: warning annotations: summary: Anomaly Score exceeded 1.0. `sum(rate(node_cpu_seconds_total))` is showing abnormal behavior.在查询表达式expr中,关键是基于生成的异常分数设定判定准则。通常,0.0 到 1.0的 anomaly score 表示被分析的值处于正常行为范围内;超过 1.0的分数表示模型对"该观测值异常"的信心在增加。
如何选择阈值?阈值的选择取决于具体需求与数据上下文。一个有效的方法是通过可视化分析:将anomaly_score指标与由yhat_lower、yhat_upper界定的"期望"范围一起绘制,据此做出更明智的阈值决策。下文第 10 节将结合实例演示。
9. Docker Compose 全栈部署
仓库中已提供全部配套文件,见 deployment/docker/vmanomaly/vmanomaly-integration/(包含compose.yml、vmanomaly_config.yml、vmalert_config.yml、prometheus.yml、alertmanager.yml、Grafana provisioning 目录及vmanomaly_guide_dashboard.json仪表盘)。本教程将编排以下服务:
| 服务 | 作用 |
|---|---|
| vmanomaly | VictoriaMetrics 异常检测服务 |
| victoriametrics | VictoriaMetrics 时序数据库 |
| vmagent | 从各类来源采集指标、relabel 与过滤,并通过 Prometheus remote_write 协议写入 VictoriaMetrics 或其他存储 |
| grafana | 可视化工具 |
| node-exporter | 暴露丰富的硬件与内核相关指标 |
| vmalert | VictoriaMetrics 告警服务 |
| alertmanager | 处理来自 vmalert 告警的通知服务 |
9.1 Grafana 数据源配置
在provisioning/datasources/目录下创建datasource.yml(默认用户名/密码为admin:admin):
apiVersion: 1 datasources: - name: VictoriaMetrics type: prometheus access: proxy url: http://victoriametrics:8428 isDefault: true jsonData: prometheusType: Prometheus prometheusVersion: 2.24.09.2 Grafana Dashboard Provider
在provisioning/dashboards/目录下创建dashboard.yml:
apiVersion: 1 providers: - name: Prometheus orgId: 1 folder: '' type: file options: path: /var/lib/grafana/dashboards9.3 vmagent 抓取配置
创建 vmagent 的prometheus.yml(仓库实际版本见 deployment/docker/vmanomaly/vmanomaly-integration/prometheus.yml):
global: scrape_interval: 10s scrape_configs: - job_name: 'vmagent' static_configs: - targets: - 'vmagent:8429' - job_name: 'vmalert' static_configs: - targets: - 'vmalert:8880' - job_name: 'victoriametrics' static_configs: - targets: - 'victoriametrics:8428' - job_name: 'node-exporter' static_configs: - targets: - 'node-exporter:9100' - job_name: 'vmanomaly' static_configs: - targets: - 'vmanomaly:8490'注意最后一个 job 抓取的是vmanomaly:8490,即上文 monitoring 配置中暴露的/metrics端点,用于对 vmanomaly 自身进行可观测性监控。
9.4 vmanomaly 许可证
本教程使用本地存储于文件vmanomaly_license中的 license key。使用前必须将仓库 deployment/docker/vmanomaly/vmanomaly-integration/vmanomaly_license 中的占位内容替换为有效的 license(可在 VictoriaMetrics 官方申请试用 key)。更多许可选项见官方 Anomaly Detection 文档的 Licensing 章节。
9.5 Alertmanager 配置
创建alertmanager.yml(仓库版本见 deployment/docker/vmanomaly/vmanomaly-integration/alertmanager.yml)。本教程中将告警路由到blackhole接收者(即只展示不实际发送通知):
route: receiver: blackhole receivers: - name: blackhole9.6 完整 docker-compose 文件
将上述配置整合进docker-compose.yml:
services: vmagent: container_name: vmagent image: victoriametrics/vmagent:v1.151.0 depends_on: - "victoriametrics" ports: - 8429:8429 volumes: - vmagentdata-guide-vmanomaly-vmalert:/vmagentdata - ./prometheus.yml:/etc/prometheus/prometheus.yml command: - "--promscrape.config=/etc/prometheus/prometheus.yml" - "--remoteWrite.url=http://victoriametrics:8428/api/v1/write" networks: - vm_net restart: always victoriametrics: container_name: victoriametrics image: victoriametrics/victoria-metrics:v1.151.0 ports: - 8428:8428 volumes: - vmdata-guide-vmanomaly-vmalert:/storage command: - "--storageDataPath=/storage" - "--httpListenAddr=:8428" - "--vmalert.proxyURL=http://vmalert:8880" - "-search.disableCache=1" # for guide only, do not use in production networks: - vm_net restart: always grafana: container_name: grafana image: grafana/grafana:12.2.0 depends_on: - "victoriametrics" ports: - 3000:3000 volumes: - grafanadata-guide-vmanomaly-vmalert:/var/lib/grafana - ./provisioning/datasources:/etc/grafana/provisioning/datasources - ./provisioning/dashboards:/etc/grafana/provisioning/dashboards - ./vmanomaly_guide_dashboard.json:/var/lib/grafana/dashboards/vmanomaly_guide_dashboard.json networks: - vm_net restart: always vmalert: container_name: vmalert image: victoriametrics/vmalert:v1.151.0 depends_on: - "victoriametrics" ports: - 8880:8880 volumes: - ./vmalert_config.yml:/etc/alerts/alerts.yml command: - "--datasource.url=http://victoriametrics:8428/" - "--remoteRead.url=http://victoriametrics:8428/" - "--remoteWrite.url=http://victoriametrics:8428/" - "--notifier.url=http://alertmanager:9093/" - "--rule=/etc/alerts/*.yml" # display source of alerts in grafana - "--external.url=http://127.0.0.1:3000" # grafana outside container # when copypaste the line be aware of '$$' for escaping in '$expr' - '--external.alert.source=explore?orgId=1&left=["now-1h","now","VictoriaMetrics",{"expr": },{"mode":"Metrics"},{"ui":[true,true,true,"none"]}]' networks: - vm_net restart: always vmanomaly: container_name: vmanomaly image: victoriametrics/vmanomaly:v1.30.4 depends_on: - "victoriametrics" ports: - "8490:8490" networks: - vm_net restart: always volumes: - ./vmanomaly_config.yml:/config.yaml - ./vmanomaly_license:/license platform: "linux/amd64" command: - "/config.yaml" - "--licenseFile=/license" alertmanager: container_name: alertmanager image: prom/alertmanager:v0.28.1 volumes: - ./alertmanager.yml:/config/alertmanager.yml command: - "--config.file=/config/alertmanager.yml" ports: - 9093:9093 networks: - vm_net restart: always node-exporter: image: quay.io/prometheus/node-exporter:v1.9.1 container_name: node-exporter ports: - 9100:9100 pid: host restart: unless-stopped networks: - vm_net volumes: vmagentdata-guide-vmanomaly-vmalert: {} vmdata-guide-vmanomaly-vmalert: {} grafanadata-guide-vmanomaly-vmalert: {} networks: vm_net:关键点解读:
- vmalert通过
--datasource.url、--remoteRead.url、--remoteWrite.url指向 VictoriaMetrics,--notifier.url指向 Alertmanager,--rule=/etc/alerts/*.yml加载告警规则文件。--external.url与--external.alert.source用于在 Grafana 中显示告警来源(复制该行时注意$$对$expr的转义)。 - victoriametrics的
-search.disableCache=1仅用于本教程(让结果更实时可见),生产环境不要使用。 - vmanomaly以
/config.yaml作为配置文件、--licenseFile=/license指定 license 文件,并声明platform: "linux/amd64"。
9.7 运行与验证
运行 docker-compose 前,请确保目录中包含全部所需文件(docker-compose.yml、prometheus.yml、alertmanager.yml、vmalert_config.yml、vmanomaly_config.yml、vmanomaly_license、vmanomaly_guide_dashboard.json及provisioning/目录)。随后执行:
docker-compose up -d提示:若使用新版 Docker Compose 插件,可改用
docker compose up -d。详见仓库 deployment/docker/vmanomaly/vmanomaly-integration/README.md 的运行说明。
该命令会拉取镜像、配置各服务并整体启动。要确认 vmanomaly 是否正常运行,可查看其日志:
docker logs vmanomaly -f10. 查看模型结果与告警
10.1 在 Grafana 中查看模型输出
打开localhost:3000进入 Grafana(需给 vmanomaly 一些时间生成足够多的数据)。在Vmanomaly Guide仪表盘中,针对每个 CPU mode 可以查看:
- 初始查询结果:
sum(rate(node_cpu_seconds_total[5m])) by (mode, instance, job) anomaly_scoreyhat(预测值)yhat_lower(预测下边界)yhat_upper(预测上边界)
上述每个指标都携带查询sum(rate(node_cpu_seconds_total[5m])) by (mode, instance, job)返回的相同标签。
10.2 查看各指标的异常分数
查询anomaly_score:
可以对照检查:你认为异常的数据点,其 anomaly score 是否确实较高?如果不是,可以尝试调整配置文件中的模型参数,或改用其他模型类型。
需要注意:刚启动时会有大量数据的 anomaly score 大于 1,这符合预期——因为抓取与存储刚刚开始,可用于训练的数据点不足。等待更长时间积累数据后,才能看出该模型发现异常的准确程度。本教程配置中模型完整拟合需要约两周数据。
10.3 预测边界与预测值
查询yhat_lower、yhat_upper和yhat:
这些边界即模型推理出的"正常"指标值范围。将yhat_lower/yhat_upper与anomaly_score对照观察,是确定告警阈值最直观的方法。
10.4 查看告警
在http://localhost:8880/vmalert/groups页面可以看到已配置的HighAnomalyScore告警规则(每 60 秒评估一次)。
根据为 vmalert 配置的规则,当 anomaly score 超过 1 时即触发告警。在http://localhost:8880/vmalert/alerts的 Alert 标签页可以看到处于 firing 状态的告警:
每条告警会携带instance、mode、job等标签,并展示触发时间与具体分数值,便于定位是哪个 CPU 模式、哪台主机出现了异常。
11. 源码佐证:配置在仓库中的真实落点
本文涉及的所有配置并非虚构,均可在当前仓库中找到对应实现:
- deployment/docker/vmanomaly/vmanomaly-integration/compose.yml:与本教程第 9.6 节 docker-compose 完全对应的服务编排(仓库版本省略了 container_name 与显式 networks,语义一致)。
- deployment/docker/vmanomaly/vmanomaly-integration/vmanomaly_config.yml:vmanomaly 实际配置,含
fit_window: "2w"与iqr_threshold: 2等补充参数。 - deployment/docker/vmanomaly/vmanomaly-integration/vmalert_config.yml:vmalert 告警规则。
- deployment/docker/vmanomaly/vmanomaly-integration/prometheus.yml:vmagent 抓取配置。
- deployment/docker/vmanomaly/vmanomaly-integration/provisioning/:Grafana 数据源与 Dashboard Provider 的自动配置。
- deployment/docker/vmanomaly/vmanomaly-integration/vmanomaly_guide_dashboard.json:Grafana 仪表盘定义。
- 异常检测相关组件的详细配置语义(scheduler、models、reader、writer、monitoring)可进一步阅读 docs/anomaly-detection/components/ 下的对应文档。
12. 总结
本文完整走通了VictoriaMetrics Anomaly Detection(vmanomaly)与 vmalert 的集成与实战:从前置条件、组件职责,到数据采集、配置编写、Docker Compose 部署,再到结果可视化与告警验证。核心收获如下:
- 理解 vmanomaly 与 vmalert:两者分别承担"用机器学习模型发现异常"与"基于异常分数触发告警"的职责,配合使用时能捕捉经典告警规则难以预先定义的异常模式。
- 掌握实用配置与部署:通过 docker-compose 环境,学会编排 VictoriaMetrics 及其关联服务(含 vmanomaly、vmalert),并理解
schedulers、models、reader、writer、monitoring各配置节的实际语义。 - 学会数据分析与监控:在 Grafana 中采集、分析与可视化数据,解读 vmanomaly 生成的 anomaly score、yhat、yhat_lower、yhat_upper 等指标。
- 掌握告警配置:基于 anomaly score 设置与定制 vmalert 告警规则,实现主动监控与潜在问题的及时响应。
需要强调的是,异常检测的有效性在很大程度上取决于模型选择是否恰当、配置是否准确以及数据模式本身。本文是一个起点,建议根据自身数据特点尝试不同的模型与参数组合。此外,官方在 v1.13.0 起提供的node-exporter可观测性预设(docs/anomaly-detection/Presets.md)可作为快速上手的另一条路径。
【免费下载链接】VictoriaMetricsVictoriaMetrics: fast, cost-effective monitoring solution and time series database项目地址: https://gitcode.com/GitHub_Trending/vi/VictoriaMetrics
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考