Skip to content

Commit de1fac3

Browse files
committed
Merge branch 'main' of https://github.com/risingwavelabs/risingwave into li0k/storage_intra_picker
2 parents b9cf598 + 5a8866d commit de1fac3

13 files changed

+409
-122
lines changed

src/meta/src/hummock/compaction/level_selector.rs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ use risingwave_pb::hummock::hummock_version::Levels;
2626
use risingwave_pb::hummock::{compact_task, CompactionConfig, LevelType};
2727

2828
use super::picker::{
29-
IntraCompactionPicker, SpaceReclaimCompactionPicker, SpaceReclaimPickerState, TtlPickerState,
30-
TtlReclaimCompactionPicker,
29+
CompactionTaskValidator, IntraCompactionPicker, SpaceReclaimCompactionPicker,
30+
SpaceReclaimPickerState, TtlPickerState, TtlReclaimCompactionPicker,
3131
};
3232
use super::{
3333
create_compaction_task, LevelCompactionPicker, ManualCompactionOption, ManualCompactionPicker,
@@ -111,14 +111,22 @@ impl DynamicLevelSelectorCore {
111111
&self,
112112
picker_info: &PickerInfo,
113113
overlap_strategy: Arc<dyn OverlapStrategy>,
114+
compaction_task_validator: Arc<CompactionTaskValidator>,
114115
) -> Box<dyn CompactionPicker> {
115116
match picker_info.picker_type {
116-
PickerType::Tier => Box::new(TierCompactionPicker::new(self.config.clone())),
117-
PickerType::ToBase => Box::new(LevelCompactionPicker::new(
117+
PickerType::Tier => Box::new(TierCompactionPicker::new_with_validator(
118+
self.config.clone(),
119+
compaction_task_validator,
120+
)),
121+
PickerType::ToBase => Box::new(LevelCompactionPicker::new_with_validator(
118122
picker_info.target_level,
119123
self.config.clone(),
124+
compaction_task_validator,
125+
)),
126+
PickerType::Intra => Box::new(IntraCompactionPicker::new_with_validator(
127+
self.config.clone(),
128+
compaction_task_validator,
120129
)),
121-
PickerType::Intra => Box::new(IntraCompactionPicker::new(self.config.clone())),
122130
PickerType::BottomLevel => {
123131
assert_eq!(picker_info.select_level + 1, picker_info.target_level);
124132
Box::new(MinOverlappingPicker::new(
@@ -277,6 +285,7 @@ impl DynamicLevelSelectorCore {
277285
}
278286
});
279287

288+
// FIXME: more accurate score calculation algorithm will be introduced (#11903)
280289
ctx.score_levels.push({
281290
PickerInfo {
282291
score: non_overlapping_score,
@@ -415,12 +424,20 @@ impl LevelSelector for DynamicLevelSelector {
415424
let overlap_strategy =
416425
create_overlap_strategy(compaction_group.compaction_config.compaction_mode());
417426
let ctx = dynamic_level_core.get_priority_levels(levels, level_handlers);
427+
// TODO: Determine which rule to enable by write limit
428+
let compaction_task_validator = Arc::new(CompactionTaskValidator::new(
429+
compaction_group.compaction_config.clone(),
430+
));
418431
for picker_info in &ctx.score_levels {
419432
if picker_info.score <= SCORE_BASE {
420433
return None;
421434
}
422-
let mut picker =
423-
dynamic_level_core.create_compaction_picker(picker_info, overlap_strategy.clone());
435+
let mut picker = dynamic_level_core.create_compaction_picker(
436+
picker_info,
437+
overlap_strategy.clone(),
438+
compaction_task_validator.clone(),
439+
);
440+
424441
let mut stats = LocalPickerStatistic::default();
425442
if let Some(ret) = picker.pick_compaction(levels, level_handlers, &mut stats) {
426443
ret.add_pending_task(task_id, level_handlers);

src/meta/src/hummock/compaction/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -247,25 +247,25 @@ impl LocalSelectorStatistic {
247247
metrics
248248
.compact_skip_frequency
249249
.with_label_values(&[level_label.as_str(), "write-amp"])
250-
.inc_by(stats.skip_by_write_amp_limit);
250+
.inc();
251251
}
252252
if stats.skip_by_count_limit > 0 {
253253
metrics
254254
.compact_skip_frequency
255255
.with_label_values(&[level_label.as_str(), "count"])
256-
.inc_by(stats.skip_by_count_limit);
256+
.inc();
257257
}
258258
if stats.skip_by_pending_files > 0 {
259259
metrics
260260
.compact_skip_frequency
261261
.with_label_values(&[level_label.as_str(), "pending-files"])
262-
.inc_by(stats.skip_by_pending_files);
262+
.inc();
263263
}
264264
if stats.skip_by_overlapping > 0 {
265265
metrics
266266
.compact_skip_frequency
267267
.with_label_values(&[level_label.as_str(), "overlapping"])
268-
.inc_by(stats.skip_by_overlapping);
268+
.inc();
269269
}
270270
metrics
271271
.compact_skip_frequency

src/meta/src/hummock/compaction/picker/base_level_compaction_picker.rs

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,18 @@ use risingwave_pb::hummock::hummock_version::Levels;
2020
use risingwave_pb::hummock::{CompactionConfig, InputLevel, Level, LevelType, OverlappingLevel};
2121

2222
use super::min_overlap_compaction_picker::NonOverlapSubLevelPicker;
23-
use super::{CompactionInput, CompactionPicker, LocalPickerStatistic};
23+
use super::{
24+
CompactionInput, CompactionPicker, CompactionTaskValidator, LocalPickerStatistic,
25+
ValidationRuleType,
26+
};
2427
use crate::hummock::compaction::create_overlap_strategy;
2528
use crate::hummock::compaction::picker::TrivialMovePicker;
2629
use crate::hummock::level_handler::LevelHandler;
2730

2831
pub struct LevelCompactionPicker {
2932
target_level: usize,
3033
config: Arc<CompactionConfig>,
34+
compaction_task_validator: Arc<CompactionTaskValidator>,
3135
}
3236

3337
impl CompactionPicker for LevelCompactionPicker {
@@ -80,13 +84,27 @@ impl CompactionPicker for LevelCompactionPicker {
8084
}
8185

8286
impl LevelCompactionPicker {
87+
#[cfg(test)]
8388
pub fn new(target_level: usize, config: Arc<CompactionConfig>) -> LevelCompactionPicker {
8489
LevelCompactionPicker {
8590
target_level,
91+
compaction_task_validator: Arc::new(CompactionTaskValidator::new(config.clone())),
8692
config,
8793
}
8894
}
8995

96+
pub fn new_with_validator(
97+
target_level: usize,
98+
config: Arc<CompactionConfig>,
99+
compaction_task_validator: Arc<CompactionTaskValidator>,
100+
) -> LevelCompactionPicker {
101+
LevelCompactionPicker {
102+
target_level,
103+
config,
104+
compaction_task_validator,
105+
}
106+
}
107+
90108
fn pick_base_trivial_move(
91109
&self,
92110
l0: &OverlappingLevel,
@@ -113,10 +131,10 @@ impl LevelCompactionPicker {
113131
level_handlers: &[LevelHandler],
114132
stats: &mut LocalPickerStatistic,
115133
) -> Option<CompactionInput> {
134+
// TODO: remove this
116135
let l0_size = l0.total_file_size - level_handlers[0].get_pending_file_size();
117136
let base_level_size = target_level.total_file_size
118137
- level_handlers[target_level.level_idx as usize].get_pending_file_size();
119-
120138
if l0_size < base_level_size {
121139
stats.skip_by_write_amp_limit += 1;
122140
return None;
@@ -153,7 +171,7 @@ impl LevelCompactionPicker {
153171

154172
let mut skip_by_pending = false;
155173
let mut input_levels = vec![];
156-
let mut min_write_amp_meet = false;
174+
157175
for input in l0_select_tables_vec {
158176
let l0_select_tables = input
159177
.sstable_infos
@@ -180,16 +198,6 @@ impl LevelCompactionPicker {
180198
continue;
181199
}
182200

183-
// The size of target level may be too large, we shall skip this compact task and wait
184-
// the data in base level compact to lower level.
185-
if target_level_size > self.config.max_compaction_bytes && strict_check {
186-
continue;
187-
}
188-
189-
if input.total_file_size >= target_level_size {
190-
min_write_amp_meet = true;
191-
}
192-
193201
input_levels.push((input, target_level_size, target_level_ssts));
194202
}
195203

@@ -200,20 +208,7 @@ impl LevelCompactionPicker {
200208
return None;
201209
}
202210

203-
if !min_write_amp_meet && strict_check {
204-
// If the write-amplification of all candidate task are large, we may hope to wait base
205-
// level compact more data to lower level. But if we skip all task, I'm
206-
// afraid the data will be blocked in level0 and will be never compacted to base level.
207-
// So we only allow one task exceed write-amplification-limit running in
208-
// level0 to base-level.
209-
return None;
210-
}
211-
212211
for (input, target_file_size, target_level_files) in input_levels {
213-
if min_write_amp_meet && input.total_file_size < target_file_size {
214-
continue;
215-
}
216-
217212
let mut select_level_inputs = input
218213
.sstable_infos
219214
.into_iter()
@@ -224,18 +219,33 @@ impl LevelCompactionPicker {
224219
})
225220
.collect_vec();
226221
select_level_inputs.reverse();
222+
let target_file_count = target_level_files.len();
227223
select_level_inputs.push(InputLevel {
228224
level_idx: target_level.level_idx,
229225
level_type: target_level.level_type,
230226
table_infos: target_level_files,
231227
});
232-
return Some(CompactionInput {
228+
229+
let result = CompactionInput {
233230
input_levels: select_level_inputs,
234231
target_level: self.target_level,
235-
target_sub_level_id: 0,
236-
});
232+
select_input_size: input.total_file_size,
233+
target_input_size: target_file_size,
234+
total_file_count: (input.total_file_count + target_file_count) as u64,
235+
..Default::default()
236+
};
237+
238+
if !self.compaction_task_validator.valid_compact_task(
239+
&result,
240+
ValidationRuleType::ToBase,
241+
stats,
242+
) && strict_check
243+
{
244+
continue;
245+
}
246+
247+
return Some(result);
237248
}
238-
stats.skip_by_write_amp_limit += 1;
239249
None
240250
}
241251
}
@@ -632,6 +642,7 @@ pub mod tests {
632642
}],
633643
target_level: 1,
634644
target_sub_level_id: pending_level.sub_level_id,
645+
..Default::default()
635646
};
636647
assert!(!levels_handler[0].is_level_pending_compact(&pending_level));
637648
tier_task_input.add_pending_task(1, &mut levels_handler);
@@ -649,7 +660,6 @@ pub mod tests {
649660
// But stopped by pending sub-level when trying to include more sub-levels.
650661
let mut picker = LevelCompactionPicker::new(1, config.clone());
651662
let ret = picker.pick_compaction(&levels, &levels_handler, &mut local_stats);
652-
653663
assert!(ret.is_none());
654664

655665
// Free the pending sub-level.
@@ -695,7 +705,6 @@ pub mod tests {
695705
let ret = picker
696706
.pick_compaction(&levels, &levels_handler, &mut local_stats)
697707
.unwrap();
698-
// println!("ret.input_levels: {:?}", ret.input_levels);
699708
// 1. trivial_move
700709
assert_eq!(2, ret.input_levels.len());
701710
assert!(ret.input_levels[1].table_infos.is_empty());
@@ -705,7 +714,6 @@ pub mod tests {
705714
let ret = picker
706715
.pick_compaction(&levels, &levels_handler, &mut local_stats)
707716
.unwrap();
708-
println!("ret.input_levels: {:?}", ret.input_levels);
709717
assert_eq!(3, ret.input_levels.len());
710718
assert_eq!(6, ret.input_levels[0].table_infos[0].sst_id);
711719
}

0 commit comments

Comments
 (0)