M3 Query, a stateless query server for M3DB and Prometheus

Overview

M3 Query and M3 Coordinator are written entirely in Go, M3 Query is as a query engine for M3DB and M3 Coordinator is a remote read/write endpoint for Prometheus and M3DB. To learn more about Prometheus’s remote endpoints and storage, see here. M3 Query is a service that exposes all metrics query endpoints along with metrics time series metadata APIs that return dimensions and labels of metrics that reside in a M3DB cluster.
Read more arrow-right-circle

Blocks

Please note: This documentation is a work in progress and more detail is required. Overview The fundamental data structures that M3 Query uses are Blocks. Blocks are what get created from the series iterators that M3DB returns. A Block is associated with a start and end time. It contains data from multiple time series stored in columnar format. Most transformations within M3 Query will be applied across different series for each time interval.
Read more arrow-right-circle

Fetching and querying

Fetch fanout Since m3query does not currently have a view into the M3DB index, fanout to multiple clusters is rather complicated. Since not every metric is necessarily in every cluster (as an example, carbon metrics routed to a certain resolution), it is not trivial to determine which namespaces should be queried to return a fully correct set of recorded metrics. The general approach is therefore to attempt to fanout to any namespace which has a complete view of all metrics, for example, Unaggregated, and take that if it fulfills the query range; if not, m3query will attempt to stitch together namespaces with longer retentions to try and build the most complete possible view of stored metrics.
Read more arrow-right-circle

Function Processing

Supported Functions M3QL Prometheus Graphite abs/absolute abs() absolute(seriesList) alias [alias] alias(seriesList, newName) aliasByTags [tag] aliasByTags(seriesList, *tags) aliasByBucket/aliasByHistogramBucket [tag] anomalies [flags] asPercent / asPercent(seriesList, total=None, *nodes) avg/averageSeries [tag] avg() averageSeries(*seriesLists) changed changed(seriesList) constantLine [value] constantLine(value) count count() countSeries(*seriesLists) derivative derivative(seriesList) diff - diffSeries(*seriesLists) divideSeries / divideSeries(dividendSeriesList, divisorSeries) eq/== [value] == removeBelowValue(seriesList, n)/removeAboveValue(seriesList, n) ne/!
Read more arrow-right-circle