From c1cd13d948cb99c336bb67549a3daa9f523e5684 Mon Sep 17 00:00:00 2001 From: Bojan Serafimov Date: Thu, 18 May 2023 17:49:53 -0400 Subject: [PATCH] make 100 layers --- pageserver/benches/bench_disk_lookup.rs | 107 +++++++++++------- pageserver/src/tenant.rs | 1 + pageserver/src/tenant/disk_persistent_bst.rs | 0 .../src/tenant/storage_layer/delta_layer.rs | 3 - 4 files changed, 68 insertions(+), 43 deletions(-) create mode 100644 pageserver/src/tenant/disk_persistent_bst.rs diff --git a/pageserver/benches/bench_disk_lookup.rs b/pageserver/benches/bench_disk_lookup.rs index 664662394e..4797b76ace 100644 --- a/pageserver/benches/bench_disk_lookup.rs +++ b/pageserver/benches/bench_disk_lookup.rs @@ -1,6 +1,6 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion}; use pageserver::{tenant::{disk_btree::{DiskBtreeBuilder, DiskBtreeReader, VisitDirection}, block_io::{BlockBuf, FileBlockReader}, storage_layer::DeltaLayerWriter}, repository::Key, virtual_file::{VirtualFile, self}, page_cache}; -use std::time::Instant; +use std::{time::Instant, collections::BTreeMap}; use rand::prelude::{SeedableRng, SliceRandom, StdRng}; use utils::{id::{TimelineId, TenantId}, lsn::Lsn}; use std::{io::{Read, Write}, path::PathBuf}; @@ -13,34 +13,6 @@ struct MockLayer { } impl MockLayer { - fn make_simple(n_keys: i128) -> Self { - let block_buf = BlockBuf::new(); - let mut writer = DiskBtreeBuilder::<_, 24>::new(block_buf); - for i in 0..n_keys { - let key: Key = Key::from_i128(i); - let value: u64 = i as u64; - - let mut key_bytes: [u8; 24] = [8u8; 24]; - key.write_to_byte_slice(&mut key_bytes); - writer.append(&key_bytes, value).unwrap(); - } - let (index_root_blk, block_buf) = writer.finish().unwrap(); - let index_start_blk = 0; // ??? - let path = std::env::current_dir().unwrap().join("btree.tmp"); - let layer = MockLayer { - path: path.clone(), - index_start_blk, - index_root_blk, - }; - - let mut file = VirtualFile::create(&path).unwrap(); - for buf in block_buf.blocks { - file.write_all(buf.as_ref()).unwrap(); - } - - layer - } - fn read(&self, key: i128) -> Option { // Read from disk btree let file = FileBlockReader::new(VirtualFile::open(&self.path).unwrap()); @@ -66,6 +38,47 @@ impl MockLayer { } } +fn make_simple(n_keys: i128, name: &str) -> MockLayer { + let block_buf = BlockBuf::new(); + let mut writer = DiskBtreeBuilder::<_, 24>::new(block_buf); + for i in 0..n_keys { + let key: Key = Key::from_i128(i); + let value: u64 = i as u64; + + let mut key_bytes: [u8; 24] = [8u8; 24]; + key.write_to_byte_slice(&mut key_bytes); + writer.append(&key_bytes, value).unwrap(); + } + let (index_root_blk, block_buf) = writer.finish().unwrap(); + let index_start_blk = 0; // ??? + let path = std::env::current_dir().unwrap() + .parent().unwrap() + .join("test_output") + .join("bench_disk_lookup") + .join("disk_btree") + .join(name); + std::fs::create_dir_all(path.clone().parent().unwrap()).unwrap(); + let layer = MockLayer { + path: path.clone(), + index_start_blk, + index_root_blk, + }; + + let mut file = VirtualFile::create(&path).unwrap(); + for buf in block_buf.blocks { + file.write_all(buf.as_ref()).unwrap(); + } + + layer +} + +fn make_many(n_keys: i128, n_layers: i128) -> Vec { + (0..n_layers) + .map(|i| make_simple(n_keys, &format!("layer_{}.tmp", i))) + .collect() +} + + // cargo bench --bench bench_disk_lookup fn bench_disk_lookup(c: &mut Criterion) { virtual_file::init(10); @@ -74,27 +87,41 @@ fn bench_disk_lookup(c: &mut Criterion) { // Results in a 40MB index let n_keys = 4_000_000; + // One layer for each query + let n_layers = 100; + let n_queries = n_layers; + // Write to disk btree - let layer = MockLayer::make_simple(n_keys); + let layers = make_many(n_keys, n_layers); + + // Write to mem btrees + let mem_btrees: Vec> = (0..n_layers) + .map(|_| (0..n_keys) + .map(|i| (i as i128, i as u64)) + .collect()) + .collect(); // Pick queries let rng = &mut StdRng::seed_from_u64(1); let queries: Vec<_> = (0..n_keys).collect(); - let queries: Vec<_> = queries.choose_multiple(rng, 100).copied().collect(); - - let now = Instant::now(); - black_box({ - assert_eq!(layer.read(queries[0]), Some(queries[0] as u64)); - }); - println!("Finished one query in {:?}", now.elapsed()); + let queries: Vec<_> = queries.choose_multiple(rng, n_queries as usize).copied().collect(); // Define and name the benchmark function let mut group = c.benchmark_group("g1"); - group.bench_function("f1", |b| { + group.bench_function("disk_btree", |b| { b.iter(|| { - for q in queries.clone().into_iter() { + for (i, q) in queries.clone().into_iter().enumerate() { black_box({ - assert_eq!(layer.read(q), Some(q as u64)); + assert_eq!(layers[i].read(q), Some(q as u64)); + }) + } + }); + }); + group.bench_function("mem_btree", |b| { + b.iter(|| { + for (i, q) in queries.clone().into_iter().enumerate() { + black_box({ + assert_eq!(mem_btrees[i].get(&q), Some(&(q as u64))); }) } }); diff --git a/pageserver/src/tenant.rs b/pageserver/src/tenant.rs index 8349e1993f..7b94d41aa6 100644 --- a/pageserver/src/tenant.rs +++ b/pageserver/src/tenant.rs @@ -80,6 +80,7 @@ use utils::{ mod blob_io; pub mod block_io; pub mod disk_btree; +pub mod disk_persistent_bst; pub(crate) mod ephemeral_file; pub mod layer_map; diff --git a/pageserver/src/tenant/disk_persistent_bst.rs b/pageserver/src/tenant/disk_persistent_bst.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pageserver/src/tenant/storage_layer/delta_layer.rs b/pageserver/src/tenant/storage_layer/delta_layer.rs index 9657678ae5..ba3ab6dd4c 100644 --- a/pageserver/src/tenant/storage_layer/delta_layer.rs +++ b/pageserver/src/tenant/storage_layer/delta_layer.rs @@ -709,9 +709,6 @@ impl DeltaLayerWriterInner { // FIXME: throw an error instead? let path = DeltaLayer::temp_path_for(conf, timeline_id, tenant_id, key_start, &lsn_range); - // HACK - fs::create_dir_all(path.clone().parent().unwrap())?; - let mut file = VirtualFile::create(&path)?; // make room for the header block file.seek(SeekFrom::Start(PAGE_SZ as u64))?;