From 124fd08a1077389eaaf292941b9346123bcdc584 Mon Sep 17 00:00:00 2001 From: Chen Chen Date: Wed, 24 Jul 2024 15:10:24 -0500 Subject: [PATCH] *: revise docs and stores; add mixed example --- README.md | 42 ++++++++++-------------- examples/mixed/mixed.pdf | Bin 0 -> 17775 bytes examples/mixed/plot.gpl | 15 +++++++++ examples/mixed/run.sh | 14 ++++++++ presets/benchmarks/mixed.toml | 49 +++++++++++++++++++++++++++ src/cmdline.rs | 60 ++++++++++++++++++++++++++++++++-- src/server.rs | 41 ++++++++++++----------- src/stores/chashmap.rs | 10 ++++++ src/stores/contrie.rs | 11 +++++++ src/stores/dashmap.rs | 11 +++++++ src/stores/flurry.rs | 11 +++++++ src/stores/hashmap.rs | 24 ++++++++++++++ src/stores/mod.rs | 35 ++++++++------------ src/stores/null.rs | 23 ++++++++++++- src/stores/papaya.rs | 11 +++++++ src/stores/remote.rs | 13 ++++++++ src/stores/scc.rs | 10 ++++++ src/thread.rs | 2 +- 18 files changed, 310 insertions(+), 72 deletions(-) create mode 100644 examples/mixed/mixed.pdf create mode 100644 examples/mixed/plot.gpl create mode 100755 examples/mixed/run.sh create mode 100644 presets/benchmarks/mixed.toml diff --git a/README.md b/README.md index f88b7a3..53fdf03 100644 --- a/README.md +++ b/README.md @@ -6,40 +6,32 @@ A benchmarking framework designed for testing key-value stores with easily customizable workloads. -## Intro +## Introduction -This Rust crate enables the execution of tailored benchmarks on various key-value stores. Users -have the flexibility to adjust benchmark and key-value store parameters and store them in a -TOML-formatted file. The default command line interface is capable of loading these files and +This Rust crate enables the execution of customizable benchmarks on various key-value stores. +Users have the flexibility to adjust benchmark and key-value store parameters and store them +in TOML-formatted files. The built-in command line interface is capable of loading these files and running the benchmarks as specified. -In addition to standard single-process benchmarks, kvbench seamlessly incorporates a key-value -client/server setup that operates with a dedicated server thread/machine. +In addition to standard single-process benchmarks, it also seamlessly incorporates a key-value +client/server setup that operates with a dedicated server thread or machine. ## Usage -Without any changes, you can run the default command line interface with three modes: +The [Documentation](https://docs.rs/kvbench) provides detailed usage guidelines. -- `kvbench bench -s -b ` runs a (group of) benchmark using the parameters -stored in `` and ``. -- `kvbench server -h -p -s -n ` boots up a key-value server -with `` workers, listening on `:`, and uses the key-value stores specified in -``. -- `kvbench list` lists all registered key-value stores that can be used. +## Examples -See [examples](examples/) for more examples. +- [examples/your-kv-store](examples/your-kv-store): How to integrate `kvbench` into your own +key-value store implementations. +- [examples/readpopular](examples/readpopular): A benchmark that reads popular records in +the store, running with different number of threads. +- [examples/writeheavy](examples/writeheavy): A benchmark that mixes reads and writes at 1:1 +on a random record in the store, running with different number of threads. +- [examples/mixed](examples/mixed): A benchmark that consists of multiple phases (5 seconds +running time each), benchmarked with 32 threads. -## Configuration - -See the documentation of the modules `stores` and `bench` for available options. - -## Integration - -You can incorporate `kvbench` into your own key-value store implementations and run it -against the built-in stores. All you need is implementing the necessary traits, depending on the -type of the store, and call the default command line interface provided by this crate. - -See [examples/your-kv-store](examples/your-kv-store) for a minimal but concrete example. +The built-in configuration files used by the above benchmarks can be found in [presets](presets). ## Development diff --git a/examples/mixed/mixed.pdf b/examples/mixed/mixed.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b275a56cd531ab953454022103d34db6dfcb9d76 GIT binary patch literal 17775 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 literal 0 HcmV?d00001 diff --git a/examples/mixed/plot.gpl b/examples/mixed/plot.gpl new file mode 100644 index 0000000..54ca286 --- /dev/null +++ b/examples/mixed/plot.gpl @@ -0,0 +1,15 @@ +set terminal pdf +set ylabel "Throughput (MOP/s)" +set xlabel "Time (sec)" +set key left top + +set output "mixed.pdf" +plot [0:21] [0:] \ + "chashmap.txt" using ($1*$7+1):13 with lp ti "chashmap",\ + "contrie.txt" using ($1*$7+1):13 with lp ti "contrie",\ + "dashmap.txt" using ($1*$7+1):13 with lp ti "dashmap",\ + "flurry.txt" using ($1*$7+1):13 with lp ti "flurry",\ + "papaya.txt" using ($1*$7+1):13 with lp ti "papaya",\ + "scchashmap.txt" using ($1*$7+1):13 with lp ti "scchashmap",\ + "mutex_hashmap.txt" using ($1*$7+1):13 with lp ti "mutexhashmap",\ + "rwlock_hashmap.txt" using ($1*$7+1):13 with lp ti "rwlockhashmap" diff --git a/examples/mixed/run.sh b/examples/mixed/run.sh new file mode 100755 index 0000000..4b76da9 --- /dev/null +++ b/examples/mixed/run.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DIR="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" + +cargo build --profile release-lto + +STORE_DIR=$DIR/../../presets/stores +BENCHMARK=$DIR/../../presets/benchmarks/mixed.toml + +STORES="chashmap contrie dashmap flurry papaya scchashmap mutex_hashmap rwlock_hashmap" + +for s in $STORES; do + env global.threads=32 cargo run --profile release-lto -- bench -s $STORE_DIR/$s.toml -b $BENCHMARK 2>/dev/null | tee $s.txt +done diff --git a/presets/benchmarks/mixed.toml b/presets/benchmarks/mixed.toml new file mode 100644 index 0000000..688049c --- /dev/null +++ b/presets/benchmarks/mixed.toml @@ -0,0 +1,49 @@ +[global] +threads = 1 +repeat = 5 +klen = 8 +vlen = 16 +kmin = 0 +kmax = 1000000 +report = "repeat" + +[[benchmark]] +set_perc = 100 +get_perc = 0 +del_perc = 0 +repeat = 1 +dist = "incrementp" +report = "hidden" + +# write-intensive, zipfian +[[benchmark]] +set_perc = 50 +get_perc = 50 +del_perc = 0 +timeout = 1.0 +dist = "zipfian" + +# write-intensive, zipfian, hotspot in middle +[[benchmark]] +set_perc = 50 +get_perc = 50 +del_perc = 0 +timeout = 1.0 +dist = "zipfian" +zipf_hotspot = 0.5 + +# read-intensive, zipfian +[[benchmark]] +set_perc = 5 +get_perc = 95 +del_perc = 0 +timeout = 1.0 +dist = "zipfian" + +# read-only, uniform +[[benchmark]] +set_perc = 0 +get_perc = 100 +del_perc = 0 +timeout = 1.0 +dist = "uniform" diff --git a/src/cmdline.rs b/src/cmdline.rs index fa26b82..0d84871 100644 --- a/src/cmdline.rs +++ b/src/cmdline.rs @@ -9,26 +9,32 @@ use std::sync::mpsc::channel; struct BenchArgs { #[arg(short = 's')] #[arg(value_hint = FilePath)] + #[arg(help = "Path to the key-value store's TOML config file")] store_config: String, #[arg(short = 'b')] #[arg(value_hint = FilePath)] + #[arg(help = "Path to the benchmark's TOML config file")] benchmark_config: String, } #[derive(Args, Debug)] struct ServerArgs { - #[arg(short = 'h', default_value = "0.0.0.0")] + #[arg(short = 'a', default_value = "0.0.0.0")] + #[arg(help = "Bind address")] host: String, #[arg(short = 'p', default_value = "9000")] + #[arg(help = "Bind port")] port: String, #[arg(short = 's')] #[arg(value_hint = FilePath)] + #[arg(help = "Path to the key-value store's TOML config file")] store_config: String, #[arg(short = 'n', default_value_t = 1)] + #[arg(help = "Number of worker threads")] workers: usize, } @@ -41,8 +47,11 @@ struct Cli { #[derive(Subcommand, Debug)] enum Commands { - Server(ServerArgs), + #[command(about = "Run a benchmark")] Bench(BenchArgs), + #[command(about = "Start a key-value server")] + Server(ServerArgs), + #[command(about = "List all registered key-value stores")] List, } @@ -98,6 +107,53 @@ fn list_cli() { /// This function is public and can be called in a different crate. For example, one can integrate /// their own key-value stores by registering the constructor function. Then, adding this function /// will produce a benchmark binary the has the same usage as the one in this crate. +/// +/// ## Usage +/// +/// To get the usage of the command line interface, users can run: +/// +/// ```bash +/// kvbench -h +/// ``` +/// +/// The interface supports three modes, `bench`, `server` and `list`. +/// +/// ### Benchmark Mode +/// +/// Usage: +/// +/// ```bash +/// kvbench bench -s -b +/// ``` +/// +/// Where `STORE_CONFIG` and `BENCH_CONFIG` are the paths to the key-value store and benchmark +/// configuration files, respectively. For their format, you can refer to the documentations of +/// [`crate::stores`] and [`crate::bench`]. +/// +/// ### Server mode +/// +/// Usage: +/// +/// ```bash +/// kvbench server -s -a -p -n +/// ``` +/// +/// Where `STORE_CONFIG` is the path of the key-value store configuration file. Its format is +/// documented in [`crate::stores`]. +/// +/// The default `HOST` and `PORT` are `0.0.0.0` and `9000`. By default, the server will spawn one +/// worker thread only for incoming connections. You can adjust the number of worker threads by +/// specifying `-n`. +/// +/// ### List mode +/// +/// Usage: +/// ``` bash +/// kvbench list +/// ``` +/// +/// This command lists all registered key-value stores' names. + pub fn cmdline() { env_logger::init(); let cli = Cli::parse(); diff --git a/src/server.rs b/src/server.rs index 834f32d..313eec0 100644 --- a/src/server.rs +++ b/src/server.rs @@ -652,7 +652,6 @@ pub fn init(text: &str) -> BenchKVMap { #[cfg(test)] mod tests { use super::*; - use crate::stores::*; use std::sync::atomic::{AtomicU32, Ordering}; use std::sync::mpsc::{channel, Receiver, Sender}; @@ -711,51 +710,51 @@ mod tests { #[test] fn simple_mutex() { - let opt = MutexHashMapOpt { shards: 512 }; - let map = BenchKVMap::Regular(Box::new(MutexHashMap::new(&opt))); + let opt = hashmap::MutexHashMapOpt { shards: 512 }; + let map = BenchKVMap::Regular(Box::new(hashmap::MutexHashMap::new(&opt))); simple(map); } #[test] fn simple_rwlock() { - let opt = RwLockHashMapOpt { shards: 512 }; - let map = BenchKVMap::Regular(Box::new(RwLockHashMap::new(&opt))); + let opt = hashmap::RwLockHashMapOpt { shards: 512 }; + let map = BenchKVMap::Regular(Box::new(hashmap::RwLockHashMap::new(&opt))); simple(map); } #[test] fn simple_dashmap() { - let map = BenchKVMap::Regular(Box::new(DashMap::new())); + let map = BenchKVMap::Regular(Box::new(dashmap::DashMap::new())); simple(map); } #[test] fn simple_contrie() { - let map = BenchKVMap::Regular(Box::new(Contrie::new())); + let map = BenchKVMap::Regular(Box::new(contrie::Contrie::new())); simple(map); } #[test] fn simple_chashmap() { - let map = BenchKVMap::Regular(Box::new(CHashMap::new())); + let map = BenchKVMap::Regular(Box::new(chashmap::CHashMap::new())); simple(map); } #[test] fn simple_scchashmap() { - let map = BenchKVMap::Regular(Box::new(SccHashMap::new())); + let map = BenchKVMap::Regular(Box::new(scc::SccHashMap::new())); simple(map); } #[test] fn simple_flurry() { - let map = BenchKVMap::Regular(Box::new(Flurry::new())); + let map = BenchKVMap::Regular(Box::new(flurry::Flurry::new())); simple(map); } #[test] fn simple_papaya() { - let map = BenchKVMap::Regular(Box::new(Papaya::new())); + let map = BenchKVMap::Regular(Box::new(papaya::Papaya::new())); simple(map); } @@ -849,51 +848,51 @@ mod tests { #[test] fn batch_mutex() { - let opt = MutexHashMapOpt { shards: 512 }; - let map = BenchKVMap::Regular(Box::new(MutexHashMap::new(&opt))); + let opt = hashmap::MutexHashMapOpt { shards: 512 }; + let map = BenchKVMap::Regular(Box::new(hashmap::MutexHashMap::new(&opt))); batch(map); } #[test] fn batch_rwlock() { - let opt = RwLockHashMapOpt { shards: 512 }; - let map = BenchKVMap::Regular(Box::new(RwLockHashMap::new(&opt))); + let opt = hashmap::RwLockHashMapOpt { shards: 512 }; + let map = BenchKVMap::Regular(Box::new(hashmap::RwLockHashMap::new(&opt))); batch(map); } #[test] fn batch_dashmap() { - let map = BenchKVMap::Regular(Box::new(DashMap::new())); + let map = BenchKVMap::Regular(Box::new(dashmap::DashMap::new())); batch(map); } #[test] fn batch_contrie() { - let map = BenchKVMap::Regular(Box::new(Contrie::new())); + let map = BenchKVMap::Regular(Box::new(contrie::Contrie::new())); batch(map); } #[test] fn batch_chashmap() { - let map = BenchKVMap::Regular(Box::new(CHashMap::new())); + let map = BenchKVMap::Regular(Box::new(chashmap::CHashMap::new())); batch(map); } #[test] fn batch_scchashmap() { - let map = BenchKVMap::Regular(Box::new(SccHashMap::new())); + let map = BenchKVMap::Regular(Box::new(scc::SccHashMap::new())); batch(map); } #[test] fn batch_flurry() { - let map = BenchKVMap::Regular(Box::new(Flurry::new())); + let map = BenchKVMap::Regular(Box::new(flurry::Flurry::new())); batch(map); } #[test] fn batch_papaya() { - let map = BenchKVMap::Regular(Box::new(Papaya::new())); + let map = BenchKVMap::Regular(Box::new(papaya::Papaya::new())); batch(map); } } diff --git a/src/stores/chashmap.rs b/src/stores/chashmap.rs index 0287d9d..7280b7e 100644 --- a/src/stores/chashmap.rs +++ b/src/stores/chashmap.rs @@ -1,3 +1,13 @@ +//! Adapter implementation of [`chashmap::CHashMap`]. +//! +//! ## Configuration Format +//! +//! ``` toml +//! [map] +//! name = "chashmap" +//! ``` +//! This store is [`KVMap`]. + use crate::stores::{BenchKVMap, Registry}; use crate::*; diff --git a/src/stores/contrie.rs b/src/stores/contrie.rs index 8e5db82..be37bb6 100644 --- a/src/stores/contrie.rs +++ b/src/stores/contrie.rs @@ -1,3 +1,14 @@ +//! Adapter implementation of [`contrie::ConMap`]. +//! +//! ## Configuration Format +//! +//! ``` toml +//! [map] +//! name = "contrie" +//! ``` +//! +//! This store is [`KVMap`]. + use crate::stores::{BenchKVMap, Registry}; use crate::*; diff --git a/src/stores/dashmap.rs b/src/stores/dashmap.rs index 8a87bf3..ffa9940 100644 --- a/src/stores/dashmap.rs +++ b/src/stores/dashmap.rs @@ -1,3 +1,14 @@ +//! Adapter implementation of [`dashmap::DashMap`]. +//! +//! ## Configuration Format +//! +//! ``` toml +//! [map] +//! name = "dashmap" +//! ``` +//! +//! This store is [`KVMap`]. + use crate::stores::{BenchKVMap, Registry}; use crate::*; diff --git a/src/stores/flurry.rs b/src/stores/flurry.rs index 9ef1fff..3b918e8 100644 --- a/src/stores/flurry.rs +++ b/src/stores/flurry.rs @@ -1,3 +1,14 @@ +//! Adapter implementation of [`flurry::HashMap`]. +//! +//! ## Configuration Format +//! +//! ``` toml +//! [map] +//! name = "flurry" +//! ``` +//! +//! This store is [`KVMap`]. + use crate::stores::{BenchKVMap, Registry}; use crate::*; diff --git a/src/stores/hashmap.rs b/src/stores/hashmap.rs index ee12de8..e4c031f 100644 --- a/src/stores/hashmap.rs +++ b/src/stores/hashmap.rs @@ -1,3 +1,27 @@ +//! Adapter implementation of [`hashbrown::HashMap`]. Sharded, and in flavors of both [`Mutex`] and +//! [`RwLock`]. +//! +//! ## Configuration Format +//! +//! ### [`Mutex`]-based: +//! +//! ``` toml +//! [map] +//! name = "mutex_hashmap" +//! shards = ... # number of shards +//! ``` +//! +//! This store is [`KVMap`]. +//! +//! ### [`RwLock`]-based: +//! ``` toml +//! [map] +//! name = "rwlock_hashmap" +//! shards = ... # number of shards +//! ``` +//! +//! This store is [`KVMap`]. + use crate::stores::*; use ::hashbrown::HashMap; use parking_lot::{Mutex, RwLock}; diff --git a/src/stores/mod.rs b/src/stores/mod.rs index 7ff6e2f..0630cd2 100644 --- a/src/stores/mod.rs +++ b/src/stores/mod.rs @@ -15,7 +15,8 @@ //! ``` //! The field `name` must be given and it should be equal to the name registered by the store. //! Other than `name`, all the fields are parsed as a string map and will be hand over to the -//! constructor of the store's constructor function. +//! constructor of the store's constructor function. For available options other than `name`, one +//! can refer to the module-level documentation of a specific store. //! //! ## Registering New Stores //! @@ -123,16 +124,6 @@ pub mod papaya; pub mod remote; pub mod scc; -pub use chashmap::*; -pub use contrie::*; -pub use dashmap::*; -pub use flurry::*; -pub use hashmap::*; -pub use null::*; -pub use papaya::*; -pub use remote::*; -pub use scc::*; - #[cfg(test)] mod tests { use super::*; @@ -155,57 +146,57 @@ mod tests { #[test] fn nullmap() { - let mut map = NullMap::new(); + let mut map = null::NullMap::new(); assert!(map.get("foo".as_bytes().into()).is_none()); } #[test] fn mutex_hashmap() { - let opt = MutexHashMapOpt { shards: 512 }; - let mut map = MutexHashMap::new(&opt); + let opt = hashmap::MutexHashMapOpt { shards: 512 }; + let mut map = hashmap::MutexHashMap::new(&opt); map_test(&mut map); } #[test] fn rwlock_hashmap() { - let opt = RwLockHashMapOpt { shards: 512 }; - let mut map = RwLockHashMap::new(&opt); + let opt = hashmap::RwLockHashMapOpt { shards: 512 }; + let mut map = hashmap::RwLockHashMap::new(&opt); map_test(&mut map); } #[test] fn dashmap() { - let mut map = DashMap::new(); + let mut map = dashmap::DashMap::new(); map_test(&mut map); } #[test] fn contrie() { - let mut map = Contrie::new(); + let mut map = contrie::Contrie::new(); map_test(&mut map); } #[test] fn chashmap() { - let mut map = CHashMap::new(); + let mut map = chashmap::CHashMap::new(); map_test(&mut map); } #[test] fn scchashmap() { - let mut map = SccHashMap::new(); + let mut map = scc::SccHashMap::new(); map_test(&mut map); } #[test] fn flurry() { - let mut map = Flurry::new(); + let mut map = flurry::Flurry::new(); map_test(&mut map); } #[test] fn papaya() { - let mut map = Papaya::new(); + let mut map = papaya::Papaya::new(); map_test(&mut map); } } diff --git a/src/stores/null.rs b/src/stores/null.rs index 1e961e7..2c150d6 100644 --- a/src/stores/null.rs +++ b/src/stores/null.rs @@ -1,7 +1,28 @@ +//! A store that does nothing. It can be used to measure overheads of the crate. +//! +//! ## Configuration Format +//! +//! ### Regular +//! +//! ``` toml +//! [map] +//! name = "nullmap" +//! ``` +//! +//! This store is [`KVMap`]. +//! +//! ### Async +//! +//! ``` toml +//! [map] +//! name = "nullmap_async" +//! ``` +//! +//! This store is [`AsyncKVMap`]. + use crate::stores::{BenchKVMap, Registry}; use crate::*; -/// It does nothing. It can be used to measure overheads in the future. #[derive(Clone)] pub struct NullMap; diff --git a/src/stores/papaya.rs b/src/stores/papaya.rs index 96b1a16..e08ae2e 100644 --- a/src/stores/papaya.rs +++ b/src/stores/papaya.rs @@ -1,3 +1,14 @@ +//! Adapter implementation of [`papaya::HashMap`]. +//! +//! ## Configuration Format +//! +//! ``` toml +//! [map] +//! name = "papaya" +//! ``` +//! +//! This store is [`KVMap`]. + use crate::stores::{BenchKVMap, Registry}; use crate::*; diff --git a/src/stores/remote.rs b/src/stores/remote.rs index 1ed950e..15b24ac 100644 --- a/src/stores/remote.rs +++ b/src/stores/remote.rs @@ -1,3 +1,16 @@ +//! A client of a key-value server. The server can be backed by any stores available. +//! +//! ## Configuration Format +//! +//! ``` toml +//! [map] +//! name = "remote" +//! host = "..." # hostname of the server +//! port = "..." # port of the server +//! ``` +//! +//! This store is [`AsyncKVMap`]. + use crate::server::KVClient; use crate::stores::{BenchKVMap, Registry}; use crate::*; diff --git a/src/stores/scc.rs b/src/stores/scc.rs index 426fec6..15e5493 100644 --- a/src/stores/scc.rs +++ b/src/stores/scc.rs @@ -1,3 +1,13 @@ +//! Adapter implementation of [`scc::hash_map::HashMap`]. +//! +//! ## Configuration Format +//! +//! ``` toml +//! [map] +//! name = "scchashmap" +//! ``` +//! This store is [`KVMap`]. + use crate::stores::{BenchKVMap, Registry}; use crate::*; diff --git a/src/thread.rs b/src/thread.rs index 86420c0..e71a037 100644 --- a/src/thread.rs +++ b/src/thread.rs @@ -2,7 +2,7 @@ //! //! **You may not need to check this if it is OK to run benchmarks with [`std::thread`].** //! -//! A [`KVMap`] implementation is generally passive. However, some store may act like a server with +//! A key-value store is generally passive. However, some store may act like a server with //! active threads. In that case, one may employ its own implementation of spawn-join. If that is //! the case, their join handle (like `[std::thread::JoinHandle`]) should implement the //! [`JoinHandle`] trait and the spawn struct needs to implement `[Spawn]`.