From 2e128408d9a03579c73665ea469b82e380a0403d Mon Sep 17 00:00:00 2001 From: Bartlomiej Plotka Date: Fri, 16 Oct 2020 14:42:49 +0200 Subject: [PATCH] Quick fix for remote write "leak". (#3327) Signed-off-by: Bartlomiej Plotka --- CHANGELOG.md | 2 - pkg/store/labelpb/label.go | 202 +------------------------------------ 2 files changed, 4 insertions(+), 200 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40a9a3cc28..2850c9960e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,6 @@ Highlights: `storeMatch[]` arguments with `__address__` matchers. * Improved debuggability on all Thanos components by exposing [off-CPU profiles thanks to fgprof endpoint](https://github.com/felixge/fgprof). * Significantly improved sidecar latency and CPU usage for metrics fetches. -* Significantly improved query performance on Store Gateway, Querier, Ruler and Receive by introducing zero allocation gRPC label encoding / decoding. ### Fixed @@ -43,7 +42,6 @@ Highlights: ### Changed -- [#2783](https://github.com/thanos-io/thanos/pull/2783) Querier,Store,Receive,Rule: Improved performance of all gRPC StoreAPI implementation that use labels. Label encoding and decoding reuse same bytes instead of re-allocated new for string conversion. - [#3136](https://github.com/thanos-io/thanos/pull/3136) Sidecar: **breaking** Added metric `thanos_sidecar_reloader_config_apply_operations_total` and rename metric `thanos_sidecar_reloader_config_apply_errors_total` to `thanos_sidecar_reloader_config_apply_operations_failed_total`. - [#3154](https://github.com/thanos-io/thanos/pull/3154) Querier: **breaking** Added metric `thanos_query_gate_queries_max`. Remove metric `thanos_query_concurrent_selects_gate_queries_in_flight`. - [#3154](https://github.com/thanos-io/thanos/pull/3154) Store: **breaking** Renamed metric `thanos_bucket_store_queries_concurrent_max` to `thanos_bucket_store_series_gate_queries_max`. diff --git a/pkg/store/labelpb/label.go b/pkg/store/labelpb/label.go index bc4b58d645..ff675fdb16 100644 --- a/pkg/store/labelpb/label.go +++ b/pkg/store/labelpb/label.go @@ -6,9 +6,6 @@ package labelpb import ( - "encoding/json" - "fmt" - "io" "sort" "strings" "unsafe" @@ -17,10 +14,6 @@ import ( "github.com/prometheus/prometheus/pkg/labels" ) -func noAllocString(buf []byte) string { - return *((*string)(unsafe.Pointer(&buf))) -} - // LabelsFromPromLabels converts Prometheus labels to slice of storepb.Label in type unsafe manner. // It reuses the same memory. Caller should abort using passed labels.Labels. func LabelsFromPromLabels(lset labels.Labels) []Label { @@ -42,197 +35,10 @@ func LabelSetsToPromLabelSets(lss ...LabelSet) []labels.Labels { return res } -// Label is a labels.Label that can be marshaled to/from protobuf reusing the same -// memory address for string bytes. -type Label labels.Label - -func (m *Label) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalToSizedBuffer(data[:size]) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *Label) MarshalTo(data []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(data[:size]) -} - -func (m *Label) MarshalToSizedBuffer(data []byte) (int, error) { - i := len(data) - _ = i - var l int - _ = l - if len(m.Value) > 0 { - i -= len(m.Value) - copy(data[i:], m.Value) - i = encodeVarintTypes(data, i, uint64(len(m.Value))) - i-- - data[i] = 0x12 - } - if len(m.Name) > 0 { - i -= len(m.Name) - copy(data[i:], m.Name) - i = encodeVarintTypes(data, i, uint64(len(m.Name))) - i-- - data[i] = 0xa - } - return len(data) - i, nil -} - -func (m *Label) Unmarshal(data []byte) error { - l := len(data) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := data[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Label: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Label: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := data[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = noAllocString(data[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := data[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Value = noAllocString(data[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipTypes(data[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthTypes - } - if (iNdEx + skippy) < 0 { - return ErrInvalidLengthTypes - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} - -func (m *Label) UnmarshalJSON(entry []byte) error { - l := FullCopyLabel{} - - if err := json.Unmarshal(entry, &l); err != nil { - return errors.Wrapf(err, "labels: label field unmarshal: %v", string(entry)) - } - m.Name = l.Name - m.Value = l.Value - return nil -} - -func (m *Label) MarshalJSON() ([]byte, error) { - return json.Marshal(&FullCopyLabel{Name: m.Name, Value: m.Value}) -} - -// Size implements proto.Sizer. -func (m *Label) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Name) - if l > 0 { - n += 1 + l + sovTypes(uint64(l)) - } - l = len(m.Value) - if l > 0 { - n += 1 + l + sovTypes(uint64(l)) - } - return n -} +// Label is a FullCopyLabel. +// This is quick fix for https://github.com/thanos-io/thanos/issues/3265. +// TODO(bwplotka): Replace with https://github.com/thanos-io/thanos/pull/3279 +type Label = FullCopyLabel // Equal implements proto.Equaler. func (m *Label) Equal(other Label) bool {