VictoriaMetrics 中文教程(08)VictoriaMetrics 的存储
VictoriaMetrics 中文教程系列文章:
- VictoriaMetrics 中文教程(01)简介
- VictoriaMetrics 中文教程(02)安装
- VictoriaMetrics 中文教程(03)如何配置 Prometheus 使其把数据远程写入 VictoriaMetrics
- VictoriaMetrics 中文教程(04)对接 Grafana 同时介绍 vmui
- VictoriaMetrics 中文教程(05)对接各类监控数据采集器
- VictoriaMetrics 中文教程(06)容量规划
- VictoriaMetrics 中文教程(07)高可用(High availability)方案
VictoriaMetrics 的存储
VictoriaMetrics 将摄取的数据在内存中缓冲长达一秒钟。然后将缓冲的数据写入内存 parts
,可以在查询期间搜索。内存中的 parts
会定期保存到磁盘,因此它们可以承受非正常关机,例如内存不足崩溃、硬件电源丢失或 SIGKILL 信号。可以使用 -inmemoryDataFlushInterval
命令行标志配置将内存数据刷新到磁盘的间隔(请注意,刷新间隔太短可能会显著增加磁盘 IO)。
内存中的 parts
被持久化到 <-storageDataPath>/data/Small/YYYY_MM/
文件夹下,其中 YYYY_MM
是存储数据的月份分区。例如,2022_11
是从 2022 年 11 月开始的带有原始样本的 parts
的分区。每个分区目录都包含 parts.json
文件,改文件中存储了所有的 parts
目录。
每个 part
目录都包含具有以下字段的 metadata.json 文件:
- RowsCount - 该
part
中存储的原始样本数量 - BlocksCount - 存储在该
part
中的块数(请参阅下面有关块的详细信息) - MinTimestamp 和 MaxTimestamp - 存储在该
part
中的原始样本的最小和最大时间戳 - MinDedupInterval - 应用于给定
part
的重复数据删除间隔
每个 part
由按 time series ID(又称 TSID)排序的块组成。每个块包含最多 8K 个原始样本,这些样本属于单个时间序列。每个块中的原始样本按时间戳排序。同一时间序列的块按第一个样本的时间戳排序。所有块的 imestamps 和值都以压缩形式存储在 part
目录下的单独文件中 - timestamps.bin 和 values.bin。
part
目录还包含 index.bin 和 metaindex.bin 文件 - 这些文件包含用于快速块查找的索引,属于给定的 TSID 并覆盖给定的时间范围。
part
会定期在后台合并为更大的 part
。后台合并具有以下优势:
- 控制数据文件数量,使其不超过打开文件的限制
- 提高数据压缩率,因为较大的
part
通常比较小的part
压缩得更好 - 提高查询速度,因为对较少数量的
part
的查询执行速度更快 - 合并期间会执行各种后台维护任务,例如重复数据删除、降采样以及为已删除的时间序列释放磁盘空间
新添加的 part
有可能会成功出现在存储中,有可能会失败。新添加的 part
在完全写入并 fsync 到存储后,将原子地注册到相应分区下的 parts.json 文件中。由于这种算法,存储永远不会包含部分创建的 part
,即使在将 part
写入磁盘的过程中发生硬件断电 - 这些未完整写入的 part
会在下次 VictoriaMetrics 启动时自动删除。
合并过程也是如此 - part
要么完全合并成一个新 part
,要么合并失败,源部分保持不变。然而,由于硬件问题,无论 VictoriaMetrics 流程如何,磁盘上的数据都可能损坏。VictoriaMetrics 可以在数据块解压缩、解码或健全性检查期间检测损坏情况。但它无法修复损坏的数据。启动时无法加载的数据部分需要删除或从备份中恢复。这就是为什么建议定期进行备份。
VictoriaMetrics 不对存储的数据块使用校验和。原因参考这里。
如果各部分的摘要大小超出可用磁盘空间,VictoriaMetrics 不会合并这些部分。这可以防止合并过程中出现潜在的磁盘空间不足错误。在可用磁盘空间不足的情况下,part
数量可能会随着时间的推移而显着增加。这会增加数据查询期间的开销,因为 VictoriaMetrics 每次请求都需要从更多 part
读取数据。这就是为什么建议在 -storageDataPath
命令行标志指向的目录下至少有 20% 的可用磁盘空间。
可以从下面两个仪表盘中查看存储的 merge 过程的信息:
索引库
VictoriaMetrics 通过 TSID(时间序列 ID)识别时间序列,并按 TSID 排序存储原始样本(参见存储)。因此,TSID 是主索引,可用于搜索和检索原始样本。但是,TSID 永远不会暴露给客户端,即仅供内部使用。
相反,VictoriaMetrics 维护一个倒排索引,通过将这些值映射到相应的 TSID,可以按指标名称、标签名称和标签值搜索原始样本。
VictoriaMetrics 使用两种类型的倒排索引:
- 全局索引。使用此索引的搜索将在整个保留期内执行。
- 按日索引。此索引存储与全局索引类似的映射,但每个映射中还包括日期。这加快了较短时间范围内查询(通常只是最后一天)的数据检索速度。
当执行搜索查询时,VictoriaMetrics 会根据查询的时间范围决定使用哪个索引:
- 如果搜索时间范围为 40 天或更短,则使用每日索引。
- 全局索引用于时间范围大于 40 天的搜索查询。
在数据摄取期间将映射添加到索引:
- 在全局索引中,每个映射每个保留期仅创建一次。
- 按天的索引,则是每天创建一次。只要对应的某个日期里出现了相关的时序数据,这些时序数据的索引就会被添加到这个日期的索引中。
IndexDB 尊重保留期,一旦保留期结束,索引就会被删除。对于新的保留期,随着新样本的到来,索引会逐渐再次填充。
VictoriaMetrics 的数据保留
保留期使用 -retentionPeriod
命令行标志配置,该标志采用数字后跟时间单位字符 - h(小时)、d(天)、w(周)、y(年)。如果未指定时间单位,则假定为一个月(31 天)。例如,-retentionPeriod=3
表示数据将存储 3 个月(93 天),然后删除。默认保留期为一个月。最短保留期为 24 小时或 1 天。
数据按月划分在 <-storageDataPath>/data/{small,big}
文件夹内。配置保留期之外的数据分区将在新月的第一天删除。每个分区由一个或多个数据 part
组成。配置的保留期之外的数据 part
最终会在后台合并期间被删除。数据 part
所涵盖的时间范围不受保留期单位限制。一个数据 part
可以涵盖数小时或数天的数据。因此,只有完全超出配置的保留期时,才能删除数据 part
。
给定 -retentionPeriod
的最大磁盘空间使用量为 (-retentionPeriod
+ 1) 个月。例如,如果 -retentionPeriod
设置为 1,则 1 月份的数据将在 3 月 1 日删除。延长现有数据的 -retentionPeriod
是安全的。如果将 -retentionPeriod
设置为比以前更低的值,则配置期限之外的数据最终将被删除。
VictoriaMetrics 不支持无限期保留,但您可以指定任意长的保留期限,例如 -retentionPeriod=100y
。
如果我想让不同的数据不同的保留期,该怎么办?有两个办法:
- 使用商业版,商业版支持在一个实例上配置不同的时序数据不同的保留期。
- 开源版的话,使用多个 VictoriaMetrics 实例,每个实例配置不同的保留期。然后在前面使用 vmauth 做代理。
总结
本文介绍了 VictoriaMetrics 的存储机制,包括内存中的 parts
、磁盘上的 parts
、块、索引库、数据保留等。这些都是 VictoriaMetrics 的核心功能,对于用户来说,了解这些机制有助于更好地使用 VictoriaMetrics。