Update WAL doc to include native histogram encodings

This commit is contained in:
Carrie Edwards 2024-11-26 11:14:09 -08:00
parent 6684344026
commit f8a39767a4
3 changed files with 192 additions and 30 deletions

View file

@ -79,32 +79,6 @@ The first sample record begins at the second row.
└──────────────────────────────────────────────────────────────────┘
```
### Native histogram records
Native histogram records are encoded as
```
┌──────────────────────────────────────────────────────────────────┐
│ type = 2 <1b>
├──────────────────────────────────────────────────────────────────┤
│ ┌────────────────────┬───────────────────────────┐ │
│ │ id <8b> │ timestamp <8b> │ │
│ └────────────────────┴───────────────────────────┘ │
│ ┌────────────────────┬───────────────────────────┬ │
│ │ id_delta <uvarint> │ timestamp_delta <uvarint> │ │
│ ├────────────────────┴───────────────────────────┴─────────────┤ │
│ │ n = len(labels) <uvarint> │ │
│ ├──────────────────────┬───────────────────────────────────────┤ │
│ │ len(str_1) <uvarint> │ str_1 <bytes> │ │
│ ├──────────────────────┴───────────────────────────────────────┤ │
│ │ ... │ │
│ ├───────────────────────┬──────────────────────────────────────┤ │
│ │ len(str_2n) <uvarint> │ str_2n <bytes> │ │ │
│ └───────────────────────┴────────────────┴─────────────────────┘ │
│ . . . │
└──────────────────────────────────────────────────────────────────┘
```
### Tombstone records
Tombstone records encode tombstones as a list of triples `(series_id, min_time, max_time)`
@ -182,3 +156,193 @@ Metadata records encode the metadata updates associated with a series.
└────────────────────────────────────────────┘
```
### Native histogram records
Native histogram records are encoded as a list of histogram samples.
Series reference and timestamp are encoded as deltas w.r.t the first histogram sample.
The first row stores the starting id and the starting timestamp.
The first native histogram sample record begins at the second row.
There are several different types of native histogram samples.
Integer histogram encoding:
```
┌──────────────────────────────────────────────────────────────────┐
│ type = 9 <1b>
├──────────────────────────────────────────────────────────────────┤
│ ┌────────────────────┬───────────────────────────┐ │
│ │ id <8b> │ timestamp <8b> │ │
│ └────────────────────┴───────────────────────────┘ │
│ ┌────────────────────┬───────────────────────────┬ │
│ │ id_delta <uvarint> │ timestamp_delta <uvarint> │ │
│ ├────────────────────┴────┬──────────────────────┤ │
│ │ counter_reset_hint <8b> │ schema <uvarint> │ │
│ ├──────────────────────┬──┴──────────────────────┤ │
│ │ zero_threshold <8b> │ zero_count <uvarint> │ │
│ ├──────────────────────┴┬────────────────────────┤ │
│ │ count <uvarint> │ sum <uvariant> │ │
│ ├───────────────────────┴────────┬───────────────┴─────────────┐ │
│ │ len(positive_spans) <uvarint> │ offset <uvarint> │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ │ length <uvarint> │ │
│ │ ├─────────────────────────────┤ │
│ │ │ . . . │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ len(negative_spans) <uvarint> │ offset <uvarint> │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ │ length <uvarint> │ │
│ │ ├─────────────────────────────┤ │
│ │ │ . . . │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ len(positive_buckets) <uvarint>│ bucket_count <uvarint> │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ │ . . . │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ len(negative_buckets) <uvarint>│ bucket_count <uvarint> │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ │ . . . │ │
│ └────────────────────────────────┴─────────────────────────────┘ │
│ . . . │
└──────────────────────────────────────────────────────────────────┘
```
There are also integer histograms that have custom buckets, which will always
have a schem of 053. Custom bucket native histograms additionally encode
a field that specifies the custom values:
```
┌──────────────────────────────────────────────────────────────────┐
│ type = 9 <1b>
├──────────────────────────────────────────────────────────────────┤
│ ┌────────────────────┬───────────────────────────┐ │
│ │ id <8b> │ timestamp <8b> │ │
│ └────────────────────┴───────────────────────────┘ │
│ ┌────────────────────┬───────────────────────────┬ │
│ │ id_delta <uvarint> │ timestamp_delta <uvarint> │ │
│ ├────────────────────┴────┬──────────────────────┤ │
│ │ counter_reset_hint <8b> │ schema <uvarint> │ │
│ ├──────────────────────┬──┴──────────────────────┤ │
│ │ zero_threshold <8b> │ zero_count <uvarint> │ │
│ ├──────────────────────┴┬────────────────────────┤ │
│ │ count <uvarint> │ sum <uvariant> │ │
│ ├───────────────────────┴────────┬───────────────┴─────────────┐ │
│ │ len(positive_spans) <uvarint> │ offset <uvarint> │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ │ length <uvarint> │ │
│ │ ├─────────────────────────────┤ │
│ │ │ . . . │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ len(negative_spans) <uvarint> │ offset <uvarint> │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ │ length <uvarint> │ │
│ │ ├─────────────────────────────┤ │
│ │ │ . . . │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ len(positive_buckets) <uvarint>│ bucket_count <uvarint> │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ │ . . . │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ len(negative_buckets) <uvarint>│ bucket_count <uvarint> │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ │ . . . │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ len(custom_values) <uvarint> │ value <8b> │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ │ . . . │ │
│ └────────────────────────────────┴─────────────────────────────┘ │
│ . . . │
└──────────────────────────────────────────────────────────────────┘
```
(Note: negative spans and negative buckets will be empty for custom bucket native histograms.)
Float histogram encoding:
```
┌──────────────────────────────────────────────────────────────────┐
│ type = 10 <1b>
├──────────────────────────────────────────────────────────────────┤
│ ┌────────────────────┬───────────────────────────┐ │
│ │ id <8b> │ timestamp <8b> │ │
│ └────────────────────┴───────────────────────────┘ │
│ ┌────────────────────┬───────────────────────────┐ │
│ │ id_delta <uvarint> │ timestamp_delta <uvarint> │ │
│ ├────────────────────┴────┬──────────────────────┤ │
│ │ counter_reset_hint <8b> │ schema <uvarint> │ │
│ ├──────────────────────┬──┴──────────────────────┤ │
│ │ zero_threshold <8b> │ zero_count <8b> │ │
│ ├──────────────────────┴┬────────────────────────┤ │
│ │ count <8b> │ sum <8b> │ │
│ ├───────────────────────┴────────┬───────────────┴─────────────┐ │
│ │ len(positive_spans) <uvarint> │ offset <uvarint> │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ │ length <uvarint> │ │
│ │ ├─────────────────────────────┤ │
│ │ │ . . . │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ len(negative_spans) <uvarint> │ offset <uvarint> │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ │ length <uvarint> │ │
│ │ ├─────────────────────────────┤ │
│ │ │ . . . │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ len(positive_buckets) <uvarint>│ bucket_count <8b> │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ │ . . . │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ len(negative_buckets) <uvarint>│ bucket_count <8b> │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ │ . . . │ │
│ └────────────────────────────────┴─────────────────────────────┘ │
│ . . . │
└──────────────────────────────────────────────────────────────────┘
```
There are also float histograms with custom buckets.
```
┌──────────────────────────────────────────────────────────────────┐
│ type = 10 <1b>
├──────────────────────────────────────────────────────────────────┤
│ ┌────────────────────┬───────────────────────────┐ │
│ │ id <8b> │ timestamp <8b> │ │
│ └────────────────────┴───────────────────────────┘ │
│ ┌────────────────────┬───────────────────────────┐ │
│ │ id_delta <uvarint> │ timestamp_delta <uvarint> │ │
│ ├────────────────────┴────┬──────────────────────┤ │
│ │ counter_reset_hint <8b> │ schema <uvarint> │ │
│ ├──────────────────────┬──┴──────────────────────┤ │
│ │ zero_threshold <8b> │ zero_count <8b> │ │
│ ├──────────────────────┴┬────────────────────────┤ │
│ │ count <8b> │ sum <8b> │ │
│ ├───────────────────────┴────────┬───────────────┴─────────────┐ │
│ │ len(positive_spans) <uvarint> │ offset <uvarint> │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ │ length <uvarint> │ │
│ │ ├─────────────────────────────┤ │
│ │ │ . . . │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ len(negative_spans) <uvarint> │ offset <uvarint> │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ │ length <uvarint> │ │
│ │ ├─────────────────────────────┤ │
│ │ │ . . . │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ len(positive_buckets) <uvarint>│ bucket_count <8b> │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ │ . . . │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ len(negative_buckets) <uvarint>│ bucket_count <8b> │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ │ . . . │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ len(custom_values) <uvarint> │ value <8b> │ │
│ ├────────────────────────────────┼─────────────────────────────┤ │
│ │ │ . . . │ │
│ └────────────────────────────────┴─────────────────────────────┘ │
│ . . . │
└──────────────────────────────────────────────────────────────────┘
```
(Note: negative spans and negative buckets will also be empty for custom bucket float native histograms.)

View file

@ -691,6 +691,7 @@ func (a *headAppender) AppendHistogram(ref storage.SeriesRef, lset labels.Labels
if created && s.lastHistogramValue == nil && s.lastFloatHistogramValue == nil {
s.lastHistogramValue = &histogram.Histogram{}
}
// TODO(codesome): If we definitely know at this point that the sample is ooo, then optimise
// to skip that sample from the WAL and write only in the WBL.
_, delta, err := s.appendableHistogram(t, h, a.headMaxt, a.minValidTime, a.oooTimeWindow, a.head.opts.EnableOOONativeHistograms.Load())

View file

@ -58,7 +58,6 @@ func (h *Head) loadWAL(r *wlog.Reader, syms *labels.SymbolTable, multiRef map[ch
var unknownExemplarRefs atomic.Uint64
var unknownHistogramRefs atomic.Uint64
var unknownMetadataRefs atomic.Uint64
// Track number of series records that had overlapping m-map chunks.
var mmapOverlappingChunks atomic.Uint64
@ -139,8 +138,7 @@ func (h *Head) loadWAL(r *wlog.Reader, syms *labels.SymbolTable, multiRef map[ch
dec := record.NewDecoder(syms)
for r.Next() {
rec := r.Record()
recType := dec.Type(rec)
switch recType {
switch dec.Type(rec) {
case record.Series:
series := seriesPool.Get()[:0]
series, err = dec.Series(rec, series)
@ -618,7 +616,6 @@ func (wp *walSubsetProcessor) processWALSamples(h *Head, mmappedChunks, oooMmapp
if s.t <= ms.mmMaxTime {
continue
}
var chunkCreated bool
if s.h != nil {
_, chunkCreated = ms.appendHistogram(s.t, s.h, 0, appendChunkOpts)