Skip to content

Commit 4b89cd5

Browse files
committed
Add hash collision detection
Signed-off-by: György Krajcsovits <[email protected]>
1 parent b008f23 commit 4b89cd5

File tree

1 file changed

+33
-6
lines changed

1 file changed

+33
-6
lines changed

storage/remote/otlptranslator/prometheusremotewrite/combined_appender.go

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ func NewCombinedAppender(app storage.Appender, logger *slog.Logger, reg promethe
4848
app: app,
4949
logger: logger,
5050
ingestCTZeroSample: ingestCTZeroSample,
51-
refs: make(map[uint64]storage.SeriesRef),
51+
refs: make(map[uint64]labelsRef),
5252
samplesAppendedWithoutMetadata: promauto.With(reg).NewCounter(prometheus.CounterOpts{
5353
Namespace: "prometheus",
5454
Subsystem: "api",
@@ -64,20 +64,32 @@ func NewCombinedAppender(app storage.Appender, logger *slog.Logger, reg promethe
6464
}
6565
}
6666

67+
type labelsRef struct {
68+
ref storage.SeriesRef
69+
ls modelLabels.Labels
70+
}
71+
6772
type combinedAppender struct {
6873
app storage.Appender
6974
logger *slog.Logger
7075
samplesAppendedWithoutMetadata prometheus.Counter
7176
outOfOrderExemplars prometheus.Counter
7277
ingestCTZeroSample bool
7378
// Used to ensure we only update metadata and created timestamps once, and to share storage.SeriesRefs.
74-
refs map[uint64]storage.SeriesRef
79+
// To detect hash collision it also stores the labels.
80+
// There is no overflow/conflict list, the TSDB will handle that part.
81+
refs map[uint64]labelsRef
7582
}
7683

7784
func (b *combinedAppender) AppendSample(_ string, rawls labels.Labels, meta metadata.Metadata, t, ct int64, v float64, es []exemplar.Exemplar) (err error) {
7885
ls := modelLabels.NewFromSorted(rawls)
7986
hash := ls.Hash()
80-
ref, exists := b.refs[hash]
87+
lref, exists := b.refs[hash]
88+
ref := lref.ref
89+
if exists && !modelLabels.Equal(lref.ls, ls) {
90+
// Hash collision, this is a new series.
91+
exists = false
92+
}
8193
if !exists {
8294
ref, err = b.app.UpdateMetadata(0, ls, meta)
8395
if err != nil {
@@ -105,14 +117,24 @@ func (b *combinedAppender) AppendSample(_ string, rawls labels.Labels, meta meta
105117
}
106118
}
107119
ref = b.appendExemplars(ref, ls, es)
108-
b.refs[hash] = ref
120+
if !exists {
121+
b.refs[hash] = labelsRef{
122+
ref: ref,
123+
ls: ls,
124+
}
125+
}
109126
return
110127
}
111128

112129
func (b *combinedAppender) AppendHistogram(_ string, rawls labels.Labels, meta metadata.Metadata, t, ct int64, h *histogram.Histogram, es []exemplar.Exemplar) (err error) {
113130
ls := modelLabels.NewFromSorted(rawls)
114131
hash := ls.Hash()
115-
ref, exists := b.refs[hash]
132+
lref, exists := b.refs[hash]
133+
ref := lref.ref
134+
if exists && !modelLabels.Equal(lref.ls, ls) {
135+
// Hash collision, this is a new series.
136+
exists = false
137+
}
116138
if !exists {
117139
ref, err = b.app.UpdateMetadata(0, ls, meta)
118140
if err != nil {
@@ -140,7 +162,12 @@ func (b *combinedAppender) AppendHistogram(_ string, rawls labels.Labels, meta m
140162
}
141163
}
142164
ref = b.appendExemplars(ref, ls, es)
143-
b.refs[hash] = ref
165+
if !exists {
166+
b.refs[hash] = labelsRef{
167+
ref: ref,
168+
ls: ls,
169+
}
170+
}
144171
return
145172
}
146173

0 commit comments

Comments
 (0)