1. 引言
VictoriaMetrics 作为一个高性能、经济高效且可扩展的时序数据库解决方案,在监控领域得到了广泛应用 1。然而,随着数据量的持续增长,磁盘空间的有效管理成为确保系统稳定性和成本控制的关键因素。磁盘空间不足不仅可能导致数据丢失、服务中断,还会显著增加运维成本。因此,深入理解 VictoriaMetrics 的存储机制并采取有效的优化策略至关重要。
本报告旨在全面探讨 VictoriaMetrics 磁盘空间占用的优化方法。首先,报告将概述 VictoriaMetrics 的核心存储架构,为后续的优化讨论奠定基础。随后,将详细介绍如何识别磁盘空间瓶颈,包括监控关键指标以及诊断高基数和高流失率等常见问题。核心章节将聚焦于具体的优化策略,涵盖数据保留、去重、降采样等配置调整,以及解决高基数问题、数据删除、vmagent 配置优化等高级技术。最后,报告还将讨论容量规划和长期管理方面的考量,并对关键优化手段进行总结。通过本报告,用户可以更全面地掌握 VictoriaMetrics 磁盘空间优化的原理和实践,从而更高效地利用这一强大的时序数据库。
2. VictoriaMetrics 存储架构概览
理解 VictoriaMetrics 的存储架构是优化磁盘空间占用的前提。其设计旨在实现高效率的数据写入、压缩和查询。
2.1 核心组件及其职责
VictoriaMetrics 采用模块化设计,主要组件包括单节点版本和集群版本 2。无论是单节点还是集群版本,其核心功能都围绕着数据的插入、存储和查询。
-
vminsert (集群版组件): 负责接收来自vmagent 或其他兼容 Prometheus 协议的数据源发送的数据。它使用基于指标名称和标签的一致性哈希算法将数据分片到不同的vmstorage 节点 2。此外,vminsert 支持数据复制以提高持久性和可用性。在某些vmstorage 节点不可用时,vminsert 会将数据重新路由到健康的节点,优先保证可用性 2。 -
vmstorage: 这是核心的存储节点,负责接收来自vminsert 的数据并将其持久化到磁盘,同时响应来自vmselect 的查询请求 2。每个vmstorage 节点都需要一个独立的数据目录 (通过-storageDataPath 参数指定),并使用-retentionPeriod 参数自动管理数据保留 2。vmstorage 还会维护内存缓存以加速频繁访问数据的查询,并监控磁盘空间等系统指标。当可用磁盘空间严重不足时,vmstorage 可能会切换到只读模式 2。 -
vmselect (集群版组件): 负责处理查询请求。它会将查询分解并发送到所有相关的vmstorage 节点,等待响应,合并结果,并应用任何必要的聚合或汇总函数,最终向客户端返回统一的结果 2。 -
vmagent: 这是一个高效的指标收集代理,可以从各种来源抓取指标,支持 Prometheus 的relabeling 规则,允许在发送数据前对指标进行添加、修改或删除标签,从而实现数据清理、元数据组织、过滤不需要的指标以及将特定指标路由到不同的存储目标 2。如果远程存储不可用,vmagent 会将指标缓存在本地磁盘,并在连接恢复后重新发送 2。 - 单节点 VictoriaMetrics: 与集群版不同,单节点版本在单个进程中执行
vminsert、vmstorage 和vmselect 的所有任务,专为垂直扩展而设计 2。对于每秒数据点采集率低于一百万的场景,官方推荐使用单节点版本,因为它避免了内部组件之间的网络开销,从而可能减少 CPU 和内存使用,并且更易于设置和管理 2。
VictoriaMetrics 的集群架构遵循“无共享架构”(shared-nothing architecture),组件之间通过网络通信,不共享内存或磁盘,这增强了集群的可用性并简化了维护和扩展 2。
2.2 数据分区与数据块生命周期
vmstorage 内部对数据进行高效组织以优化存储和查询性能。数据按月进行分区存储 4。每个分区覆盖一个月的数据,并将数据组织成三种类型的 LSM (Log-Structured Merge-tree) 部件(parts):
- 内存部件 (In-memory part) : 这是原始数据行分片(raw-row shards)首次刷盘后数据所处的位置。此时,指标数据变为可搜索和可查询状态 5。这些内存部件通常占用系统内存的约 10% 5。
- 小部件 (Small part) : 比内存部件稍大,存储在持久化磁盘上(通常在
<-storageDataPath>/data/small 目录)5。 - 大部件 (Big part) : 是最大的部件,也存储在磁盘上(通常在
<-storageDataPath>/data/big 目录)5。
vmstorage 会定期(默认为每5秒,通过 -inmemoryDataFlushInterval 控制)将内存部件刷写到磁盘上的部件中,并在该过程中进行合并,以确保即使 vmstorage 崩溃(如 OOM 错误或 SIGKILL信号),最近接收的数据也不会丢失 5。
2.3 合并过程
VictoriaMetrics 在后台执行数据合并(compaction/merge)操作,以维持良好的性能和压缩率 4。合并过程主要发生在 vmstorage 节点内部,针对每个月度分区独立进行 5。
合并的主要目标是将较小的、可能存在冗余数据的数据部件融合成更大、更紧凑的数据部件。这个过程有几个好处:
- 提高查询性能: 查询时需要检查的数据部件数量减少 4。
- 减少数据文件数量: 每个部件包含固定数量的文件,合并后总文件数减少 4。
- 应用去重和降采样: 在合并过程中,可以根据配置执行数据去重和降采样操作 5。
vmstorage 的合并乘数(merge multiplier)通常设置为 7.5,一次最多合并 15 个部件 5。系统会根据可用资源(如内存和磁盘空间)动态调整合并策略。例如,如果系统可用内存较少,可能会选择创建大部件而不是小部件,以避免过多使用有限的内存 5。小部件的最大大小通常限制在 10MB 左右,而大部件可以达到剩余磁盘空间的四分之一左右,但不会超过 1TB 5。
值得注意的是,后台合并操作是持续进行的,但对于不再有新数据写入的旧分区(例如上个月的分区),合并活动可能会停止。如果需要对旧分区强制执行合并(例如,在更改去重设置或删除数据后回收空间),可以通过 API /internal/force_merge?partition_prefix=YYYYMMDD 来触发特定月份分区的强制合并 6。
2.4 indexdb 的角色和工作原理
indexdb 是 VictoriaMetrics 存储引擎中至关重要的组成部分,负责存储时序数据的索引信息。当 vmstorage 接收到新的指标数据时,它会为每个唯一的时序(由指标名称和一组标签定义)生成一个唯一的标识符,称为 TSID (TimeSeries ID) 3。indexdb 的核心功能就是建立从指标名称、标签到其对应 TSID 的映射关系,以及其他元数据查找条目。
具体来说,indexdb 中会创建多种类型的条目,例如 3:
- 指标日期到指标 ID 的映射。
- 指标 ID 到 TSID 的映射。
- (日期, 指标) 到 TSID 的映射。
- 指标名称以及每个标签(如
code="200",path="/") 到指标 ID 的映射。
为了加速查找,vmstorage 会维护一个内存中的 TSID 缓存,直接将原始指标名称映射到 TSID 3。如果缓存未命中,则需要在 indexdb 中查找。
indexdb 的大小和性能直接受到数据基数(唯一时间序列的数量)和流失率(旧时间序列被新时间序列取代的速率)的影响。高基数意味着需要索引更多的唯一时间序列,从而增加 indexdb 的大小。高流失率则意味着 indexdb 需要频繁更新,不断注册新的 TSID 并处理旧 TSID 的淘汰,这会消耗更多的 CPU 和磁盘 I/O 资源,并可能导致 indexdb 膨胀 8。一个健康的系统中,<-storageDataPath>/indexdb 文件夹的大小通常应小于 <-storageDataPath>/data 文件夹的大小。如果前者显著大于后者(例如,占比超过 50%),则很可能存在高流失率问题 8。
2.5 影响磁盘空间的架构因素
从架构层面看,多个因素共同决定了 VictoriaMetrics 的磁盘空间占用:
- 数据压缩效率: VictoriaMetrics 使用了优于 Prometheus Gorilla 压缩的算法,通常能实现很高的数据压缩率,从而显著减少原始数据所需的存储空间 9。一般情况下,每个样本点压缩后约占 1 字节 11。
- **数据保留期 (**
-retentionPeriod ) : 这是最直接影响磁盘空间的因素。保留期越长,存储的数据量越大 2。 - 数据基数 (Cardinality) : 唯一时间序列的数量。高基数不仅会增加
indexdb 的大小,还可能因为每个序列的数据点较少而降低数据部分的压缩效率,因为压缩算法在处理更长、更连续的数据块时效果更好 11。 - 数据流失率 (Churn Rate) : 新时间序列取代旧时间序列的速率。高流失率会导致
indexdb 频繁更新和膨胀,并可能产生许多小的、生命周期短的数据部件,这些部件在被合并之前会占用额外空间,同时影响压缩效率 8。 - 数据去重 (Deduplication) : 如果启用了去重,并且存在大量重复或近似重复的数据点(例如,来自高可用采集代理对),去重可以显著减少存储的数据量 5。
- 降采样 (Downsampling) : 对旧数据降低采样频率,只保留聚合后的数据点,可以大幅减少长期存储所需的空间 5。
- 数据部件的合并策略和效率: 后台合并过程的效率直接影响数据在磁盘上的紧凑程度。如果合并跟不上写入速度,或者由于资源限制(如 CPU、磁盘 I/O)导致合并缓慢,可能会暂时性地增加磁盘占用 5。
-
indexdb 的大小: 如前所述,indexdb 的大小与基数和流失率密切相关,是总磁盘占用的重要组成部分 8。 - 预留空间: VictoriaMetrics 需要一定的预留磁盘空间(建议至少 20%)来进行有效的合并操作和处理突发写入。如果可用空间过低,
vmstorage 可能进入只读模式,并且合并等优化操作可能无法正常进行 3。
这些架构因素相互作用,共同决定了最终的磁盘空间使用情况。因此,优化磁盘空间需要综合考虑这些方面,而不仅仅是调整单一配置。例如,仅仅延长保留期而不解决高基数问题,可能会导致磁盘空间失控。反之,有效管理基数和流失率,配合合理的保留策略和去重/降采样,才能实现最佳的磁盘空间效率。
3. 识别磁盘空间占用瓶颈
在着手优化之前,准确识别导致磁盘空间占用过高的瓶颈至关重要。这通常涉及监控关键系统指标、利用可视化工具以及诊断特定的数据特征问题,如高基数和高流失率。
3.1 监控关键指标
VictoriaMetrics 自身会暴露大量内部状态指标,这些指标可以通过 Prometheus 兼容的方式进行抓取和监控。对于磁盘空间占用,以下指标尤为关键:
-
vm_data_size_bytes{type="<type>"} : 该指标展示了不同类型数据占用的磁盘空间大小。<type> 可以是storage/small(小部件数据)、storage/big(大部件数据)、indexdb(索引数据)等。通过监控这些细分指标,可以了解磁盘空间主要被哪部分数据占用 8。 -
vm_free_disk_space_bytes{path="<path>"} : 显示指定路径(即-storageDataPath 对应的路径)的可用磁盘空间。持续监控此指标并设置告警阈值(例如,低于 20% 时告警)是防止磁盘耗尽的必要措施 8。 -
vm_rows_per_insert: 每次插入操作平均包含的数据行数。如果该值持续较低,可能意味着插入请求过于频繁或批量大小不足,这可能影响写入效率和产生更多的小数据块,间接影响合并效率和磁盘空间。 -
vm_inflight_insert_requests: 当前正在处理的插入请求数。如果该值持续较高,可能表明存储层存在写入压力。 -
vm_new_timeseries_created_total 或相关流失率指标: 监控新时间序列的创建速率。VictoriaMetrics 的 Grafana 仪表盘通常包含一个“Churn rate”图表,显示过去24小时内注册的新时间序列的平均数量 8。高流失率是磁盘空间问题的重要诱因。 -
vm_active_timeseries: 当前活跃的时间序列数量。这是衡量系统基数的一个重要指标 8。
3.2 使用 vmui 和 Grafana 仪表盘
VictoriaMetrics 提供了内置的 Web UI (vmui),它不仅可以用于查询数据,还提供了一些有用的诊断信息。例如,vmui 的“Cardinality Explorer”(基数浏览器)功能可以帮助识别具有最高基数(最多唯一标签组合)的指标 8。
官方推荐为 VictoriaMetrics 设置 Grafana 仪表盘,这些仪表盘预置了对关键性能和健康指标的可视化,包括磁盘使用情况、活跃时间序列数量、流失率、慢插入等 8。通过这些仪表盘,可以直观地发现异常趋势和潜在问题。例如,“Slow inserts”图表如果显示值持续高于 5%,可能表明活跃时间序列数量超出了 storage/tsid 缓存的容量,导致性能下降和资源消耗增加 8。
3.3 高基数问题诊断
高基数是指指标具有过多唯一标签组合的情况,是导致磁盘空间(尤其是 indexdb)和内存占用过高、查询缓慢的常见原因 12。
诊断方法:
VictoriaMetrics 基数浏览器:
vmui 中的基数浏览器是最直接的工具,可以列出具有最高基数的指标名称、标签名和标签值组合 8。PromQL/MetricsQL 查询:
- 查找具有最多序列数的指标:
topk(10, count by (__name__)({__name__=~".+"})) 12。 - 检查特定指标的基数:
count(count by (label1, label2,...)(metric_name)) 12。
- 查找具有最多序列数的指标:
VictoriaMetrics API:
-
/api/v1/status/tsdb: 此端点以 Prometheus 类似的方式返回 TSDB 统计信息,包括高基数指标的相关信息,例如可以通过topN=N 参数获取基数最高的 N 个指标 4。 -
curl http://vmselect:8481/select/0/prometheus/api/v1/series/count | jq (集群版) 或类似单节点命令,可以获取总序列数或按指标名称统计的序列数 12。
-
常见的导致高基数的“元凶”包括:将完整的 URL、用户 ID、随机生成的 Pod 名称等用作标签值 12。一旦识别出高基数指标及其来源,就需要采取措施减少标签的唯一值数量,例如参数化 URL、使用用户类型代替用户 ID,或在 vmagent层面通过 relabel_configs 丢弃或修改这些标签 12。
3.4 高流失率问题诊断
高流失率是指旧的时间序列被新的时间序列以非常快的速度替换的现象。这通常发生在标签值频繁变化的场景(例如,每次应用部署都产生新的 instance 或 pod 标签值,而旧值不再使用)。高流失率对 indexdb 的压力尤为巨大,因为注册新序列比向现有序列添加数据点要慢得多,并且会导致 indexdb 快速增长和索引碎片化 8。
诊断方法:
Grafana 仪表盘: 官方 VictoriaMetrics Grafana 仪表盘通常包含一个“Churn rate”图表,显示了在过去24小时内注册的新时间序列的平均数量。如果这个数字超过了活跃时间序列的数量,那么就表明存在高流失率问题 8。
indexdb 与数据文件夹大小比较:- 检查
<-storageDataPath>/indexdb 文件夹的大小是否显著大于<-storageDataPath>/data 文件夹的大小。正常情况下,indexdb 的大小应该远小于数据部分。 - 可以使用以下查询(如果已设置 VictoriaMetrics 监控):
sum(vm_data_size_bytes{type=~"indexdb/.+"}) without(type) / sum(vm_data_size_bytes{type=~"(storage|indexdb)/.+"}) without(type)如果此查询返回的值大于 0.5,则很可能存在高流失率问题,导致indexdb 和数据文件夹的磁盘空间使用过多 8。
- 检查
基数浏览器: 高流失率通常也伴随着高基数,因为不断有新的序列被创建。基数浏览器可以帮助识别那些标签值频繁变化的指标 8。
解决高流失率的关键在于识别并修复导致标签值频繁变化的源头。这可能需要在应用层面调整指标暴露方式,或者在 vmagent 中使用更积极的 relabel_configs 来规范化或移除易变的标签 8。例如,对于 Kubernetes 环境中因 Pod 重启导致 pod 标签不断变化的问题,可能需要考虑在聚合时忽略 pod 标签,或者使用更稳定的上层标识(如 deployment 或 statefulset)。高流失率不仅消耗磁盘空间,还会降低查询性能和缓存效率,因此尽早识别和处理至关重要 11。
4. 核心优化策略:配置与调整
VictoriaMetrics 提供了多种内置机制来帮助用户管理和优化磁盘空间占用。其中,数据保留策略、数据去重和降采样是最核心的配置选项。
4.1 数据保留策略 (-retentionPeriod)
-retentionPeriod 命令行标志用于设置数据的保留时长,是控制磁盘空间使用的最基本也是最重要的手段 2。该标志接受一个数字后跟时间单位字符(如 h 小时, d 天, w 周, y 年;若无单位则默认为月)4。例如,-retentionPeriod=30d 表示数据保留30天。
工作机制:
-
vmstorage 会自动删除超出指定保留期的数据 2。 - 在数据接收阶段(由
vminsert 或单节点 VictoriaMetrics 处理),时间戳超出保留期的数据点会被直接丢弃 5。 - 后台会有一个“保留观察者”(retention watcher) 每分钟运行一次,清理旧的数据部件和分区 5。数据按月分区存储,当整个分区的所有数据都超出保留期后,该分区目录会被快速删除 5。
重要注意事项:
- 部件级保留: 一个数据部件(part)只要包含一个仍在保留期内的数据点,整个部件就不会被删除。这意味着某些旧数据点可能会比预期保留更长时间,直到其所在的整个部件都完全超出了保留窗口 5。这强调了后台合并的重要性,因为合并会重新组织数据,可能将旧数据分离到可以被更快删除的部件中。
- 运行时更改保留策略: 在运行时更改
-retentionPeriod 需要谨慎。根据官方文档和社区反馈,更改此参数可能会导致先前indexdb 的数据早于预期被删除的问题,或者对历史数据的应用可能不会立即生效,而是随着后台合并逐渐体现 5。 - VictoriaLogs 的特定保留: 对于 VictoriaLogs,除了基于时间的
-retentionPeriod,还可以通过-retention.maxDiskSpaceUsageBytes 设置基于磁盘空间总用量的保留策略,当总存储大小超过阈值时,会自动删除最旧的按天分区数据。但它至少会保留最近两天的数据 6。
企业版功能 - Retention Filters:
VictoriaMetrics 企业版支持通过 -retentionFilter 标志为特定标签组合的数据设置不同的保留期 5。例如:
-
-retentionFilter='{team="juniors"}:3d':标签team="juniors" 的数据保留3天。 -
-retentionFilter='{env=~"dev|staging"}:30d':标签env 为dev 或staging 的数据保留30天。 这些可以与全局的-retentionPeriod 结合使用,例如-retentionFilter='{team="juniors"}:3d' -retentionPeriod=1y,表示 “juniors” 团队的数据保留3天,其他数据默认保留1年 5。
合理设置 -retentionPeriod 是平衡数据价值和存储成本的第一步。过短可能导致无法进行长期趋势分析和故障排查,过长则会消耗大量磁盘。
4.2 数据去重 (-dedup.minScrapeInterval)
数据去重功能旨在消除由高可用性采集设置(例如,两个相同的 vmagent 实例采集相同的目标)或网络重试等原因造成的重复数据点。默认情况下,去重是关闭的 5。
启用与配置:
通过设置 -dedup.minScrapeInterval 命令行标志来启用和配置去重。此标志的值应设置为数据源的最小抓取间隔。例如,如果 Prometheus 的抓取间隔是 15 秒,则可以将 -dedup.minScrapeInterval=15s。VictoriaMetrics 会在此时间窗口内对具有相同时间戳(或非常接近的时间戳)和相同标签集的指标值进行去重,只保留一个版本(通常是值最大的那个,或者根据具体实现策略选择)5。
工作机制与影响:
- 去重操作发生在
vmstorage 的后台合并过程中 5。 - 当配置了
-dedup.minScrapeInterval 后,vmstorage 会在合并数据部件时,识别并移除在指定时间间隔内的重复数据点 5。 - 这可以显著减少磁盘使用量,并可能提高查询速度,因为需要处理的数据点更少 5。
注意事项:
- 对实时更新值的影响: 如果某些时间序列在同一时间戳下会有值的更新(例如,交易系统中的价格更新),则应避免对这些序列进行去重,因为去重可能会保留非预期的值(例如,总是选择最大值)5。
- 更改去重窗口: 每个数据部件都会记录其合并时所使用的去重窗口。如果运行时更改了
-dedup.minScrapeInterval 的值,一个“去重观察者”(Deduplication Watcher) 会每小时检查是否有部件的去重窗口小于新设置的窗口。如果是,则会触发对该分区中所有部件的合并,以应用新的去重设置。当前月份分区中的现有数据不会被此更改追溯去重,但新进入的数据会立即遵循新的去重窗口 5。 - 与降采样的关系: 如果同时启用了降采样,需要确保
-dedup.minScrapeInterval 的值与降采样的时间间隔兼容(例如,互为倍数关系),以避免冲突和不一致的行为 14。
在确定是否启用以及如何配置去重时,需要仔细评估数据源的特性和采集架构。对于确实存在冗余数据采集的场景,去重是一个非常有效的空间优化手段。
4.3 降采样 (-downsampling.period)
降采样是一种通过降低旧数据的采样频率来减少长期存储数据量的技术。它对于那些不需要永久保留高精度原始数据,但仍希望进行长期趋势分析的场景非常有用 5。
配置语法:
降采样通过 -downsampling.period=offset:interval 命令行标志进行配置。这意味着对于时间戳早于 offset 的数据,系统将只保留每个 interval 内的最后一个样本点,其余的则被丢弃 5。offset 必须是 interval 的倍数 14。
多级降采样:
可以多次指定 -downsampling.period 标志以实现多级降采样策略 5。例如:
-downsampling.period=30d:5m,180d:1h
这条配置表示:
- 对于早于30天的数据,每5分钟保留一个点。
- 对于早于180天的数据,每1小时保留一个点 5。
带过滤器的降采样:
可以将降采样规则应用于特定的时间序列子集,通过使用 filter:offset:interval 的语法 5。filter 是一个标准的 Prometheus 序列选择器。例如:
-downsampling.period=’{__name__=~"(node|process)_.*"}:7d:1m'
此配置指示 VictoriaMetrics 对名称以 node_ 或 process_ 开头的指标,在数据早于7天后,以1分钟的间隔进行降采样 5。
工作机制与注意事项:
- 降采样操作在
vmstorage 的后台合并期间执行 5。 - 需要足够的可用磁盘空间才能执行降采样,如果磁盘空间不足或
vmstorage 处于只读模式,则无法进行 14。 - 应用带过滤器的降采样时,由于需要读取、过滤和持久化数据,预计 CPU 和内存资源使用会暂时增加 14。
- 如果一个时间序列匹配多个过滤器,则应用第一个匹配到的过滤器的降采样规则 14。
- 若要对某些匹配特定过滤器的序列禁用降采样,可以使用
filter:0s:0s 的形式,并将其置于其他规则之前。但0s:0s 或0s:interval 不能与去重同时使用,因为可能存在冲突 14。 - 在 VictoriaMetrics 重启期间更新
-downsampling.period 标志是安全的,更新后的配置将最终在后台合并期间应用于历史数据 14。 - 在版本 v1.106.0 中曾引入一个关于带过滤器
filter:offset:interval 的降采样规则可能被未过滤规则offset:interval 错误跳过的回归性缺陷,该问题已在 v1.119.0 及后续版本中修复 13。
降采样是管理海量历史数据的有效手段,尤其适用于那些对近期数据精度要求高,而对远期数据精度要求相对较低的场景。通过精心设计多级降采样策略,可以在保证数据分析能力的同时,大幅节约长期存储成本。
5. 高级优化技术与主动管理
除了核心的配置调整外,VictoriaMetrics 还提供了一些高级技术和管理手段,用于应对更复杂的数据特性和实现更精细化的磁盘空间控制。这包括主动解决高基数和高流失率问题,审慎地执行数据删除,以及优化数据采集端的配置。
5.1 解决高基数和高流失率问题
高基数和高流失率是导致 VictoriaMetrics(尤其是 indexdb)磁盘空间占用过高、性能下降的主要“隐形杀手”。主动识别和解决这些问题至关重要。
策略概览:
识别来源: 利用第3节中描述的诊断工具(如基数浏览器、API、特定查询)定位产生高基数或高流失率的指标和标签 8。常见来源包括将请求ID、用户ID、完整URL路径、动态容器ID等直接作为标签值 12。
减少标签基数 (Reduce Label Cardinality) :
- 参数化: 不要使用具体的实例值作为标签,而是使用模式或类别。例如,将
path="/api/v1/users/12345/profile" 替换为path_pattern="/api/v1/users/:id/profile" 12。 - 泛化: 将具体的标签值替换为更通用的类别。例如,用
user_type="registered" 代替user_id="12345" 12。 - 哈希: 对于某些必须保留但基数过高的标签,可以考虑对其值进行哈希处理,以减少唯一值的数量,但这会牺牲一定的可读性。
- 参数化: 不要使用具体的实例值作为标签,而是使用模式或类别。例如,将
使用记录规则 (Recording Rules) : 对于需要高基数标签进行细粒度分析的场景,可以考虑在 Prometheus 或
vmalert 中创建记录规则,预先聚合数据,生成新的、基数较低的指标用于常规查询和仪表盘,而原始高基数数据可以设置较短的保留期或不保留 2。流式聚合 (Streaming Aggregation) : 在数据存储之前进行实时聚合。这种方式可以处理像
user_id 或session_id 这样的高基数指标,在数据进入存储系统前就降低其基数,从而节省存储和计算成本。但这可能导致原始指标细节的丢失 15。vmagent 的relabel_configs 可以在一定程度上实现类似效果。在源头或
vmagent层面过滤/修改标签:- Prometheus
relabel_configs / metric_relabel_configs: 在数据采集端(如 Prometheus exporter 或vmagent 的抓取配置中)使用relabel_configs 来drop (丢弃) 不必要的标签或高基数标签,或者replace (替换) 标签值以降低其基数 2。这是最有效的手段之一,因为它从源头上阻止了问题数据的进入。
- Prometheus
设计时考虑基数: 制定清晰的标签使用指南,教育团队成员了解添加新标签对系统的影响,并定期审计指标以清理未使用或冗余的标签 15。
监控基数变化: 设置告警,当唯一时间序列数或维度意外增长时得到通知 15。可以使用
vm_metrics_with_highest_cardinality (VictoriaMetrics) 或sum(scrape_series_added) by (job) (Prometheus) 等指标进行监控 12。
高基数和高流失率问题往往源于监控系统设计或应用埋点的不规范。解决这些问题通常需要跨团队协作,从应用代码、Exporter 配置到 vmagent 和 VictoriaMetrics 本身的配置进行全面审视和调整。虽然 VictoriaMetrics 相较于 Prometheus 能更好地处理高基数数据,但优化仍然是必要的,以确保最佳性能和资源利用率 12。
5.2 数据删除策略
在某些情况下,可能需要从 VictoriaMetrics 中删除数据,例如移除错误注入的数据、遵守 GDPR 等数据隐私法规,或尝试回收磁盘空间。VictoriaMetrics 提供了 API 进行数据删除,但也存在手动删除分区的方式,后者风险极高。
**通过 API 删除数据 (** /api/v1/admin/tsdb/delete_series )
VictoriaMetrics 允许通过 /api/v1/admin/tsdb/delete_series API 端点删除时间序列 16。
使用方法:
- 单节点 VictoriaMetrics:
curl http://<vm-addr>:8428/api/v1/admin/tsdb/delete_series -d 'match=<selector>' - 集群版 VictoriaMetrics:
curl http://<vmselect-addr>:8481/delete/<accountID>/prometheus/api/v1/admin/tsdb/delete_series -d 'match=<selector>' 17 -
<selector> 是一个 Prometheus 时间序列选择器,用于指定要删除的指标,例如my_metric、{job="my_job"} 或{__name__="my_metric",label="value"} 7。 - 重要: 此 API 只能完整删除匹配选择器的时间序列,不支持删除特定时间范围内的数据点 18。
- 单节点 VictoriaMetrics:
影响与过程:
- 删除操作成功后,被删除的序列将不再可查询 7。
- 磁盘空间不会立即释放。空间将在后续的后台数据文件合并过程中逐渐回收。对于历史数据(例如前几个月的分区),后台合并可能永远不会发生,因此这些空间可能不会自动释放 7。
- 在这种情况下,可能需要强制合并 (
curl -v -X POST http://vmstorage:8482/internal/force_merge 或针对特定分区的强制合并API/internal/force_merge?partition_prefix=YYYYMMDD) 来帮助释放磁盘空间 6。 -
indexdb 中的条目也不会立即清理,而是在配置的保留期过后才会被清理 18。
风险与建议:
- 不推荐用于常规清理: 由于存在性能开销,此 API 主要用于一次性的操作,如删除错误数据或满足合规性要求,不应用于定期的数据清理 7。
- 优先预防: 更推荐的做法是通过
relabeling 等手段从一开始就阻止不需要的数据写入 VictoriaMetrics 18。 - 验证选择器: 在执行删除前,强烈建议使用
/api/v1/series?match=<selector> API(可能需要调整start 和end 参数)来验证选择器将匹配到哪些序列,以避免误删 7。 - 安全: 可以通过
-deleteAuthKey 命令行标志为删除 API 设置授权密钥以增加安全性 18。
手动删除分区目录
这是一种直接在文件系统层面删除数据的方法,被认为是移除整月分区数据“最简单和最快的方式”,但风险极高 17。
过程:
- 停止 VictoriaMetrics 服务(单节点)或相关的
vmstorage 节点(集群版)。 - 删除目标月份的目录,例如
YYYY_MM,该目录位于<-storageDataPath>/data/small/ 和<-storageDataPath>/data/big/ 之下。 - 重新启动 VictoriaMetrics 服务或
vmstorage 节点 17。
- 停止 VictoriaMetrics 服务(单节点)或相关的
风险:
- 极度危险: 如果操作不当(例如,删错目录、未正确停止服务),极易导致数据损坏或永久性数据丢失。
- 绕过元数据管理: 此操作完全绕过了 VictoriaMetrics 内部的元数据管理机制。
- 孤立
indexdb 条目: 可能会在indexdb 中留下指向已删除数据文件的孤立条目,虽然这些条目最终可能会因保留期而清理,但短期内可能导致不一致。 - 仅限最后手段: 只有在 API 删除方法不适用(例如,需要删除非常大量的历史整月数据,API 效率过低)且操作人员完全理解潜在风险并具备相应专业知识时,才应考虑此方法。
数据删除方法对比表
为了更清晰地对比这两种数据删除方法,下表总结了它们的主要特性和风险:
| 特性 | API 删除 (/api/v1/admin/tsdb/delete_series) | 手动分区删除 |
|---|---|---|
| 操作概要 | curl请求,使用match选择器7 | 停止服务,rm -rf <storageDataPath>/data/{small,big}/YYYY_MM, 启动服务17 |
| 粒度 | 基于标签选择器的特定时间序列。无法删除时间范围18。 | 所有序列的整月数据。 |
| 磁盘空间回收 | 非即时。在后续后台合并中回收。可能需要强制合并7。 | 删除分区文件后即时(服务重启后)。 |
indexdb清理 | 非即时。按保留期清理18。 | 无直接indexdb清理;可能留下孤立条目。 |
| 安全性 | 若选择器已验证,则相对安全。可审计。 | 极度危险。极易出错,导致数据损坏。 |
| 推荐用途 | 一次性修正(错误数据,GDPR),不用于常规清理7。 | 仅作为最后手段,由专家在 API 不可行时用于批量移除旧的月度数据。 |
| 性能影响 | 每次调用有非零开销7。 | 需要服务停机。 |
| 相关文档片段 | 7 | 17 |
选择何种删除策略取决于具体需求和风险承受能力。API 删除更为规范和安全,而手动删除虽然快速,但伴随着巨大的操作风险。一个重要的考虑是,VictoriaMetrics 的设计哲学倾向于数据不可变性和追加写入,这使得删除操作相对“重”。因此,与其频繁依赖删除来管理空间,不如从数据采集和配置层面入手,预防不必要数据的产生和存储,这是一种更为高效和稳健的长期策略。
5.3 优化 vmagent 配置
vmagent 作为数据进入 VictoriaMetrics 存储层之前的第一道关卡,其配置对于控制数据量、降低基数、过滤无关指标从而优化磁盘空间至关重要 2。
过滤不需要的指标: 在
vmagent 的 Prometheus 抓取配置中,使用metric_relabel_configs 的action: drop 规则,可以在指标被发送到远程存储之前就将其丢弃 2。这对于排除那些对监控目标没有实际价值的指标非常有效。YAML# vmagent scrape job example scrape_configs: - job_name: 'example_service' static_configs: - targets: ['service_host:port'] metric_relabel_configs: - source_labels: [__name__] regex: 'go_goroutines|process_cpu_seconds_total' # Drop these specific metrics action: drop - source_labels: [__name__] regex: 'some_prefix_to_keep_.*' # Keep metrics with this prefix action: keep在代理层面重打标签 (Relabeling at Agent Level) :
修改或丢弃高基数标签:
metric_relabel_configs 同样可以用来修改或丢弃导致高基数的标签 2。例如,如果某个标签instance_id 的值是随机生成的 UUID,可以考虑将其drop,或者使用replace 和hashmod 等操作将其转换为基数较低的值。YAMLmetric_relabel_configs: - source_labels: [problematic_label] action: labeldrop # Drop the label entirely - source_labels: [user_id_label] regex: '.*' # Match any user_id target_label: user_category # Create a new, lower cardinality label replacement: 'registered_user' # Generalize the value标准化标签名称和值: 确保标签命名和取值的一致性,避免因大小写、命名风格不一等问题产生不必要的额外序列。
减少抓取间隔: 对于某些变化不频繁或重要性较低的指标,适当增加抓取间隔(
scrape_interval)可以直接减少数据点的产生量 12。
vmagent 的优化是“预防胜于治疗”理念的体现。通过在数据采集和预处理阶段就进行精细化控制,可以从源头上减少进入存储系统的数据量和复杂性,这不仅能节省 vmstorage 的磁盘空间,还能减轻 vminsert 的处理压力,降低网络带宽消耗,并提升整体查询性能。相比于数据存储后再进行清理或优化,vmagent 端的预处理成本更低,效果也更直接。
5.4 微调存储相关配置标志 (Beyond Core)
除了核心的保留、去重、降采样配置外,VictoriaMetrics 还提供了一些其他与存储相关的命令行标志,可用于进一步微调和保护系统。
基数限制器:
-
-storage.maxHourlySeries 和-storage.maxDailySeries: 这两个标志用于限制每小时和每天可以创建的新时间序列的最大数量 12。它们可以作为防止基数失控导致系统崩溃的“安全阀”。如果达到这些限制,新的时间序列将不会被创建,相关数据点也可能被丢弃。 这些限制器并非解决高基数问题的根本方法,而是作为一种保护机制。如果频繁触及这些限制,表明系统存在严重的基数或流失率问题,需要从源头(如应用埋点、vmagent relabeling)进行治理,而不是仅仅依赖这些限制或不断调高其阈值,后者可能导致重要数据丢失。
-
**禁用按天索引 (**
-disablePerDayIndex ) :- 从 VictoriaMetrics v1.112.0 版本开始,对于流失率极低或为零的工作负载(例如,某些物联网场景,设备ID固定,标签集稳定),可以通过设置
-disablePerDayIndex 标志来禁用按天创建的索引部分 13。 - 这可以显著减少
indexdb 的磁盘占用和相关的资源消耗,因为系统不再需要为每个日期维护独立的索引结构。然而,此选项仅适用于流失率确实很低的特定场景,对于常规监控场景(如 Kubernetes 环境,Pod 频繁启停导致标签变化),禁用按天索引可能会对查询性能产生负面影响。
- 从 VictoriaMetrics v1.112.0 版本开始,对于流失率极低或为零的工作负载(例如,某些物联网场景,设备ID固定,标签集稳定),可以通过设置
确保足够的可用磁盘空间:
-
vmstorage 需要足够的可用磁盘空间(官方建议至少保留 20% 的自由空间)才能高效运行,特别是执行后台合并、数据压缩和应用保留策略等操作 8。 -
-storage.minFreeDiskSpaceBytes (默认为 10MB): 如果vmstorage 检测到可用磁盘空间低于此阈值,它可能会切换到只读模式,拒绝新的数据写入,以保护现有数据和防止磁盘完全耗尽 3。 - 监控磁盘可用空间并设置告警是运维的基本要求。磁盘空间不足会直接阻碍所有基于合并的优化策略(如去重、降采样、空间回收)的执行。
-
这些高级配置选项提供了更细致的控制能力,但使用时需要充分理解其含义和潜在影响,并结合具体的业务场景和数据特征进行调整。
6. 容量规划与长期管理
有效的磁盘空间优化不仅仅是配置调整,更是一个涉及容量规划、持续监控和架构选择的长期管理过程。
6.1 估算存储需求
准确预测存储需求对于资源规划和成本控制至关重要。影响 VictoriaMetrics 存储需求的因素主要包括 11:
- 数据注入率 (Ingestion Rate) : 每秒写入的数据点数量。
- 活跃时间序列数 (Active Time Series) : 系统中唯一的指标和标签组合的数量,即基数。
- 数据保留期 (Retention Period) : 数据在系统中存储的时长。
- 副本因子 (Replication Factor) : 在集群模式下,数据被复制的份数。
- 数据流失率 (Churn Rate) : 新时间序列取代旧时间序列的速率。
估算方法:
- 基于样本大小的估算: VictoriaMetrics 经过压缩后,每个数据点(样本)通常占用大约 1 字节的空间 11。一个基础的估算公式可以是: 总磁盘空间 (GB) ≈ (
(字节/样本 * 样本/秒 * 副本因子 * 保留期秒数) * (1 + 开销百分比)) / 230例如,一个每秒产生 5000 个时间序列,保留期为1年,副本因子为2的环境,考虑 20% 的额外开销(用于索引、临时空间等),估算如下:(1 byte/sample * 5000 series/sec * 2 RF * 31536000 seconds/year) * 1.2 / (1024^3) \approx 372 GB (注意:11 中示例用34128000 秒,这里用标准年秒数,结果略有差异) -
indexdb 空间:indexdb 的大小通常占数据存储空间的 20% 左右。但在高基数或高流失率的情况下,indexdb 的占比可能超过 50% 11。 - 资源规划公式: 一些文档提供了基于注入率为
vminsert 和vmstorage 组件估算 CPU、内存和带宽的公式 19。虽然这些公式不直接计算磁盘空间,但更高的注入率和更长的保留期自然意味着更快的磁盘填充速度。
这些估算方法提供了一个初始的参考点。然而,实际的磁盘使用量会因数据的具体特征(如可压缩性、标签分布)而有很大差异。因此,在实际部署后,持续监控真实的磁盘使用情况,并根据观察到的趋势进行调整,是更为可靠的做法。可以先从小规模部署开始,观察一段时间的资源消耗情况,然后据此推断更大规模部署的需求 11。
6.2 定期审计指标和基数
防止“数据沼泽”的形成,确保存储资源被用于真正有价值的数据,需要定期对监控指标和数据基数进行审计。
- 清理未使用或冗余的标签和指标: 定期审查当前收集的指标,识别那些不再被查询、不再关联到任何仪表盘或告警规则的指标,并考虑停止采集或设置更短的保留期 15。VictoriaMetrics 据称可以显示每个指标名称被查询的次数,这有助于识别不常用的指标 10。
- 跟踪时间序列增长: 监控唯一时间序列的总数及其增长趋势。设置告警,以便在基数出现异常飙升时能够及时发现并介入调查 15。
- 标准化命名约定: 建立并执行一致的指标和标签命名约定,可以防止因命名混乱导致的数据重复和管理困难 15。
这种主动的“数据整理”不仅能节省磁盘空间,还能提高查询效率,简化监控系统的维护。
6.3 可扩展性和磁盘管理的架构考量
选择合适的 VictoriaMetrics 部署架构对长期的可扩展性和磁盘管理有深远影响。
单节点 vs. 集群:
- 对于注入率低于每秒一百万数据点的场景,单节点 VictoriaMetrics 通常是更简单、更高效的选择,因为它避免了集群组件间的网络通信开销,并且易于管理 2。单节点通过垂直扩展(增加 CPU、内存、磁盘)来提升容量。
- 当注入率非常高,或者需要更高的可用性和水平扩展能力时,应选择集群版本。
运行多个小型
vmstorage 节点: 在 VictoriaMetrics 集群中,推荐运行多个小型vmstorage 节点,而不是少数几个大型节点 11。这样做的好处是:- 故障影响降低: 当某个
vmstorage 节点临时不可用时,其余节点需要承担的额外负载增量较小。 - 稳定性提升: 整体集群的稳定性更高。
- 官方建议
vmstorage 节点的最佳数量通常在 10 到 50 个之间,每个节点至少分配 2 个 vCPU 11。 这种架构选择对磁盘空间管理也带来了间接影响。虽然每个小型vmstorage 节点独立管理其数据和保留策略 2,并且“整个部件保留”规则 5 意味着每个节点都可能存在少量比保留期更旧的数据,但这种分布式存储使得单个节点的磁盘管理更为聚焦。然而,这也要求在所有节点上保持配置(如保留期、降采样规则)的一致性,否则可能导致磁盘使用不均或数据保留不一致的问题,因此需要强大的自动化配置管理。
- 故障影响降低: 当某个
vmstorage 节点的伸缩:- 增加节点: 向集群中添加
vmstorage 节点(水平扩展)是一个相对直接的过程,可以有效提升系统的总存储容量和处理能力 11。 - 减少节点: 减少
vmstorage 节点的数量是一个非常复杂的过程,应尽量避免 11。这是因为 VictoriaMetrics 集群中的数据是基于一致性哈希分片到各个vmstorage 节点的 2。移除一个节点意味着其上存储的数据需要被重新分配到剩余的节点上,这个过程涉及到大量的数据迁移和潜在的性能影响。这一特性提示我们在进行容量规划时,应倾向于从一个合理的、能满足当前和近期增长需求的节点数量开始,然后根据需要逐步增加,而不是过度配置后又试图缩减。这对于长期的成本控制和运维复杂度管理具有重要意义。
- 增加节点: 向集群中添加
6.4 资源分配
为 VictoriaMetrics 组件分配合理的计算资源(CPU、内存)是确保其高效运行,包括执行后台磁盘优化任务(如合并、压缩)的基础。
- 预留资源: 建议为 VictoriaMetrics 组件预留至少 50% 的空闲 CPU 和 50% 的空闲内存,以应对工作负载的突发高峰,并确保后台任务有足够的资源执行 8。
-
vmstorage 资源:vmstorage 节点尤其需要足够的 CPU 和内存来执行数据合并、去重、降采样以及索引更新等操作。如果这些节点资源受限,后台优化任务可能会延迟或运行缓慢,导致数据在磁盘上以次优状态存储(例如,大量未合并的小部件),从而间接增加磁盘占用并降低查询性能。 -
vmselect 和 vminsert 资源:vmselect 的性能(特别是处理复杂查询或大量时间序列的查询)可以通过增加 CPU 和内存来提升(垂直扩展),或者通过增加副本数来提高查询并发能力(水平扩展)19。vminsert 也可以通过增加副本数来提高注入能力 20。
充足的资源分配是 VictoriaMetrics 实现其高性能和高效率磁盘管理的前提。一个资源不足的系统,即使配置了所有优化选项,也可能因为无法有效执行这些优化操作而达不到预期的磁盘空间节省效果。
7. 结论与关键要点
优化 VictoriaMetrics 的磁盘空间占用是一个系统性的工程,涉及到对其存储架构的深入理解、持续的监控与诊断,以及在数据生命周期的各个阶段采取恰当的策略。
主要优化手段回顾:
本报告详细阐述了多种优化磁盘空间的有效手段。其中,管理数据基数和流失率是基础,对 indexdb 大小和整体性能有深远影响。通过在 vmagent 端进行标签重写和过滤,以及在应用层面规范指标设计,可以从源头上控制这两个关键因素。核心配置层面,合理设置数据保留策略 (-retentionPeriod) 是控制数据总量的首要步骤。结合使用数据去重 (-dedup.minScrapeInterval) 和降采样 (-downsampling.period),可以进一步显著减少存储在磁盘上的数据量,特别是对于存在冗余采集或需要长期保留历史趋势数据的场景。此外,审慎使用数据删除 API 并在必要时强制合并,以及利用基数限制器等高级配置,为特定场景下的空间管理提供了额外工具。
整体性方法:
实现最佳的磁盘空间效率,并非依赖单一的“银弹”配置,而是需要采取一种多层次、主动的整体性方法。优化应始于数据产生之前(例如,通过规范的应用埋点和指标设计),贯穿数据采集和预处理阶段(例如,在 vmagent 进行过滤和重标签),并延伸至 vmstorage 的核心存储配置(保留、去重、降采样)。相较于数据存储后进行清理等被动措施,这种预防性的、前置的优化策略通常更为高效,风险也更低。例如,在 vmagent 层面阻止不需要的高基数数据进入存储系统,远比数据写入后再通过 API 删除并等待合并来回收空间要经济和简单。
VictoriaMetrics 的优势与用户职责:
VictoriaMetrics 本身在设计上就具备出色的存储效率,例如其高效的数据压缩算法使其相较于 Prometheus 等其他方案能用更少的磁盘空间存储相同的数据量 9。它提供了丰富的配置选项和诊断工具,赋予用户强大的控制能力。然而,这种控制能力也意味着用户需要承担起相应的职责:深入理解这些工具和配置的含义、工作原理及其潜在影响,并根据自身具体的工作负载、数据特性和业务需求进行明智的选择和调整。默认配置可能并非适用于所有场景,例如数据去重默认关闭,保留期也需要用户根据实际情况设定。系统提供了机制,但最终的优化效果高度依赖于用户的实践和管理。
持续改进的呼吁:
磁盘空间优化不是一次性的任务,而是一个持续监控、评估和调整的过程。随着业务的发展、数据量的增长以及查询模式的变化,原先的优化策略可能不再适用。因此,强烈建议用户定期回顾其 VictoriaMetrics 的部署配置,审计指标的实际使用情况和基数变化,并根据最新的观察和需求,不断迭代和完善其磁盘空间优化策略。通过这种持续改进的实践,才能最大限度地发挥 VictoriaMetrics 的效能,实现监控数据存储的长期成本效益和系统稳定性。