| #!/usr/bin/env bash |
| # REQUIRE: benchmark.sh exists in the current directory |
| # After execution of this script, log files are generated in $output_dir. |
| # report.txt provides a high level statistics |
| |
| # This should be run from the parent of the tools directory. The command line is: |
| # [$env_vars] tools/run_flash_bench.sh [list-of-threads] |
| # |
| # This runs a sequence of tests in the following sequence: |
| # step 1) load - bulkload, compact, fillseq, overwrite |
| # step 2) read-only for each number of threads |
| # step 3) read-write for each number of threads |
| # step 4) merge for each number of threads |
| # |
| # The list of threads is optional and when not set is equivalent to "24". |
| # Were list-of-threads specified as "1 2 4" then the tests in steps 2, 3 and |
| # 4 above would be repeated for 1, 2 and 4 threads. The tests in step 1 are |
| # only run for 1 thread. |
| |
| # Test output is written to $OUTPUT_DIR, currently /tmp/output. The performance |
| # summary is in $OUTPUT_DIR/report.txt. There is one file in $OUTPUT_DIR per |
| # test and the tests are listed below. |
| # |
| # The environment variables are also optional. The variables are: |
| # |
| # NKEYS - number of key/value pairs to load |
| # BG_MBWRITEPERSEC - write rate limit in MB/second for tests in which |
| # there is one thread doing writes and stats are |
| # reported for read threads. "BG" stands for background. |
| # If this is too large then the non-writer threads can get |
| # starved. This is used for the "readwhile" tests. |
| # FG_MBWRITEPERSEC - write rate limit in MB/second for tests like overwrite |
| # where stats are reported for the write threads. |
| # NSECONDS - number of seconds for which to run each test in steps 2, |
| # 3 and 4. There are currently 15 tests in those steps and |
| # they are repeated for each entry in list-of-threads so |
| # this variable lets you control the total duration to |
| # finish the benchmark. |
| # RANGE_LIMIT - the number of rows to read per range query for tests that |
| # do range queries. |
| # VAL_SIZE - the length of the value in the key/value pairs loaded. |
| # You can estimate the size of the test database from this, |
| # NKEYS and the compression rate (--compression_ratio) set |
| # in tools/benchmark.sh |
| # BLOCK_LENGTH - value for db_bench --block_size |
| # CACHE_BYTES - the size of the RocksDB block cache in bytes |
| # DATA_DIR - directory in which to create database files |
| # LOG_DIR - directory in which to create WAL files, may be the same |
| # as DATA_DIR |
| # DO_SETUP - when set to 0 then a backup of the database is copied from |
| # $DATA_DIR.bak to $DATA_DIR and the load tests from step 1 |
| # The WAL directory is also copied from a backup if |
| # DATA_DIR != LOG_DIR. This allows tests from steps 2, 3, 4 |
| # to be repeated faster. |
| # SAVE_SETUP - saves a copy of the database at the end of step 1 to |
| # $DATA_DIR.bak. When LOG_DIR != DATA_DIR then it is copied |
| # to $LOG_DIR.bak. |
| # SKIP_LOW_PRI_TESTS - skip some of the tests which aren't crucial for getting |
| # actionable benchmarking data (look for keywords "bulkload", |
| # "sync=1", and "while merging"). |
| # |
| |
| # Size constants |
| K=1024 |
| M=$((1024 * K)) |
| G=$((1024 * M)) |
| |
| num_keys=${NKEYS:-$((1 * G))} |
| # write rate for readwhile... tests |
| bg_mbwps=${BG_MBWRITEPERSEC:-4} |
| # write rate for tests other than readwhile, 0 means no limit |
| fg_mbwps=${FG_MBWRITEPERSEC:-0} |
| duration=${NSECONDS:-$((60 * 60))} |
| nps=${RANGE_LIMIT:-10} |
| vs=${VAL_SIZE:-400} |
| cs=${CACHE_BYTES:-$(( 1 * G ))} |
| bs=${BLOCK_LENGTH:-8192} |
| |
| # If no command line arguments then run for 24 threads. |
| if [[ $# -eq 0 ]]; then |
| nthreads=( 24 ) |
| else |
| nthreads=( "$@" ) |
| fi |
| |
| for num_thr in "${nthreads[@]}" ; do |
| echo Will run for $num_thr threads |
| done |
| |
| # Update these parameters before execution !!! |
| db_dir=${DATA_DIR:-"/tmp/rocksdb/"} |
| wal_dir=${LOG_DIR:-"/tmp/rocksdb/"} |
| |
| do_setup=${DO_SETUP:-1} |
| save_setup=${SAVE_SETUP:-0} |
| |
| # By default we'll run all the tests. Set this to skip a set of tests which |
| # aren't critical for getting key metrics. |
| skip_low_pri_tests=${SKIP_LOW_PRI_TESTS:-0} |
| |
| if [[ $skip_low_pri_tests == 1 ]]; then |
| echo "Skipping some non-critical tests because SKIP_LOW_PRI_TESTS is set." |
| fi |
| |
| output_dir="${TMPDIR:-/tmp}/output" |
| |
| ARGS="\ |
| OUTPUT_DIR=$output_dir \ |
| NUM_KEYS=$num_keys \ |
| DB_DIR=$db_dir \ |
| WAL_DIR=$wal_dir \ |
| VALUE_SIZE=$vs \ |
| BLOCK_SIZE=$bs \ |
| CACHE_SIZE=$cs" |
| |
| mkdir -p $output_dir |
| echo -e "ops/sec\tmb/sec\tSize-GB\tL0_GB\tSum_GB\tW-Amp\tW-MB/s\tusec/op\tp50\tp75\tp99\tp99.9\tp99.99\tUptime\tStall-time\tStall%\tTest" \ |
| > $output_dir/report.txt |
| |
| # Notes on test sequence: |
| # step 1) Setup database via sequential fill followed by overwrite to fragment it. |
| # Done without setting DURATION to make sure that overwrite does $num_keys writes |
| # step 2) read-only tests for all levels of concurrency requested |
| # step 3) non read-only tests for all levels of concurrency requested |
| # step 4) merge tests for all levels of concurrency requested. These must come last. |
| |
| ###### Setup the database |
| |
| if [[ $do_setup != 0 ]]; then |
| echo Doing setup |
| |
| if [[ $skip_low_pri_tests != 1 ]]; then |
| # Test 1: bulk load |
| env $ARGS ./tools/benchmark.sh bulkload |
| fi |
| |
| # Test 2a: sequential fill with large values to get peak ingest |
| # adjust NUM_KEYS given the use of larger values |
| env $ARGS BLOCK_SIZE=$((1 * M)) VALUE_SIZE=$((32 * K)) NUM_KEYS=$(( num_keys / 64 )) \ |
| ./tools/benchmark.sh fillseq_disable_wal |
| |
| # Test 2b: sequential fill with the configured value size |
| env $ARGS ./tools/benchmark.sh fillseq_disable_wal |
| |
| # Test 2c: same as 2a, but with WAL being enabled. |
| env $ARGS BLOCK_SIZE=$((1 * M)) VALUE_SIZE=$((32 * K)) NUM_KEYS=$(( num_keys / 64 )) \ |
| ./tools/benchmark.sh fillseq_enable_wal |
| |
| # Test 2d: same as 2b, but with WAL being enabled. |
| env $ARGS ./tools/benchmark.sh fillseq_enable_wal |
| |
| # Test 3: single-threaded overwrite |
| env $ARGS NUM_THREADS=1 DB_BENCH_NO_SYNC=1 ./tools/benchmark.sh overwrite |
| |
| else |
| echo Restoring from backup |
| |
| rm -rf $db_dir |
| |
| if [ ! -d ${db_dir}.bak ]; then |
| echo Database backup does not exist at ${db_dir}.bak |
| exit -1 |
| fi |
| |
| echo Restore database from ${db_dir}.bak |
| cp -p -r ${db_dir}.bak $db_dir |
| |
| if [[ $db_dir != $wal_dir ]]; then |
| rm -rf $wal_dir |
| |
| if [ ! -d ${wal_dir}.bak ]; then |
| echo WAL backup does not exist at ${wal_dir}.bak |
| exit -1 |
| fi |
| |
| echo Restore WAL from ${wal_dir}.bak |
| cp -p -r ${wal_dir}.bak $wal_dir |
| fi |
| fi |
| |
| if [[ $save_setup != 0 ]]; then |
| echo Save database to ${db_dir}.bak |
| cp -p -r $db_dir ${db_dir}.bak |
| |
| if [[ $db_dir != $wal_dir ]]; then |
| echo Save WAL to ${wal_dir}.bak |
| cp -p -r $wal_dir ${wal_dir}.bak |
| fi |
| fi |
| |
| ###### Read-only tests |
| |
| for num_thr in "${nthreads[@]}" ; do |
| # Test 4: random read |
| env $ARGS DURATION=$duration NUM_THREADS=$num_thr ./tools/benchmark.sh readrandom |
| |
| # Test 5: random range scans |
| env $ARGS DURATION=$duration NUM_THREADS=$num_thr NUM_NEXTS_PER_SEEK=$nps \ |
| ./tools/benchmark.sh fwdrange |
| |
| # Test 6: random reverse range scans |
| env $ARGS DURATION=$duration NUM_THREADS=$num_thr NUM_NEXTS_PER_SEEK=$nps \ |
| ./tools/benchmark.sh revrange |
| done |
| |
| ###### Non read-only tests |
| |
| for num_thr in "${nthreads[@]}" ; do |
| # Test 7: overwrite with sync=0 |
| env $ARGS DURATION=$duration NUM_THREADS=$num_thr MB_WRITE_PER_SEC=$fg_mbwps \ |
| DB_BENCH_NO_SYNC=1 ./tools/benchmark.sh overwrite |
| |
| if [[ $skip_low_pri_tests != 1 ]]; then |
| # Test 8: overwrite with sync=1 |
| env $ARGS DURATION=$duration NUM_THREADS=$num_thr MB_WRITE_PER_SEC=$fg_mbwps \ |
| ./tools/benchmark.sh overwrite |
| fi |
| |
| # Test 9: random update with sync=0 |
| env $ARGS DURATION=$duration NUM_THREADS=$num_thr DB_BENCH_NO_SYNC=1 \ |
| ./tools/benchmark.sh updaterandom |
| |
| if [[ $skip_low_pri_tests != 1 ]]; then |
| # Test 10: random update with sync=1 |
| env $ARGS DURATION=$duration NUM_THREADS=$num_thr ./tools/benchmark.sh updaterandom |
| fi |
| |
| # Test 11: random read while writing |
| env $ARGS DURATION=$duration NUM_THREADS=$num_thr MB_WRITE_PER_SEC=$bg_mbwps \ |
| DB_BENCH_NO_SYNC=1 ./tools/benchmark.sh readwhilewriting |
| |
| # Test 12: range scan while writing |
| env $ARGS DURATION=$duration NUM_THREADS=$num_thr MB_WRITE_PER_SEC=$bg_mbwps \ |
| DB_BENCH_NO_SYNC=1 NUM_NEXTS_PER_SEEK=$nps ./tools/benchmark.sh fwdrangewhilewriting |
| |
| # Test 13: reverse range scan while writing |
| env $ARGS DURATION=$duration NUM_THREADS=$num_thr MB_WRITE_PER_SEC=$bg_mbwps \ |
| DB_BENCH_NO_SYNC=1 NUM_NEXTS_PER_SEEK=$nps ./tools/benchmark.sh revrangewhilewriting |
| done |
| |
| ###### Merge tests |
| |
| for num_thr in "${nthreads[@]}" ; do |
| # Test 14: random merge with sync=0 |
| env $ARGS DURATION=$duration NUM_THREADS=$num_thr MB_WRITE_PER_SEC=$fg_mbwps \ |
| DB_BENCH_NO_SYNC=1 ./tools/benchmark.sh mergerandom |
| |
| if [[ $skip_low_pri_tests != 1 ]]; then |
| # Test 15: random merge with sync=1 |
| env $ARGS DURATION=$duration NUM_THREADS=$num_thr MB_WRITE_PER_SEC=$fg_mbwps \ |
| ./tools/benchmark.sh mergerandom |
| |
| # Test 16: random read while merging |
| env $ARGS DURATION=$duration NUM_THREADS=$num_thr MB_WRITE_PER_SEC=$bg_mbwps \ |
| DB_BENCH_NO_SYNC=1 ./tools/benchmark.sh readwhilemerging |
| |
| # Test 17: range scan while merging |
| env $ARGS DURATION=$duration NUM_THREADS=$num_thr MB_WRITE_PER_SEC=$bg_mbwps \ |
| DB_BENCH_NO_SYNC=1 NUM_NEXTS_PER_SEEK=$nps ./tools/benchmark.sh fwdrangewhilemerging |
| |
| # Test 18: reverse range scan while merging |
| env $ARGS DURATION=$duration NUM_THREADS=$num_thr MB_WRITE_PER_SEC=$bg_mbwps \ |
| DB_BENCH_NO_SYNC=1 NUM_NEXTS_PER_SEEK=$nps ./tools/benchmark.sh revrangewhilemerging |
| fi |
| done |
| |
| ###### Universal compaction tests. |
| |
| # Use a single thread to reduce the variability in the benchmark. |
| env $ARGS COMPACTION_TEST=1 NUM_THREADS=1 ./tools/benchmark.sh universal_compaction |
| |
| if [[ $skip_low_pri_tests != 1 ]]; then |
| echo bulkload > $output_dir/report2.txt |
| head -1 $output_dir/report.txt >> $output_dir/report2.txt |
| grep bulkload $output_dir/report.txt >> $output_dir/report2.txt |
| fi |
| |
| echo fillseq_wal_disabled >> $output_dir/report2.txt |
| head -1 $output_dir/report.txt >> $output_dir/report2.txt |
| grep fillseq.wal_disabled $output_dir/report.txt >> $output_dir/report2.txt |
| |
| echo fillseq_wal_enabled >> $output_dir/report2.txt |
| head -1 $output_dir/report.txt >> $output_dir/report2.txt |
| grep fillseq.wal_enabled $output_dir/report.txt >> $output_dir/report2.txt |
| |
| echo overwrite sync=0 >> $output_dir/report2.txt |
| head -1 $output_dir/report.txt >> $output_dir/report2.txt |
| grep overwrite $output_dir/report.txt | grep \.s0 >> $output_dir/report2.txt |
| |
| if [[ $skip_low_pri_tests != 1 ]]; then |
| echo overwrite sync=1 >> $output_dir/report2.txt |
| head -1 $output_dir/report.txt >> $output_dir/report2.txt |
| grep overwrite $output_dir/report.txt | grep \.s1 >> $output_dir/report2.txt |
| fi |
| |
| echo updaterandom sync=0 >> $output_dir/report2.txt |
| head -1 $output_dir/report.txt >> $output_dir/report2.txt |
| grep updaterandom $output_dir/report.txt | grep \.s0 >> $output_dir/report2.txt |
| |
| if [[ $skip_low_pri_tests != 1 ]]; then |
| echo updaterandom sync=1 >> $output_dir/report2.txt |
| head -1 $output_dir/report.txt >> $output_dir/report2.txt |
| grep updaterandom $output_dir/report.txt | grep \.s1 >> $output_dir/report2.txt |
| fi |
| |
| echo mergerandom sync=0 >> $output_dir/report2.txt |
| head -1 $output_dir/report.txt >> $output_dir/report2.txt |
| grep mergerandom $output_dir/report.txt | grep \.s0 >> $output_dir/report2.txt |
| |
| if [[ $skip_low_pri_tests != 1 ]]; then |
| echo mergerandom sync=1 >> $output_dir/report2.txt |
| head -1 $output_dir/report.txt >> $output_dir/report2.txt |
| grep mergerandom $output_dir/report.txt | grep \.s1 >> $output_dir/report2.txt |
| fi |
| |
| echo readrandom >> $output_dir/report2.txt |
| head -1 $output_dir/report.txt >> $output_dir/report2.txt |
| grep readrandom $output_dir/report.txt >> $output_dir/report2.txt |
| |
| echo fwdrange >> $output_dir/report2.txt |
| head -1 $output_dir/report.txt >> $output_dir/report2.txt |
| grep fwdrange\.t $output_dir/report.txt >> $output_dir/report2.txt |
| |
| echo revrange >> $output_dir/report2.txt |
| head -1 $output_dir/report.txt >> $output_dir/report2.txt |
| grep revrange\.t $output_dir/report.txt >> $output_dir/report2.txt |
| |
| echo readwhile >> $output_dir/report2.txt >> $output_dir/report2.txt |
| head -1 $output_dir/report.txt >> $output_dir/report2.txt |
| grep readwhilewriting $output_dir/report.txt >> $output_dir/report2.txt |
| |
| if [[ $skip_low_pri_tests != 1 ]]; then |
| echo readwhile >> $output_dir/report2.txt |
| head -1 $output_dir/report.txt >> $output_dir/report2.txt |
| grep readwhilemerging $output_dir/report.txt >> $output_dir/report2.txt |
| fi |
| |
| echo fwdreadwhilewriting >> $output_dir/report2.txt |
| head -1 $output_dir/report.txt >> $output_dir/report2.txt |
| grep fwdrangewhilewriting $output_dir/report.txt >> $output_dir/report2.txt |
| |
| if [[ $skip_low_pri_tests != 1 ]]; then |
| echo fwdreadwhilemerging >> $output_dir/report2.txt |
| head -1 $output_dir/report.txt >> $output_dir/report2.txt |
| grep fwdrangewhilemerg $output_dir/report.txt >> $output_dir/report2.txt |
| fi |
| |
| echo revreadwhilewriting >> $output_dir/report2.txt |
| head -1 $output_dir/report.txt >> $output_dir/report2.txt |
| grep revrangewhilewriting $output_dir/report.txt >> $output_dir/report2.txt |
| |
| if [[ $skip_low_pri_tests != 1 ]]; then |
| echo revreadwhilemerging >> $output_dir/report2.txt |
| head -1 $output_dir/report.txt >> $output_dir/report2.txt |
| grep revrangewhilemerg $output_dir/report.txt >> $output_dir/report2.txt |
| fi |
| |
| cat $output_dir/report2.txt |