Add stress testing for `set` queries

next
Sayan Nandan 3 years ago
parent f416c7f50c
commit d39f2dcda5

84
Cargo.lock generated

@ -108,6 +108,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b"
[[package]]
name = "crossbeam-channel"
version = "0.5.1"
@ -215,6 +221,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "doc-comment"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
[[package]]
name = "either"
version = "1.6.1"
@ -229,9 +241,9 @@ checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d"
[[package]]
name = "env_logger"
version = "0.8.3"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f"
checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3"
dependencies = [
"atty",
"humantime",
@ -445,9 +457,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.96"
version = "0.2.97"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5600b4e6efc5421841a2138a6b082e07fe12f9aaa12783d50e5d13325b26b4fc"
checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6"
[[package]]
name = "libsky"
@ -464,7 +476,9 @@ name = "libstress"
version = "0.1.0"
dependencies = [
"crossbeam-channel",
"log",
"num_cpus",
"rand",
"rayon",
]
@ -503,9 +517,9 @@ dependencies = [
[[package]]
name = "mio"
version = "0.7.11"
version = "0.7.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf80d3e903b34e0bd7282b218398aec54e082c840d9baf8339e0080a0c542956"
checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16"
dependencies = [
"libc",
"log",
@ -584,9 +598,9 @@ dependencies = [
[[package]]
name = "once_cell"
version = "1.7.2"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
[[package]]
name = "openssl"
@ -736,9 +750,9 @@ dependencies = [
[[package]]
name = "rand"
version = "0.8.3"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e"
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
dependencies = [
"libc",
"rand_chacha",
@ -748,9 +762,9 @@ dependencies = [
[[package]]
name = "rand_chacha"
version = "0.3.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
@ -758,18 +772,18 @@ dependencies = [
[[package]]
name = "rand_core"
version = "0.6.2"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_hc"
version = "0.3.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
dependencies = [
"rand_core",
]
@ -801,9 +815,9 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.2.8"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "742739e41cd49414de871ea5e549afb7e2a3ac77b589bcbebe8c82fab37147fc"
checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee"
dependencies = [
"bitflags",
]
@ -999,7 +1013,7 @@ dependencies = [
[[package]]
name = "skytable"
version = "0.3.0"
source = "git+https://github.com/skytable/client-rust?branch=next#acf41607ebb883e539e5e2663341c2fbcf04a97f"
source = "git+https://github.com/skytable/client-rust?branch=next#90a72c862bc0e618713bb3480146ea10c3451347"
dependencies = [
"bytes",
"tokio",
@ -1027,8 +1041,12 @@ checksum = "d44a3643b4ff9caf57abcee9c2c621d6c03d9135e0d8b589bd9afb5992cb176a"
name = "stress-test"
version = "0.1.0"
dependencies = [
"env_logger",
"libstress",
"log",
"rand",
"skytable",
"sysinfo",
]
[[package]]
@ -1039,15 +1057,31 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "syn"
version = "1.0.72"
version = "1.0.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82"
checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "sysinfo"
version = "0.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d404aefa651a24a7f2a1190fec9fb6380ba84ac511a6fefad79eb0e63d39a97d"
dependencies = [
"cfg-if",
"core-foundation-sys",
"doc-comment",
"libc",
"ntapi",
"once_cell",
"rayon",
"winapi",
]
[[package]]
name = "termcolor"
version = "1.1.2"
@ -1079,9 +1113,9 @@ dependencies = [
[[package]]
name = "tokio"
version = "1.6.1"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a38d31d7831c6ed7aad00aa4c12d9375fd225a6dd77da1d25b707346319a975"
checksum = "c79ba603c337335df6ba6dd6afc38c38a7d5e1b0c871678439ea973cd62a118e"
dependencies = [
"autocfg",
"bytes",
@ -1155,9 +1189,9 @@ checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372"
[[package]]
name = "vcpkg"
version = "0.2.13"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "025ce40a007e1907e58d5bc1a594def78e5573bb0b1160bc389634e8f12e4faa"
checksum = "70455df2fdf4e9bf580a92e443f1eb0303c390d682e2ea817312c9e81f8c3399"
[[package]]
name = "vec_map"

@ -11,3 +11,5 @@ edition = "2018"
num_cpus = "1.13.0"
crossbeam-channel = "0.5.1"
rayon = "1.5.1"
log = "0.4.14"
rand = "0.8.3"

@ -58,6 +58,7 @@
#![deny(unused_crate_dependencies)]
#![deny(unused_imports)]
pub mod traits;
use core::marker::PhantomData;
use crossbeam_channel::unbounded;
use crossbeam_channel::Receiver as CReceiver;
@ -264,3 +265,15 @@ impl<Inp, UIn, Lv, Lp, Ex> Drop for Workpool<Inp, UIn, Lp, Lv, Ex> {
}
}
}
pub mod utils {
use rand::distributions::Alphanumeric;
pub fn ran_string(len: usize, rand: impl rand::Rng) -> String {
let rand_string: String = rand
.sample_iter(&Alphanumeric)
.take(len)
.map(char::from)
.collect();
rand_string
}
}

@ -0,0 +1,69 @@
/*
* Created on Fri Jun 18 2021
*
* This file is a part of Skytable
* Skytable (formerly known as TerrabaseDB or Skybase) is a free and open-source
* NoSQL database written by Sayan Nandan ("the Author") with the
* vision to provide flexibility in data modelling without compromising
* on performance, queryability or scalability.
*
* Copyright (c) 2021, Sayan Nandan <ohsayan@outlook.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
use std::fmt;
/// A trait for aggresive erroring
pub trait ExitError<T> {
/// Abort the process if the type errors with an error code or
/// return the type
fn exit_error<Ms>(self, msg: Ms) -> T
where
Ms: ToString;
}
impl<T, E> ExitError<T> for Result<T, E>
where
E: fmt::Display,
{
fn exit_error<Ms>(self, msg: Ms) -> T
where
Ms: ToString,
{
match self {
Self::Err(e) => {
log::error!("{} : '{}'", msg.to_string(), e);
std::process::exit(0x100);
}
Self::Ok(v) => v,
}
}
}
impl<T> ExitError<T> for Option<T> {
fn exit_error<Ms>(self, msg: Ms) -> T
where
Ms: ToString,
{
match self {
Self::None => {
log::error!("{}", msg.to_string());
std::process::exit(0x100);
}
Self::Some(v) => v,
}
}
}

@ -16,4 +16,4 @@ rand = "0.8.3"
devtimer = "4.0.1"
clap = { version="2.33.3", features=["yaml"] }
serde = { version="1.0.126", features=["derive"] }
serde_json = "1.0.64"
serde_json = "1.0.64"

@ -27,9 +27,9 @@
use crate::hoststr;
use crate::sanity_test;
use crate::util::calc;
use crate::util::ran_string;
use crate::util::JSONReportBlock;
use devtimer::DevTime;
use libstress::utils::ran_string;
use libstress::Workpool;
use rand::thread_rng;
use std::io::{Read, Write};

@ -26,7 +26,7 @@
use crate::hoststr;
use crate::sanity_test;
use crate::util::ran_string;
use libstress::utils::ran_string;
use libstress::Workpool;
use rand::thread_rng;
use std::io::{Read, Write};

@ -24,7 +24,7 @@
*
*/
use rand::distributions::Alphanumeric;
use libstress::utils::ran_string;
use rand::thread_rng;
use serde::Serialize;
use std::error::Error;
@ -96,15 +96,6 @@ pub fn calc(reqs: usize, time: u128) -> f64 {
reqs as f64 / (time as f64 / 1_000_000_000_f64)
}
pub fn ran_string(len: usize, rand: impl rand::Rng) -> String {
let rand_string: String = rand
.sample_iter(&Alphanumeric)
.take(len)
.map(char::from)
.collect();
rand_string
}
/// # Sanity Test
///
/// This function performs a 'sanity test' to determine if the benchmarks should be run; this test ensures

@ -7,5 +7,11 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
libstress = {path = "../libstress"}
skytable = {git = "https://github.com/skytable/client-rust.git", branch = "next"}
# internal deps
libstress = { path="../libstress" }
skytable = { git="https://github.com/skytable/client-rust.git", branch="next", features=["dbg"] }
sysinfo = "0.18.2"
# external deps
env_logger = "0.8.4"
log = "0.4.14"
rand = "*"

@ -27,23 +27,123 @@
#![deny(unused_crate_dependencies)]
#![deny(unused_imports)]
use libstress::traits::ExitError;
use libstress::utils::ran_string;
use libstress::Workpool;
use log::{info, trace};
use rand::thread_rng;
use skytable::actions::Actions;
use skytable::Connection;
use skytable::Query;
use skytable::{Element, Response};
use std::env;
use std::sync::Arc;
use std::sync::Mutex;
use sysinfo::{System, SystemExt};
pub const DEFAULT_SIZE_KV: usize = 4;
pub const DEFAULT_QUERY_COUNT: usize = 100_000_usize;
macro_rules! logstress {
($stressid:expr, $extra:expr) => {
log::info!("Stress ({}): {}", stringify!($stressid), $extra);
};
}
macro_rules! log_client_linearity {
($stressid:expr, $counter:expr) => {
log::info!(
"Stress ({}{}): Clients: {}; K/V size: {}; Queries: {}",
stringify!($stressid),
$counter,
$counter,
DEFAULT_SIZE_KV,
DEFAULT_QUERY_COUNT
);
};
}
fn main() {
let pool = Workpool::new(
10,
|| Connection::new("127.0.0.1", 2003).unwrap(),
|con, query| {
let ret = con.run_simple_query(&query).unwrap();
assert_eq!(ret, Response::Item(Element::String("HEY!".to_owned())));
},
|_| {},
false,
);
env_logger::Builder::new()
.parse_filters(&env::var("SKY_LOG").unwrap_or_else(|_| "trace".to_owned()))
.init();
let mut rng = thread_rng();
stress_linearity_concurrent_clients(&mut rng);
info!("SUCCESS. Stress test complete!");
}
fn stress_linearity_concurrent_clients(mut rng: &mut impl rand::Rng) {
logstress!(A, "Linearity test with monotonically increasing clients");
let mut sys = System::new_all();
sys.refresh_all();
let num_workers = sys
.get_physical_core_count()
.exit_error("Failed to get physical core count")
* 2;
trace!("Will spawn a maximum of {} workers", num_workers * 2);
let mut current_thread_count = 1usize;
let mut temp_con = Connection::new("127.0.0.1", 2003).exit_error("Failed to connect to server");
temp_con.flushdb().unwrap();
let keys: Vec<String> = (0..DEFAULT_QUERY_COUNT)
.into_iter()
.map(|_| ran_string(DEFAULT_SIZE_KV, &mut rng))
.collect();
let values: Vec<String> = (0..DEFAULT_QUERY_COUNT)
.into_iter()
.map(|_| ran_string(DEFAULT_SIZE_KV, &mut rng))
.collect();
while current_thread_count < (num_workers + 1) {
log_client_linearity!(A, current_thread_count);
let set_packs: Vec<Query> = keys
.iter()
.zip(values.iter())
.map(|(k, v)| {
let mut q = Query::from("SET");
q.push(k);
q.push(v);
q
})
.collect();
let responses = Arc::new(Mutex::new(Vec::new()));
let workpool = Workpool::new(
current_thread_count,
|| Connection::new("127.0.0.1", 2003).unwrap(),
move |sock, query| {
let resp = responses.clone();
resp.lock()
.unwrap()
.push(sock.run_simple_query(&query).unwrap());
},
|_| {},
true,
);
workpool.execute_and_finish_iter(set_packs);
// clean up the database
temp_con.flushdb().unwrap();
current_thread_count += 1;
}
}
fn calculate_max_keylen(expected_queries: usize, sys: System) -> usize {
let total_mem_in_bytes = (sys.get_total_memory() * 1024) as usize;
// av_mem gives us 90% of the memory size
let ninety_percent_of_memory = (0.90_f32 * total_mem_in_bytes as f32) as usize;
let mut highest_len = 1usize;
loop {
pool.execute(Query::from("HEYA"));
let set_pack_len = Query::array_packet_size_hint(vec![3, highest_len, highest_len]);
let get_pack_len = Query::array_packet_size_hint(vec![3, highest_len]);
let resulting_size = expected_queries
* (
// for the set packets
set_pack_len +
// for the get packets
get_pack_len +
// for the keys themselves
highest_len
);
if resulting_size >= ninety_percent_of_memory as usize {
break;
}
highest_len = (highest_len as f32 * 1.21_f32).ceil() as usize;
}
highest_len
}

Loading…
Cancel
Save