1use std::sync::LazyLock;
16
17use prometheus::core::{AtomicU64, GenericCounter, GenericCounterVec};
18use prometheus::{
19 Histogram, HistogramVec, IntGauge, Registry, exponential_buckets, histogram_opts,
20 register_histogram_vec_with_registry, register_histogram_with_registry,
21 register_int_counter_vec_with_registry, register_int_counter_with_registry,
22 register_int_gauge_with_registry,
23};
24use risingwave_common::monitor::GLOBAL_METRICS_REGISTRY;
25
26#[derive(Debug, Clone)]
27pub struct CompactorMetrics {
28 pub compaction_upload_sst_counts: GenericCounter<AtomicU64>,
29 pub compact_fast_runner_bytes: GenericCounter<AtomicU64>,
30 pub compact_write_bytes: GenericCounterVec<AtomicU64>,
31 pub compact_read_current_level: GenericCounterVec<AtomicU64>,
32 pub compact_read_next_level: GenericCounterVec<AtomicU64>,
33 pub compact_read_sstn_current_level: GenericCounterVec<AtomicU64>,
34 pub compact_read_sstn_next_level: GenericCounterVec<AtomicU64>,
35 pub compact_write_sstn: GenericCounterVec<AtomicU64>,
36 pub compact_sst_duration: Histogram,
37 pub compact_task_duration: HistogramVec,
38 pub compact_task_pending_num: IntGauge,
39 pub compact_task_pending_parallelism: IntGauge,
40 pub write_build_l0_sst_duration: Histogram,
41 pub shared_buffer_to_sstable_size: Histogram,
42 pub get_table_id_total_time_duration: Histogram,
43 pub remote_read_time: Histogram,
44 pub sstable_bloom_filter_size: Histogram,
45 pub sstable_file_size: Histogram,
46 pub sstable_avg_key_size: Histogram,
47 pub sstable_avg_value_size: Histogram,
48 pub iter_scan_key_counts: GenericCounterVec<AtomicU64>,
49 pub write_build_l0_bytes: GenericCounter<AtomicU64>,
50 pub sstable_distinct_epoch_count: Histogram,
51 pub compaction_event_consumed_latency: Histogram,
52 pub compaction_event_loop_iteration_latency: Histogram,
53 pub sstable_block_size: Histogram,
54 pub iceberg_compaction_memory_budget_bytes: IntGauge,
55 pub iceberg_compaction_running_memory_reservation_bytes: IntGauge,
56}
57
58pub static GLOBAL_COMPACTOR_METRICS: LazyLock<CompactorMetrics> =
59 LazyLock::new(|| CompactorMetrics::new(&GLOBAL_METRICS_REGISTRY));
60
61impl CompactorMetrics {
62 fn new(registry: &Registry) -> Self {
63 let size_buckets = exponential_buckets(256.0, 8.0, 9).unwrap();
65 let time_buckets = exponential_buckets(0.01, 10.0, 7).unwrap();
67 let opts = histogram_opts!(
68 "compactor_shared_buffer_to_sstable_size",
69 "Histogram of batch size compacted from shared buffer to remote storage",
70 size_buckets.clone()
71 );
72 let shared_buffer_to_sstable_size =
73 register_histogram_with_registry!(opts, registry).unwrap();
74
75 let compaction_upload_sst_counts = register_int_counter_with_registry!(
76 "compactor_compaction_upload_sst_counts",
77 "Total number of sst uploads during compaction",
78 registry
79 )
80 .unwrap();
81
82 let opts = histogram_opts!(
83 "compactor_compact_sst_duration",
84 "Total time of compact_key_range that have been issued to state store",
85 time_buckets.clone()
86 );
87 let compact_sst_duration = register_histogram_with_registry!(opts, registry).unwrap();
88 let opts = histogram_opts!(
89 "compactor_compact_task_duration",
90 "Total time of compact that have been issued to state store",
91 time_buckets.clone()
92 );
93 let compact_task_duration =
94 register_histogram_vec_with_registry!(opts, &["group", "level"], registry).unwrap();
95
96 let opts = histogram_opts!(
97 "compactor_get_table_id_total_time_duration",
98 "Total time of compact that have been issued to state store",
99 time_buckets.clone()
100 );
101 let get_table_id_total_time_duration =
102 register_histogram_with_registry!(opts, registry).unwrap();
103
104 let opts = histogram_opts!(
105 "compactor_remote_read_time",
106 "Total time of operations which read from remote storage when enable prefetch",
107 time_buckets.clone()
108 );
109 let remote_read_time = register_histogram_with_registry!(opts, registry).unwrap();
110
111 let compact_read_current_level = register_int_counter_vec_with_registry!(
112 "storage_level_compact_read_curr",
113 "KBs read from current level during history compactions to next level",
114 &["group", "level_index"],
115 registry
116 )
117 .unwrap();
118
119 let compact_read_next_level = register_int_counter_vec_with_registry!(
120 "storage_level_compact_read_next",
121 "KBs read from next level during history compactions to next level",
122 &["group", "level_index"],
123 registry
124 )
125 .unwrap();
126
127 let compact_write_bytes = register_int_counter_vec_with_registry!(
128 "storage_level_compact_write",
129 "KBs written into next level during history compactions to next level",
130 &["group", "level_index"],
131 registry
132 )
133 .unwrap();
134
135 let compact_read_sstn_current_level = register_int_counter_vec_with_registry!(
136 "storage_level_compact_read_sstn_curr",
137 "num of SSTs read from current level during history compactions to next level",
138 &["group", "level_index"],
139 registry
140 )
141 .unwrap();
142
143 let compact_read_sstn_next_level = register_int_counter_vec_with_registry!(
144 "storage_level_compact_read_sstn_next",
145 "num of SSTs read from next level during history compactions to next level",
146 &["group", "level_index"],
147 registry
148 )
149 .unwrap();
150
151 let compact_write_sstn = register_int_counter_vec_with_registry!(
152 "storage_level_compact_write_sstn",
153 "num of SSTs written into next level during history compactions to next level",
154 &["group", "level_index"],
155 registry
156 )
157 .unwrap();
158
159 let compact_task_pending_num = register_int_gauge_with_registry!(
160 "storage_compact_task_pending_num",
161 "the num of storage compact task",
162 registry
163 )
164 .unwrap();
165
166 let compact_task_pending_parallelism = register_int_gauge_with_registry!(
167 "storage_compact_task_pending_parallelism",
168 "the num of storage compact parallelism",
169 registry
170 )
171 .unwrap();
172
173 let opts = histogram_opts!(
174 "compactor_sstable_bloom_filter_size",
175 "Total bytes gotten from the SST filter payload, for observing filter size",
176 exponential_buckets(16.0, 16.0, 7).unwrap() );
178
179 let sstable_bloom_filter_size = register_histogram_with_registry!(opts, registry).unwrap();
180
181 let opts = histogram_opts!(
182 "compactor_sstable_file_size",
183 "Total bytes gotten from sstable_file_size, for observing sstable_file_size",
184 size_buckets.clone()
185 );
186
187 let sstable_file_size = register_histogram_with_registry!(opts, registry).unwrap();
188
189 let opts = histogram_opts!(
190 "compactor_sstable_avg_key_size",
191 "Total bytes gotten from sstable_avg_key_size, for observing sstable_avg_key_size",
192 size_buckets.clone()
193 );
194
195 let sstable_avg_key_size = register_histogram_with_registry!(opts, registry).unwrap();
196
197 let opts = histogram_opts!(
198 "compactor_sstable_avg_value_size",
199 "Total bytes gotten from sstable_avg_value_size, for observing sstable_avg_value_size",
200 size_buckets.clone()
201 );
202
203 let sstable_avg_value_size = register_histogram_with_registry!(opts, registry).unwrap();
204
205 let opts = histogram_opts!(
206 "state_store_write_build_l0_sst_duration",
207 "Total time of batch_write_build_table that have been issued to state store",
208 time_buckets.clone()
209 );
210 let write_build_l0_sst_duration =
211 register_histogram_with_registry!(opts, registry).unwrap();
212
213 let iter_scan_key_counts = register_int_counter_vec_with_registry!(
214 "compactor_iter_scan_key_counts",
215 "Total number of keys read by iterator",
216 &["type"],
217 registry
218 )
219 .unwrap();
220
221 let write_build_l0_bytes = register_int_counter_with_registry!(
222 "compactor_write_build_l0_bytes",
223 "Total size of compaction files size that have been written to object store from shared buffer",
224 registry
225 ).unwrap();
226 let compact_fast_runner_bytes = register_int_counter_with_registry!(
227 "compactor_fast_compact_bytes",
228 "Total size of compaction files size of fast compactor runner",
229 registry
230 )
231 .unwrap();
232 let opts = histogram_opts!(
233 "compactor_sstable_distinct_epoch_count",
234 "Total number gotten from sstable_distinct_epoch_count, for observing sstable_distinct_epoch_count",
235 exponential_buckets(1.0, 10.0, 6).unwrap()
236 );
237
238 let sstable_distinct_epoch_count =
239 register_histogram_with_registry!(opts, registry).unwrap();
240
241 let opts = histogram_opts!(
242 "compactor_compaction_event_consumed_latency",
243 "The latency of each event being consumed",
244 time_buckets.clone()
245 );
246 let compaction_event_consumed_latency =
247 register_histogram_with_registry!(opts, registry).unwrap();
248
249 let opts = histogram_opts!(
250 "compactor_compaction_event_loop_iteration_latency",
251 "The latency of each iteration of the compaction event loop",
252 time_buckets
253 );
254 let compaction_event_loop_iteration_latency =
255 register_histogram_with_registry!(opts, registry).unwrap();
256
257 let opts = histogram_opts!(
258 "compactor_sstable_block_size",
259 "Total bytes gotten from sstable_block_size, for observing sstable_block_size",
260 size_buckets,
261 );
262
263 let sstable_block_size = register_histogram_with_registry!(opts, registry).unwrap();
264
265 let iceberg_compaction_memory_budget_bytes = register_int_gauge_with_registry!(
266 "storage_iceberg_compaction_memory_budget_bytes",
267 "Heap admission budget for running Iceberg compaction plans on this compactor node",
268 registry
269 )
270 .unwrap();
271 let iceberg_compaction_running_memory_reservation_bytes =
272 register_int_gauge_with_registry!(
273 "storage_iceberg_compaction_running_memory_reservation_bytes",
274 "Estimated heap peak reservations of currently running Iceberg compaction plans",
275 registry
276 )
277 .unwrap();
278 Self {
279 compaction_upload_sst_counts,
280 compact_fast_runner_bytes,
281 compact_write_bytes,
282 compact_read_current_level,
283 compact_read_next_level,
284 compact_read_sstn_current_level,
285 compact_read_sstn_next_level,
286 compact_write_sstn,
287 compact_sst_duration,
288 compact_task_duration,
289 compact_task_pending_num,
290 compact_task_pending_parallelism,
291 write_build_l0_sst_duration,
292 shared_buffer_to_sstable_size,
293 get_table_id_total_time_duration,
294 remote_read_time,
295 sstable_bloom_filter_size,
296 sstable_file_size,
297 sstable_avg_key_size,
298 sstable_avg_value_size,
299 iter_scan_key_counts,
300 write_build_l0_bytes,
301 sstable_distinct_epoch_count,
302 compaction_event_consumed_latency,
303 compaction_event_loop_iteration_latency,
304 sstable_block_size,
305 iceberg_compaction_memory_budget_bytes,
306 iceberg_compaction_running_memory_reservation_bytes,
307 }
308 }
309
310 pub fn unused() -> Self {
312 GLOBAL_COMPACTOR_METRICS.clone()
313 }
314}