按规模进行时间序列索引 - Artem Krylysov

主要观点:Datadog 每分钟收集数十亿事件,数据量增长迅速,用户查询类型也发生显著变化,给时间序列数据存储带来压力。介绍了指标平台的架构及各组件,包括摄入、存储和查询,原始索引服务依赖自动生成索引,虽空间高效但对用户查询表现不佳,需手动干预;下一代索引服务受搜索引擎倒排索引启发,无条件索引每个摄入的标签,简化了摄入和查询路径,虽有写放大问题但性能提升,还通过节点内分片实现查询路径随 CPU 核心扩展,将 Go 服务改为 Rust 使 CPU 密集型操作速度提升。

关键信息

  • 指标平台架构:摄入数据到消息队列,存储到时间序列数据库和索引服务,查询时连接各组件。
  • 原始索引服务:基于查询日志自动生成索引,使用 SQLite 和 RocksDB,存在全表扫描和查询模式变化导致索引低效等问题。
  • 下一代索引服务:受搜索引擎倒排索引启发,无条件索引每个摄入标签,简化路径,减少 CPU 消耗,通过节点内分片实现查询并行,将 Go 改为 Rust 提升性能。
  • 结论:改变索引策略、节点内分片和语言改为 Rust 使查询性能提升,减少查询超时和运行成本。

重要细节

  • 摄入数据包含度量名称、标签、时间戳和值,标签可添加维度用于过滤等操作。
  • 原始索引服务中,Tagsets 数据库存储时间序列 ID 与标签的映射,Metrics 数据库存储时间序列 ID 与度量的映射,Indexes 数据库存储资源消耗查询的索引。
  • 下一代索引服务中,索引数据库无条件索引每个摄入的标签,查询时通过单键值查找获取相关时间序列 ID 并组合。
  • 节点内分片通过哈希时间序列 ID 将 RocksDB 索引分为多个隔离实例,并行获取数据并合并结果。
  • Rust 在分组和合并操作上比 Go 快约 3 倍,Go 通过手动复制容器/堆包可优化但仍比 Rust 慢约 2 倍。
阅读 9
0 条评论