mirror of
https://github.com/prometheus/prometheus.git
synced 2026-05-28 04:02:21 -04:00
optimization: fast path float on AppenderV2
Signed-off-by: bwplotka <bwplotka@gmail.com>
This commit is contained in:
parent
5ec87d59a3
commit
f0ca5f38cf
2 changed files with 47 additions and 21 deletions
|
|
@ -357,6 +357,18 @@ const (
|
|||
stCustomBucketFloatHistogram // Native float histograms with custom bucket boundaries. Goes to `floatHistograms`.
|
||||
)
|
||||
|
||||
// TypeLabel returns a name to use for instrumentation to reflect histogram vs float operations.
|
||||
func (s sampleType) TypeLabel() string {
|
||||
switch s {
|
||||
default:
|
||||
return ""
|
||||
case stFloat:
|
||||
return sampleMetricTypeFloat
|
||||
case stHistogram, stCustomBucketHistogram, stFloatHistogram, stCustomBucketFloatHistogram:
|
||||
return sampleMetricTypeHistogram
|
||||
}
|
||||
}
|
||||
|
||||
// appendBatch is used to partition all the appended data into batches that are
|
||||
// "type clean", i.e. every series receives only samples of one type within the
|
||||
// batch. Types in this regard are defined by the sampleType enum above.
|
||||
|
|
|
|||
|
|
@ -103,31 +103,43 @@ type headAppenderV2 struct {
|
|||
headAppenderBase
|
||||
}
|
||||
|
||||
// toBasicSampleType detects sample type based on a typical multi sample Append API.
|
||||
// Basic because this does not detect some details like custom bucket histogram or native.
|
||||
// TODO: Improve with https://github.com/prometheus/prometheus/issues/17925
|
||||
func toBasicSampleType(v float64, h *histogram.Histogram, fh *histogram.FloatHistogram) sampleType {
|
||||
if v != 0 || (h == nil && fh == nil) {
|
||||
return stFloat // Fast path.
|
||||
}
|
||||
if fh != nil {
|
||||
return stFloatHistogram
|
||||
}
|
||||
return stHistogram
|
||||
}
|
||||
|
||||
func (a *headAppenderV2) Append(ref storage.SeriesRef, ls labels.Labels, st, t int64, v float64, h *histogram.Histogram, fh *histogram.FloatHistogram, opts storage.AOptions) (storage.SeriesRef, error) {
|
||||
var (
|
||||
sTyp = toBasicSampleType(v, h, fh)
|
||||
isStale bool
|
||||
// Avoid shadowing err variables for reliability.
|
||||
valErr, appErr, partialErr error
|
||||
sampleMetricType = sampleMetricTypeFloat
|
||||
isStale bool
|
||||
appErr, partialErr error
|
||||
)
|
||||
// Fail fast on incorrect histograms.
|
||||
|
||||
switch {
|
||||
case fh != nil:
|
||||
sampleMetricType = sampleMetricTypeHistogram
|
||||
valErr = fh.Validate()
|
||||
case h != nil:
|
||||
sampleMetricType = sampleMetricTypeHistogram
|
||||
valErr = h.Validate()
|
||||
}
|
||||
if valErr != nil {
|
||||
return 0, valErr
|
||||
switch sTyp {
|
||||
default:
|
||||
case stFloatHistogram:
|
||||
if err := fh.Validate(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
case stHistogram:
|
||||
if err := h.Validate(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
// Fail fast if OOO is disabled and the sample is out of bounds.
|
||||
// Otherwise, a full check will be done later to decide if the sample is in-order or out-of-order.
|
||||
if a.oooTimeWindow == 0 && t < a.minValidTime {
|
||||
a.head.metrics.outOfBoundSamples.WithLabelValues(sampleMetricType).Inc()
|
||||
a.head.metrics.outOfBoundSamples.WithLabelValues(sTyp.TypeLabel()).Inc()
|
||||
return 0, storage.ErrOutOfBounds
|
||||
}
|
||||
|
||||
|
|
@ -141,15 +153,15 @@ func (a *headAppenderV2) Append(ref storage.SeriesRef, ls labels.Labels, st, t i
|
|||
}
|
||||
|
||||
// TODO(bwplotka): Handle ST natively (as per PROM-60).
|
||||
if a.head.opts.EnableSTAsZeroSample && st != 0 {
|
||||
if st != 0 && a.head.opts.EnableSTAsZeroSample {
|
||||
a.bestEffortAppendSTZeroSample(s, ls, st, t, h, fh)
|
||||
}
|
||||
|
||||
switch {
|
||||
case fh != nil:
|
||||
switch sTyp {
|
||||
case stFloatHistogram:
|
||||
isStale = value.IsStaleNaN(fh.Sum)
|
||||
appErr = a.appendFloatHistogram(s, t, fh, opts.RejectOutOfOrder)
|
||||
case h != nil:
|
||||
case stHistogram:
|
||||
isStale = value.IsStaleNaN(h.Sum)
|
||||
appErr = a.appendHistogram(s, t, h, opts.RejectOutOfOrder)
|
||||
default:
|
||||
|
|
@ -171,6 +183,7 @@ func (a *headAppenderV2) Append(ref storage.SeriesRef, ls labels.Labels, st, t i
|
|||
return a.Append(storage.SeriesRef(s.ref), ls, st, t, 0, nil, &histogram.FloatHistogram{Sum: v}, storage.AOptions{
|
||||
RejectOutOfOrder: opts.RejectOutOfOrder,
|
||||
})
|
||||
default:
|
||||
}
|
||||
// Note that a series reference not yet in the map will come out
|
||||
// as stNone, but since we do not handle that case separately,
|
||||
|
|
@ -179,13 +192,14 @@ func (a *headAppenderV2) Append(ref storage.SeriesRef, ls labels.Labels, st, t i
|
|||
}
|
||||
appErr = a.appendFloat(s, t, v, opts.RejectOutOfOrder)
|
||||
}
|
||||
|
||||
// Handle append error, if any.
|
||||
if appErr != nil {
|
||||
switch {
|
||||
case errors.Is(appErr, storage.ErrOutOfOrderSample):
|
||||
a.head.metrics.outOfOrderSamples.WithLabelValues(sampleMetricType).Inc()
|
||||
a.head.metrics.outOfOrderSamples.WithLabelValues(sTyp.TypeLabel()).Inc()
|
||||
case errors.Is(appErr, storage.ErrTooOldSample):
|
||||
a.head.metrics.tooOldSamples.WithLabelValues(sampleMetricType).Inc()
|
||||
a.head.metrics.tooOldSamples.WithLabelValues(sTyp.TypeLabel()).Inc()
|
||||
}
|
||||
return 0, appErr
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue