mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-12-15 00:13:30 +01:00
lib/storage: use binary search instead of full scan for skipping artificial tags when searching for tag names or tag values
This should improve performance for /api/v1/labels and /api/v1/label/<label_name>/values See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2200
This commit is contained in:
parent
f227712d7d
commit
ee066aa0d5
@ -15,6 +15,7 @@ The following tip changes can be tested by building VictoriaMetrics components f
|
|||||||
## tip
|
## tip
|
||||||
|
|
||||||
|
|
||||||
|
* BUGFIX: fix a bug, which could significantly slow down requests to `/api/v1/labels` and `/api/v1/label/<label_name>/values`. These APIs are used by Grafana for auto-completion of label names and label values. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2200).
|
||||||
* BUGFIX: vmalert: add support for `$externalLabels` and `$externalURL` template vars in the same way as Prometheus does. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2193).
|
* BUGFIX: vmalert: add support for `$externalLabels` and `$externalURL` template vars in the same way as Prometheus does. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2193).
|
||||||
* BUGFIX: update default value for `-promscrape.fileSDCheckInterval`, so it matches default duration used by Prometheus for checking for updates in `file_sd_configs`. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2187). Thanks to @corporate-gadfly for the fix.
|
* BUGFIX: update default value for `-promscrape.fileSDCheckInterval`, so it matches default duration used by Prometheus for checking for updates in `file_sd_configs`. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2187). Thanks to @corporate-gadfly for the fix.
|
||||||
|
|
||||||
|
@ -801,12 +801,9 @@ func (is *indexSearch) searchTagKeysOnDate(tks map[string]struct{}, date uint64,
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
key := mp.Tag.Key
|
key := mp.Tag.Key
|
||||||
if isArtificialTagKey(key) {
|
if !isArtificialTagKey(key) {
|
||||||
// Skip artificially created tag key.
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// Store tag key.
|
|
||||||
tks[string(key)] = struct{}{}
|
tks[string(key)] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
// Search for the next tag key.
|
// Search for the next tag key.
|
||||||
// The last char in kb.B must be tagSeparatorChar.
|
// The last char in kb.B must be tagSeparatorChar.
|
||||||
@ -880,12 +877,9 @@ func (is *indexSearch) searchTagKeys(tks map[string]struct{}, maxTagKeys int) er
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
key := mp.Tag.Key
|
key := mp.Tag.Key
|
||||||
if isArtificialTagKey(key) {
|
if !isArtificialTagKey(key) {
|
||||||
// Skip artificailly created tag keys.
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// Store tag key.
|
|
||||||
tks[string(key)] = struct{}{}
|
tks[string(key)] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
// Search for the next tag key.
|
// Search for the next tag key.
|
||||||
// The last char in kb.B must be tagSeparatorChar.
|
// The last char in kb.B must be tagSeparatorChar.
|
||||||
@ -1000,22 +994,25 @@ func (is *indexSearch) searchTagValuesOnDate(tvs map[string]struct{}, tagKey []b
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store tag value
|
skipTag := isArtificialTagKey(mp.Tag.Key)
|
||||||
|
if !skipTag {
|
||||||
tvs[string(mp.Tag.Value)] = struct{}{}
|
tvs[string(mp.Tag.Value)] = struct{}{}
|
||||||
|
|
||||||
if mp.MetricIDsLen() < maxMetricIDsPerRow/2 {
|
if mp.MetricIDsLen() < maxMetricIDsPerRow/2 {
|
||||||
// There is no need in searching for the next tag value,
|
// There is no need in searching for the next tag value,
|
||||||
// since it is likely it is located in the next row,
|
// since it is likely it is located in the next row,
|
||||||
// because the current row contains incomplete metricIDs set.
|
// because the current row contains incomplete metricIDs set.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Search for the next tag value.
|
// Search for the next tag value.
|
||||||
// The last char in kb.B must be tagSeparatorChar.
|
// The last char in kb.B must be tagSeparatorChar.
|
||||||
// Just increment it in order to jump to the next tag value.
|
// Just increment it in order to jump to the next tag value.
|
||||||
kb.B = is.marshalCommonPrefix(kb.B[:0], nsPrefixDateTagToMetricIDs)
|
kb.B = is.marshalCommonPrefix(kb.B[:0], nsPrefixDateTagToMetricIDs)
|
||||||
kb.B = encoding.MarshalUint64(kb.B, date)
|
kb.B = encoding.MarshalUint64(kb.B, date)
|
||||||
kb.B = marshalTagValue(kb.B, mp.Tag.Key)
|
kb.B = marshalTagValue(kb.B, mp.Tag.Key)
|
||||||
|
if !skipTag {
|
||||||
kb.B = marshalTagValue(kb.B, mp.Tag.Value)
|
kb.B = marshalTagValue(kb.B, mp.Tag.Value)
|
||||||
|
}
|
||||||
kb.B[len(kb.B)-1]++
|
kb.B[len(kb.B)-1]++
|
||||||
ts.Seek(kb.B)
|
ts.Seek(kb.B)
|
||||||
}
|
}
|
||||||
@ -1085,21 +1082,24 @@ func (is *indexSearch) searchTagValues(tvs map[string]struct{}, tagKey []byte, m
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store tag value
|
skipTag := isArtificialTagKey(mp.Tag.Key)
|
||||||
|
if !skipTag {
|
||||||
tvs[string(mp.Tag.Value)] = struct{}{}
|
tvs[string(mp.Tag.Value)] = struct{}{}
|
||||||
|
|
||||||
if mp.MetricIDsLen() < maxMetricIDsPerRow/2 {
|
if mp.MetricIDsLen() < maxMetricIDsPerRow/2 {
|
||||||
// There is no need in searching for the next tag value,
|
// There is no need in searching for the next tag value,
|
||||||
// since it is likely it is located in the next row,
|
// since it is likely it is located in the next row,
|
||||||
// because the current row contains incomplete metricIDs set.
|
// because the current row contains incomplete metricIDs set.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Search for the next tag value.
|
// Search for the next tag value.
|
||||||
// The last char in kb.B must be tagSeparatorChar.
|
// The last char in kb.B must be tagSeparatorChar.
|
||||||
// Just increment it in order to jump to the next tag value.
|
// Just increment it in order to jump to the next tag value.
|
||||||
kb.B = is.marshalCommonPrefix(kb.B[:0], nsPrefixTagToMetricIDs)
|
kb.B = is.marshalCommonPrefix(kb.B[:0], nsPrefixTagToMetricIDs)
|
||||||
kb.B = marshalTagValue(kb.B, mp.Tag.Key)
|
kb.B = marshalTagValue(kb.B, mp.Tag.Key)
|
||||||
|
if !skipTag {
|
||||||
kb.B = marshalTagValue(kb.B, mp.Tag.Value)
|
kb.B = marshalTagValue(kb.B, mp.Tag.Value)
|
||||||
|
}
|
||||||
kb.B[len(kb.B)-1]++
|
kb.B[len(kb.B)-1]++
|
||||||
ts.Seek(kb.B)
|
ts.Seek(kb.B)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user