Skip to content

Commit dfb688c

Browse files
authored
Merge pull request #2510 from rarruda/fix/reduce_locking
perf: use concurrent map when storing metrics
2 parents 61a1993 + f2a7639 commit dfb688c

File tree

2 files changed

+22
-30
lines changed

2 files changed

+22
-30
lines changed

pkg/metrics_store/metrics_store.go

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
"sync"
2121

2222
"k8s.io/apimachinery/pkg/api/meta"
23-
"k8s.io/apimachinery/pkg/types"
2423

2524
"k8s.io/kube-state-metrics/v2/pkg/metric"
2625
)
@@ -33,7 +32,7 @@ type MetricsStore struct {
3332
// metric families, containing a slice of metrics. We need to keep metrics
3433
// grouped by metric families in order to zip families with their help text in
3534
// MetricsStore.WriteAll().
36-
metrics map[types.UID][][]byte
35+
metrics sync.Map
3736

3837
// generateMetricsFunc generates metrics based on a given Kubernetes object
3938
// and returns them grouped by metric family.
@@ -42,17 +41,14 @@ type MetricsStore struct {
4241
// later on zipped with with their corresponding metric families in
4342
// MetricStore.WriteAll().
4443
headers []string
45-
46-
// Protects metrics
47-
mutex sync.RWMutex
4844
}
4945

5046
// NewMetricsStore returns a new MetricsStore
5147
func NewMetricsStore(headers []string, generateFunc func(interface{}) []metric.FamilyInterface) *MetricsStore {
5248
return &MetricsStore{
5349
generateMetricsFunc: generateFunc,
5450
headers: headers,
55-
metrics: map[types.UID][][]byte{},
51+
metrics: sync.Map{},
5652
}
5753
}
5854

@@ -66,17 +62,14 @@ func (s *MetricsStore) Add(obj interface{}) error {
6662
return err
6763
}
6864

69-
s.mutex.Lock()
70-
defer s.mutex.Unlock()
71-
7265
families := s.generateMetricsFunc(obj)
7366
familyStrings := make([][]byte, len(families))
7467

7568
for i, f := range families {
7669
familyStrings[i] = f.ByteSlice()
7770
}
7871

79-
s.metrics[o.GetUID()] = familyStrings
72+
s.metrics.Store(o.GetUID(), familyStrings)
8073

8174
return nil
8275
}
@@ -95,10 +88,7 @@ func (s *MetricsStore) Delete(obj interface{}) error {
9588
return err
9689
}
9790

98-
s.mutex.Lock()
99-
defer s.mutex.Unlock()
100-
101-
delete(s.metrics, o.GetUID())
91+
s.metrics.Delete(o.GetUID())
10292

10393
return nil
10494
}
@@ -126,9 +116,7 @@ func (s *MetricsStore) GetByKey(_ string) (item interface{}, exists bool, err er
126116
// Replace will delete the contents of the store, using instead the
127117
// given list.
128118
func (s *MetricsStore) Replace(list []interface{}, _ string) error {
129-
s.mutex.Lock()
130-
s.metrics = map[types.UID][][]byte{}
131-
s.mutex.Unlock()
119+
s.metrics.Clear()
132120

133121
for _, o := range list {
134122
err := s.Add(o)

pkg/metrics_store/metrics_writer.go

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -56,31 +56,35 @@ func (m MetricsWriter) WriteAll(w io.Writer) error {
5656
return nil
5757
}
5858

59-
for _, s := range m.stores {
60-
s.mutex.RLock()
61-
defer func(s *MetricsStore) {
62-
s.mutex.RUnlock()
63-
}(s)
64-
}
65-
6659
for i, help := range m.stores[0].headers {
6760
if help != "" && help != "\n" {
6861
help += "\n"
6962
}
7063

71-
if len(m.stores[0].metrics) > 0 {
72-
_, err := w.Write([]byte(help))
64+
var err error
65+
m.stores[0].metrics.Range(func(_ interface{}, _ interface{}) bool {
66+
_, err = w.Write([]byte(help))
7367
if err != nil {
74-
return fmt.Errorf("failed to write help text: %v", err)
68+
err = fmt.Errorf("failed to write help text: %v", err)
7569
}
70+
return false
71+
})
72+
if err != nil {
73+
return err
7674
}
7775

7876
for _, s := range m.stores {
79-
for _, metricFamilies := range s.metrics {
80-
_, err := w.Write(metricFamilies[i])
77+
s.metrics.Range(func(_ interface{}, value interface{}) bool {
78+
metricFamilies := value.([][]byte)
79+
_, err = w.Write(metricFamilies[i])
8180
if err != nil {
82-
return fmt.Errorf("failed to write metrics family: %v", err)
81+
err = fmt.Errorf("failed to write metrics family: %v", err)
82+
return false
8383
}
84+
return true
85+
})
86+
if err != nil {
87+
return err
8488
}
8589
}
8690
}

0 commit comments

Comments
 (0)