Architecture
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.
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.
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/!