Skip to content

Commit c6c3bf8

Browse files
authored
Avoid reading unnecessary dimension values when downsampling (#124451) (#124470)
Read dimension values once per tsid/bucket docid range instead of for each document being processed. The dimension value within a bucket-interval docid range is always to same and this avoids unnecessary reads. Latency of downsampling the tsdb track index into a 1 hour interval downsample index drop by ~16% (running on my local machine).
1 parent 593c706 commit c6c3bf8

File tree

2 files changed

+32
-9
lines changed

2 files changed

+32
-9
lines changed

docs/changelog/124451.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 124451
2+
summary: Improve downsample performance by avoiding to read unnecessary dimension values when downsampling.
3+
area: Downsampling
4+
type: bug
5+
issues: []

x-pack/plugin/downsample/src/main/java/org/elasticsearch/xpack/downsample/DimensionFieldProducer.java

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,29 @@ void reset() {
4444
isEmpty = true;
4545
}
4646

47-
void collect(final Object value) {
47+
void collectOnce(final Object value) {
48+
assert isEmpty;
4849
Objects.requireNonNull(value);
49-
if (isEmpty) {
50-
this.value = value;
51-
this.isEmpty = false;
52-
return;
53-
}
54-
if (value.equals(this.value) == false) {
55-
throw new IllegalArgumentException("Dimension value changed without tsid change [" + value + "] != [" + this.value + "]");
50+
this.value = value;
51+
this.isEmpty = false;
52+
}
53+
54+
/**
55+
* This is an expensive check, that slows down downsampling significantly.
56+
* Given that index is sorted by tsid as primary key, this shouldn't really happen.
57+
*/
58+
boolean validate(FormattedDocValues docValues, int docId) throws IOException {
59+
if (docValues.advanceExact(docId)) {
60+
int docValueCount = docValues.docValueCount();
61+
for (int i = 0; i < docValueCount; i++) {
62+
var value = docValues.nextValue();
63+
if (value.equals(this.value) == false) {
64+
assert false : "Dimension value changed without tsid change [" + value + "] != [" + this.value + "]";
65+
}
66+
}
5667
}
68+
69+
return true;
5770
}
5871
}
5972

@@ -69,12 +82,17 @@ public boolean isEmpty() {
6982

7083
@Override
7184
public void collect(FormattedDocValues docValues, int docId) throws IOException {
85+
if (dimension.isEmpty == false) {
86+
assert dimension.validate(docValues, docId);
87+
return;
88+
}
89+
7290
if (docValues.advanceExact(docId) == false) {
7391
return;
7492
}
7593
int docValueCount = docValues.docValueCount();
7694
for (int i = 0; i < docValueCount; i++) {
77-
this.dimension.collect(docValues.nextValue());
95+
this.dimension.collectOnce(docValues.nextValue());
7896
}
7997
}
8098

0 commit comments

Comments
 (0)