作为 VictoriaMetrics 用户,我们希望其具备数据删除能力。VictoriaMetrics 也确实支持删除操作,但是程度有限。由于实现上的问题,VictoriaMetrics 保持为一个 append-only 数据库,非常适合存储时序数据。这样的架构的缺点,就是修改、删除数据会变得非常昂贵。所以 VictoriaMetrics 对修改、删除操作的支持非常有限。在这篇指南中,我们就来看一下如何实现 VictoriaMetrics 中的数据的删除和修改。

如何删除指标

💡 警告:数据删除操作不建议作为一个周期性行为来执行。每次调用删除 API 都会对性能产生影响。提供删除 API 主要用于一次性需求,用于删除格式错误的数据或满足 GDPR 合规性。

删除 API 需要指定时序数据选择器。所以删除之前,首先要做的,应该是验证选择器是否匹配了期望的数据。可以使用如下命令来检查:

# Warning: response can return many metrics, so be careful with series selector.
curl -s 'http://vmselect:8481/select/0/prometheus/api/v1/series?match[]=process_cpu_cores_available' | jq

预期输出:

{
  "status": "success",
  "isPartial": false,
  "data": [
    {
      "__name__": "process_cpu_cores_available",
      "job": "vmagent",
      "instance": "vmagent:8429"
    },
    {
      "__name__": "process_cpu_cores_available",
      "job": "vmalert",
      "instance": "vmalert:8880"
    },
    {
      "__name__": "process_cpu_cores_available",
      "job": "vminsert",
      "instance": "vminsert:8480"
    },
    {
      "__name__": "process_cpu_cores_available",
      "job": "vmselect",
      "instance": "vmselect:8481"
    },
    {
      "__name__": "process_cpu_cores_available",
      "job": "vmstorage",
      "instance": "vmstorage-1:8482"
    },
    {
      "__name__": "process_cpu_cores_available",
      "job": "vmstorage",
      "instance": "vmstorage-2:8482"
    }
  ]
}

如果你确认时间序列选择器是符合预期的,接下来就可以发个POST请求执行删除,举例:

curl -s 'http://vmselect:8481/delete/0/prometheus/api/v1/admin/tsdb/delete_series?match[]=process_cpu_cores_available'

如果删除成功,删掉的数据就查不到了。不过存储空间不会立马释放,而是在后续数据文件后台合并的时候删除。前几个月的数据可能永远不会发生后台合并,因此不会为历史数据释放存储空间。这种情况下,可以尝试强制合并:

curl -v -X POST http://vmstorage:8482/internal/force_merge

merge 完成之后,数据就会从硬盘永久删除了。

如何更新指标

VictoriaMetrics 默认不提供更新数据的机制。不过你可以通过如下方式曲线折中实现:

  • 导出指标数据到文件中
  • 修改文件中的 value
  • 从 VictoriaMetrics 中删除相关指标
  • 把刚才保存的文件中的数据重新导入

导出指标

举个例子,导出node-exporter:9100这个实例和hostname.com这个job的node_memory_MemTotal_bytes指标:

curl -X POST -g http://vmselect:8481/select/0/prometheus/api/v1/export -d 'match[]=node_memory_MemTotal_bytes{instance="node-exporter:9100", job="hostname.com"}' > data.jsonl

检查一下导出的数据:

cat data.jsonl | jq

预期输出如下所示:

{
  "metric": {
    "__name__": "node_memory_MemTotal_bytes",
    "job": "hostname.com",
    "instance": "node-exporter:9100"
  },
  "values": [
    33604390912,
    33604390912,
    33604390912,
    33604390912
  ],
  "timestamps": [
    1656669031378,
    1656669032378,
    1656669033378,
    1656669034378
  ]
}

在这个例子中,我们使用 sed 命令替换 node_memory_MemTotal_bytes 的值,从 33604390912 改成 17179869184。当然,你可以使用自己习惯的方式来做修改:

sed -i 's/33604390912/17179869184/g' data.jsonl

检查一下修改是否成功:

cat data.jsonl | jq

期望的输出如下:

{
  "metric": {
    "__name__": "node_memory_MemTotal_bytes",
    "job": "hostname.com",
    "instance": "node-exporter:9100"
  },
  "values": [
    17179869184,
    17179869184,
    17179869184,
    17179869184
  ],
  "timestamps": [
    1656669031378,
    1656669032378,
    1656669033378,
    1656669034378
  ]
}

删除指标

前文介绍了,这里不再赘述。

导入指标

VictoriaMetrics 支持多种数据导入方式,下面我们使用从 json 文件导入的方式来导入数据:

curl -v -X POST http://vminsert:8480/insert/0/prometheus/api/v1/import -T data.jsonl

检查导入的指标

curl -X POST -g http://vmselect:8481/select/0/prometheus/api/v1/export -d match[]=node_memory_MemTotal_bytes

期望的输出如下:

{
  "metric": {
    "__name__": "node_memory_MemTotal_bytes",
    "job": "hostname.com",
    "instance": "node-exporter:9100"
  },
  "values": [
    17179869184,
    17179869184,
    17179869184,
    17179869184
  ],
  "timestamps": [
    1656669031378,
    1656669032378,
    1656669033378,
    1656669034378
  ]
}