【VictoriaMetrics】vm单机版和vm-storage的查询功能的对比


1.vm-storage源码调用表

文件 行号 函数 说明
app/vmstorage/main.go 53 main 入口
94行调用srv.RunVMSelect()
app/vmstorage/transport/server.go 151 func (s *Server) RunVMSelect() 启动vm-select的服务器端
208行调用s.processVMSelectConn(bc)
app/vmstorage/transport/server.go 269 func (s *Server) processVMSelectConn 275行调用s.processVMSelectRequest(ctx)
app/vmstorage/transport/server.go 467 func (s *Server) processVMSelectRequest 处理存储相关的各个命令
498行调用s.processVMSelectSearch(ctx)
app/vmstorage/transport/server.go 1037 func (s *Server) processVMSelectSearch 从存储引擎读取数据

2.vm单机版的源码

文件 行号 函数 说明
app/victoria-metrics/main.go 33 main 入口
app/victoria-metrics/main.go 84 requestHandler http处理函数
108行调用vmselect.RequestHandler
app/vmselect/main.go 87 RequestHandler 查询请求入口
220行调用prometheus.QueryRangeHandler
app/vmselect/prometheus/prometheus.go 1088 QueryRangeHandler /api/v1/query_range 入口
1112行调用queryRangeHandler
app/vmselect/prometheus/prometheus.go 1118 queryRangeHandler queryRangeHandler
1151行调用promql.Exec
app/vmselect/promql/exec.go 29 Exec 执行查询
43行调用evalExpr
app/vmselect/promql/eval.go 186 evalExpr 191行调用evalRollupFunc
app/vmselect/promql/eval.go 482 evalRollupFunc 509行调用evalRollupFuncWithMetricExpr
app/vmselect/promql/eval.go 646 evalRollupFuncWithMetricExpr 684行调用netstorage.ProcessSearchQuery
截止这个函数,VM单机版和群集版的vm-select几乎是一致的。
app/vmselect/netstorage/netstorage.go 1009 ProcessSearchQuery 执行ql查询语言。从存储引擎读取数据

3.结论

  • 证实了我的猜想:
    • vm单机版和vm集群版,在查询上,本质的不同就是进程内处理数据和进程间处理数据的差别。
    • vm单机版中,解析完promql后,直接通过存储引擎的接口拉取数据,然后进行计算。(逻辑上并未看见因为存储引擎就在本机而做的特殊优化)
    • VM群集版中:
      • vm-select负责解析promql,然后转换成range_query的参数
      • vm-select通过网络协议请求vm-storage
      • vm-storage查询到time series和data point后,返回给vm-select(数据极度精简,且经过ZTD算法压缩)
      • vm-select从多个vm-storage收到数据后,进行去重、计算、输出JSON
  • vm单机版从理论上比vm群集版节约了这些步骤:
    • vm-select到vm-storage的网络通讯可以省掉
    • vm-storage向vm-select返回数据的ZSTD压缩可以省掉
    • 不必访问多个vm-storage,因此vm-select的响应时间等于最慢的那个vm-storage。单机版中没有这个等待。
    • 数据量很大的情况下,上述的节省也是非常可观的。
  • 我认为vm单机版的优化还是不够:
    • 如果存储节点在本地,起码可以做边捞取数据边汇总,这样查询时候的内存占用就会减小很多。(但这样也不会节约计算时间)
    • 最好增加recording rules的能力,通过预计算提升查询性能