@@ -10,14 +10,18 @@ import (
10
10
"strings"
11
11
"sync"
12
12
13
+ "github.com/cespare/xxhash/v2"
14
+ "github.com/google/uuid"
13
15
"github.com/grafana/dskit/multierror"
16
+ "github.com/oklog/ulid"
14
17
"github.com/parquet-go/parquet-go"
15
18
"github.com/prometheus/common/model"
16
19
"github.com/prometheus/prometheus/storage"
17
20
"golang.org/x/sync/errgroup"
18
21
19
22
metastorev1 "github.com/grafana/pyroscope/api/gen/proto/go/metastore/v1"
20
23
"github.com/grafana/pyroscope/pkg/experiment/block/metadata"
24
+ "github.com/grafana/pyroscope/pkg/experiment/metrics"
21
25
phlaremodel "github.com/grafana/pyroscope/pkg/model"
22
26
"github.com/grafana/pyroscope/pkg/objstore"
23
27
"github.com/grafana/pyroscope/pkg/phlaredb/block"
@@ -62,6 +66,7 @@ func Compact(
62
66
ctx context.Context ,
63
67
blocks []* metastorev1.BlockMeta ,
64
68
storage objstore.Bucket ,
69
+ workerId uuid.UUID ,
65
70
options ... CompactionOption ,
66
71
) (m []* metastorev1.BlockMeta , err error ) {
67
72
c := & compactionConfig {
@@ -74,7 +79,7 @@ func Compact(
74
79
}
75
80
76
81
objects := ObjectsFromMetas (storage , blocks , c .objectOptions ... )
77
- plan , err := PlanCompaction (objects )
82
+ plan , err := PlanCompaction (objects , workerId )
78
83
if err != nil {
79
84
return nil , err
80
85
}
@@ -93,12 +98,20 @@ func Compact(
93
98
return nil , compactionErr
94
99
}
95
100
compacted = append (compacted , md )
101
+
102
+ if p .metricsExporter != nil {
103
+ go func () {
104
+ if sendErr := p .SendRecordedMetrics (); sendErr != nil {
105
+ println ("ERROR" , sendErr ) // TODO
106
+ }
107
+ }()
108
+ }
96
109
}
97
110
98
111
return compacted , nil
99
112
}
100
113
101
- func PlanCompaction (objects Objects ) ([]* CompactionPlan , error ) {
114
+ func PlanCompaction (objects Objects , workerId uuid. UUID ) ([]* CompactionPlan , error ) {
102
115
if len (objects ) == 0 {
103
116
// Even if there's just a single object, we still need to rewrite it.
104
117
return nil , ErrNoBlocksToMerge
@@ -125,6 +138,7 @@ func PlanCompaction(objects Objects) ([]*CompactionPlan, error) {
125
138
obj .meta .StringTable [s .Tenant ],
126
139
r .meta .Shard ,
127
140
level ,
141
+ workerId ,
128
142
)
129
143
m [obj .meta .StringTable [s .Tenant ]] = tm
130
144
}
@@ -149,24 +163,28 @@ func PlanCompaction(objects Objects) ([]*CompactionPlan, error) {
149
163
}
150
164
151
165
type CompactionPlan struct {
152
- tenant string
153
- path string
154
- datasetMap map [int32 ]* datasetCompaction
155
- datasets []* datasetCompaction
156
- meta * metastorev1.BlockMeta
157
- strings * metadata.StringTable
166
+ tenant string
167
+ path string
168
+ datasetMap map [int32 ]* datasetCompaction
169
+ datasets []* datasetCompaction
170
+ meta * metastorev1.BlockMeta
171
+ strings * metadata.StringTable
172
+ metricsExporter * metrics.Exporter
173
+ workerId uuid.UUID
158
174
}
159
175
160
176
func newBlockCompaction (
161
177
id string ,
162
178
tenant string ,
163
179
shard uint32 ,
164
180
compactionLevel uint32 ,
181
+ workerId uuid.UUID ,
165
182
) * CompactionPlan {
166
183
p := & CompactionPlan {
167
184
tenant : tenant ,
168
185
datasetMap : make (map [int32 ]* datasetCompaction ),
169
186
strings : metadata .NewStringTable (),
187
+ workerId : workerId ,
170
188
}
171
189
p .path = BuildObjectPath (tenant , shard , compactionLevel , id )
172
190
p .meta = & metastorev1.BlockMeta {
@@ -176,6 +194,9 @@ func newBlockCompaction(
176
194
Shard : shard ,
177
195
CompactionLevel : compactionLevel ,
178
196
}
197
+ if compactionLevel == 1 {
198
+ p .metricsExporter = metrics .NewExporter (tenant )
199
+ }
179
200
return p
180
201
}
181
202
@@ -189,6 +210,9 @@ func (b *CompactionPlan) Compact(ctx context.Context, dst objstore.Bucket, tmpdi
189
210
if err = s .compact (ctx , w ); err != nil {
190
211
return nil , fmt .Errorf ("compacting block: %w" , err )
191
212
}
213
+ if b .metricsExporter != nil {
214
+ b .metricsExporter .AppendMetrics (s .metricsRecorder .Recordings )
215
+ }
192
216
b .meta .Datasets = append (b .meta .Datasets , s .meta )
193
217
}
194
218
if err = w .Flush (ctx ); err != nil {
@@ -217,6 +241,10 @@ func (b *CompactionPlan) addDataset(md *metastorev1.BlockMeta, s *metastorev1.Da
217
241
return sm
218
242
}
219
243
244
+ func (c * CompactionPlan ) SendRecordedMetrics () error {
245
+ return c .metricsExporter .Send ()
246
+ }
247
+
220
248
type datasetCompaction struct {
221
249
// Dataset name.
222
250
name string
@@ -236,6 +264,9 @@ type datasetCompaction struct {
236
264
profiles uint64
237
265
238
266
flushOnce sync.Once
267
+
268
+ workerId uuid.UUID
269
+ metricsRecorder * metrics.Recorder
239
270
}
240
271
241
272
func (b * CompactionPlan ) newDatasetCompaction (tenant , name int32 ) * datasetCompaction {
@@ -254,6 +285,7 @@ func (b *CompactionPlan) newDatasetCompaction(tenant, name int32) *datasetCompac
254
285
Size : 0 ,
255
286
Labels : nil ,
256
287
},
288
+ workerId : b .workerId ,
257
289
}
258
290
}
259
291
@@ -309,6 +341,13 @@ func (m *datasetCompaction) open(ctx context.Context, path string) (err error) {
309
341
m .indexRewriter = newIndexRewriter (m .path )
310
342
m .symbolsRewriter = newSymbolsRewriter (m .path )
311
343
344
+ if m .parent .meta .CompactionLevel == 1 {
345
+ recordingTime := int64 (ulid .MustParse (m .parent .meta .Id ).Time ())
346
+ rules := metrics .RecordingRulesFromTenant (m .parent .tenant )
347
+ pyroscopeInstance := pyroscopeInstanceHash (m .parent .meta .Shard , m .workerId )
348
+ m .metricsRecorder = metrics .NewRecorder (rules , recordingTime , pyroscopeInstance )
349
+ }
350
+
312
351
g , ctx := errgroup .WithContext (ctx )
313
352
for _ , s := range m .datasets {
314
353
s := s
@@ -330,6 +369,13 @@ func (m *datasetCompaction) open(ctx context.Context, path string) (err error) {
330
369
return nil
331
370
}
332
371
372
+ func pyroscopeInstanceHash (shard uint32 , id uuid.UUID ) string {
373
+ buf := make ([]byte , 0 , 40 )
374
+ buf = append (buf , byte (shard >> 24 ), byte (shard >> 16 ), byte (shard >> 8 ), byte (shard ))
375
+ buf = append (buf , id .String ()... )
376
+ return fmt .Sprintf ("%x" , xxhash .Sum64 (buf ))
377
+ }
378
+
333
379
func (m * datasetCompaction ) mergeAndClose (ctx context.Context ) (err error ) {
334
380
defer func () {
335
381
err = multierror .New (err , m .close ()).Err ()
@@ -366,6 +412,9 @@ func (m *datasetCompaction) writeRow(r ProfileEntry) (err error) {
366
412
if err = m .symbolsRewriter .rewriteRow (r ); err != nil {
367
413
return err
368
414
}
415
+ if m .metricsRecorder != nil {
416
+ m .metricsRecorder .RecordRow (r .Fingerprint , r .Labels , r .Row .TotalValue ())
417
+ }
369
418
return m .profilesWriter .writeRow (r )
370
419
}
371
420
0 commit comments