Skip to content

Commit

Permalink
perf(pageserver): postpone vectored get fringe keyspace construction (#…
Browse files Browse the repository at this point in the history
…7904)

Perf shows a significant amount of time is spent on `Keyspace::merge`.
This pull request postpones merging keyspace until retrieving the layer,
which contributes to a 30x improvement in aux keyspace basebackup time.

```
--- old
10000 files found in 0.580569459s
--- new
10000 files found in 0.02995075s
```

Signed-off-by: Alex Chi Z <chi@neon.tech>
  • Loading branch information
skyzh authored May 30, 2024
1 parent 1eca8b8 commit 33395dc
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 9 deletions.
17 changes: 12 additions & 5 deletions pageserver/pagebench/src/cmd/aux_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use utils::lsn::Lsn;

use std::collections::HashMap;
use std::sync::Arc;
use std::time::Instant;

/// Ingest aux files into the pageserver.
#[derive(clap::Parser)]
Expand Down Expand Up @@ -88,11 +89,17 @@ async fn main_impl(args: Args) -> anyhow::Result<()> {
println!("ingested {file_cnt} files");
}

let files = mgmt_api_client
.list_aux_files(tenant_shard_id, timeline_id, Lsn(Lsn::MAX.0 - 1))
.await?;

println!("{} files found", files.len());
for _ in 0..100 {
let start = Instant::now();
let files = mgmt_api_client
.list_aux_files(tenant_shard_id, timeline_id, Lsn(Lsn::MAX.0 - 1))
.await?;
println!(
"{} files found in {}s",
files.len(),
start.elapsed().as_secs_f64()
);
}

anyhow::Ok(())
}
17 changes: 13 additions & 4 deletions pageserver/src/tenant/storage_layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ pub(crate) struct LayerFringe {
#[derive(Debug)]
struct LayerKeyspace {
layer: ReadableLayer,
target_keyspace: KeySpace,
target_keyspace: Vec<KeySpace>,
}

impl LayerFringe {
Expand All @@ -336,14 +336,23 @@ impl LayerFringe {
};

let removed = self.layers.remove_entry(&read_desc.layer_id);

match removed {
Some((
_,
LayerKeyspace {
layer,
target_keyspace,
},
)) => Some((layer, target_keyspace, read_desc.lsn_range)),
)) => {
let mut keyspace = KeySpaceRandomAccum::new();
for ks in target_keyspace {
for part in ks.ranges {
keyspace.add_range(part);
}
}
Some((layer, keyspace.consume_keyspace(), read_desc.lsn_range))
}
None => unreachable!("fringe internals are always consistent"),
}
}
Expand All @@ -358,7 +367,7 @@ impl LayerFringe {
let entry = self.layers.entry(layer_id.clone());
match entry {
Entry::Occupied(mut entry) => {
entry.get_mut().target_keyspace.merge(&keyspace);
entry.get_mut().target_keyspace.push(keyspace);
}
Entry::Vacant(entry) => {
self.planned_reads_by_lsn.push(ReadDesc {
Expand All @@ -367,7 +376,7 @@ impl LayerFringe {
});
entry.insert(LayerKeyspace {
layer,
target_keyspace: keyspace,
target_keyspace: vec![keyspace],
});
}
}
Expand Down

1 comment on commit 33395dc

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3238 tests run: 3092 passed, 0 failed, 146 skipped (full report)


Code coverage* (full report)

  • functions: 31.4% (6492 of 20671 functions)
  • lines: 48.4% (50201 of 103758 lines)

* collected from Rust tests only


The comment gets automatically updated with the latest test results
33395dc at 2024-05-30T15:47:10.915Z :recycle:

Please sign in to comment.