Skip to content

Commit 6556d0b

Browse files
committed
chore(cubestore): ClusterSend chunking by partition count
1 parent c388350 commit 6556d0b

File tree

2 files changed

+75
-5
lines changed

2 files changed

+75
-5
lines changed

rust/cubestore/cubestore/src/config/mod.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,8 @@ pub struct Config {
364364
pub trait ConfigObj: DIService {
365365
fn partition_split_threshold(&self) -> u64;
366366

367+
fn cluster_send_split_threshold(&self) -> u64;
368+
367369
fn partition_size_split_threshold_bytes(&self) -> u64;
368370

369371
fn max_partition_split_threshold(&self) -> u64;
@@ -555,6 +557,7 @@ pub trait ConfigObj: DIService {
555557
#[derive(Debug, Clone)]
556558
pub struct ConfigObjImpl {
557559
pub partition_split_threshold: u64,
560+
pub cluster_send_split_threshold: u64,
558561
pub partition_size_split_threshold_bytes: u64,
559562
pub max_partition_split_threshold: u64,
560563
pub compaction_chunks_total_size_threshold: u64,
@@ -662,6 +665,10 @@ impl ConfigObj for ConfigObjImpl {
662665
self.partition_split_threshold
663666
}
664667

668+
fn cluster_send_split_threshold(&self) -> u64 {
669+
self.cluster_send_split_threshold
670+
}
671+
665672
fn partition_size_split_threshold_bytes(&self) -> u64 {
666673
self.partition_size_split_threshold_bytes
667674
}
@@ -1242,6 +1249,10 @@ impl Config {
12421249
"CUBESTORE_PARTITION_SPLIT_THRESHOLD",
12431250
1048576 * 2,
12441251
),
1252+
cluster_send_split_threshold: env_parse(
1253+
"CUBESTORE_CLUSTER_SEND_SPLIT_THRESHOLD",
1254+
4,
1255+
),
12451256
partition_size_split_threshold_bytes: env_parse_size(
12461257
"CUBESTORE_PARTITION_SIZE_SPLIT_THRESHOLD",
12471258
100 * 1024 * 1024,
@@ -1597,6 +1608,7 @@ impl Config {
15971608
.join(format!("{}-local-store", name)),
15981609
dump_dir: None,
15991610
partition_split_threshold: 20,
1611+
cluster_send_split_threshold: 4,
16001612
partition_size_split_threshold_bytes: 2 * 1024,
16011613
max_partition_split_threshold: 20,
16021614
compaction_chunks_count_threshold: 1,

rust/cubestore/cubestore/src/queryplanner/query_executor.rs

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,7 +1104,7 @@ impl ClusterSendExec {
11041104
ps
11051105
}
11061106

1107-
fn issue_filters(ps: &[IdRow<Partition>]) -> Vec<(u64, RowRange)> {
1107+
fn issue_filters(ps: &[IdRow<Partition>]) -> Vec<(IdRow<Partition>, RowRange)> {
11081108
if ps.is_empty() {
11091109
return Vec::new();
11101110
}
@@ -1114,7 +1114,7 @@ impl ClusterSendExec {
11141114
if multi_id.is_none() {
11151115
return ps
11161116
.iter()
1117-
.map(|p| (p.get_id(), RowRange::default()))
1117+
.map(|p| (p.clone(), RowRange::default()))
11181118
.collect();
11191119
}
11201120
let filter = RowRange {
@@ -1129,7 +1129,7 @@ impl ClusterSendExec {
11291129
} else {
11301130
filter.clone()
11311131
};
1132-
r.push((p.get_id(), pf))
1132+
r.push((p.clone(), pf))
11331133
}
11341134
r
11351135
}
@@ -1138,7 +1138,8 @@ impl ClusterSendExec {
11381138
c: &dyn ConfigObj,
11391139
logical: Vec<Vec<InlineCompoundPartition>>,
11401140
) -> Vec<(String, (Vec<(u64, RowRange)>, Vec<InlineTableId>))> {
1141-
let mut m: HashMap<_, (Vec<(u64, RowRange)>, Vec<InlineTableId>)> = HashMap::new();
1141+
let mut m: HashMap<_, (Vec<(IdRow<Partition>, RowRange)>, Vec<InlineTableId>)> =
1142+
HashMap::new();
11421143
for ps in &logical {
11431144
let inline_table_ids = ps
11441145
.iter()
@@ -1178,7 +1179,64 @@ impl ClusterSendExec {
11781179

11791180
let mut r = m.into_iter().collect_vec();
11801181
r.sort_unstable_by(|l, r| l.0.cmp(&r.0));
1181-
r
1182+
r.into_iter()
1183+
.map(|(worker, data)| {
1184+
let splitted = Self::split_worker_parititons(c, data);
1185+
splitted.into_iter().map(move |data| (worker.clone(), data))
1186+
})
1187+
.flatten()
1188+
.collect_vec()
1189+
}
1190+
1191+
fn split_worker_parititons(
1192+
c: &dyn ConfigObj,
1193+
partitions: (Vec<(IdRow<Partition>, RowRange)>, Vec<InlineTableId>),
1194+
) -> Vec<(Vec<(u64, RowRange)>, Vec<InlineTableId>)> {
1195+
if !partitions.1.is_empty()
1196+
|| partitions
1197+
.0
1198+
.iter()
1199+
.any(|(p, _)| p.get_row().multi_partition_id().is_some())
1200+
{
1201+
return vec![(
1202+
partitions
1203+
.0
1204+
.into_iter()
1205+
.map(|(p, range)| (p.id, range))
1206+
.collect_vec(),
1207+
partitions.1,
1208+
)];
1209+
}
1210+
let rows_split_threshold = c.partition_split_threshold() * c.cluster_send_split_threshold();
1211+
let file_size_split_threshold =
1212+
c.partition_size_split_threshold_bytes() * c.cluster_send_split_threshold();
1213+
let mut result = vec![];
1214+
let mut current_rows = 0;
1215+
let mut current_files_size = 0;
1216+
let mut current_chunk = vec![];
1217+
let (partitions, _) = partitions;
1218+
for (partition, range) in partitions {
1219+
let rows = partition.get_row().main_table_row_count();
1220+
let file_size = partition.get_row().file_size().unwrap_or_default();
1221+
if current_rows + rows > rows_split_threshold
1222+
|| current_files_size + file_size > file_size_split_threshold
1223+
{
1224+
if !current_chunk.is_empty() {
1225+
result.push((std::mem::take(&mut current_chunk), vec![]));
1226+
current_rows = 0;
1227+
current_files_size = 0;
1228+
}
1229+
}
1230+
1231+
current_rows += rows;
1232+
current_files_size += file_size;
1233+
current_chunk.push((partition.id, range));
1234+
}
1235+
if !current_chunk.is_empty() {
1236+
result.push((current_chunk, vec![]));
1237+
}
1238+
1239+
result
11821240
}
11831241

11841242
pub fn with_changed_schema(

0 commit comments

Comments
 (0)