1#!/usr/bin/env bash 2# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. 3# REQUIRE: db_bench binary exists in the current directory 4# 5# This should be used with the LevelDB fork listed here to use additional test options. 6# For more details on the changes see the blog post listed below. 7# https://github.com/mdcallag/leveldb-1 8# http://smalldatum.blogspot.com/2015/04/comparing-leveldb-and-rocksdb-take-2.html 9 10if [ $# -ne 1 ]; then 11 echo -n "./benchmark.sh [fillseq/overwrite/readrandom/readwhilewriting]" 12 exit 0 13fi 14 15# size constants 16K=1024 17M=$((1024 * K)) 18G=$((1024 * M)) 19 20if [ -z $DB_DIR ]; then 21 echo "DB_DIR is not defined" 22 exit 0 23fi 24 25output_dir=${OUTPUT_DIR:-/tmp/} 26if [ ! -d $output_dir ]; then 27 mkdir -p $output_dir 28fi 29 30# all multithreaded tests run with sync=1 unless 31# $DB_BENCH_NO_SYNC is defined 32syncval="1" 33if [ ! -z $DB_BENCH_NO_SYNC ]; then 34 echo "Turning sync off for all multithreaded tests" 35 syncval="0"; 36fi 37 38num_threads=${NUM_THREADS:-16} 39# Only for *whilewriting, *whilemerging 40writes_per_second=${WRITES_PER_SECOND:-$((10 * K))} 41cache_size=${CACHE_SIZE:-$((1 * G))} 42 43num_keys=${NUM_KEYS:-$((1 * G))} 44key_size=20 45value_size=${VALUE_SIZE:-400} 46block_size=${BLOCK_SIZE:-4096} 47 48const_params=" 49 --db=$DB_DIR \ 50 \ 51 --num=$num_keys \ 52 --value_size=$value_size \ 53 --cache_size=$cache_size \ 54 --compression_ratio=0.5 \ 55 \ 56 --write_buffer_size=$((2 * M)) \ 57 \ 58 --histogram=1 \ 59 \ 60 --bloom_bits=10 \ 61 --open_files=$((20 * K))" 62 63params_w="$const_params " 64 65function summarize_result { 66 test_out=$1 67 test_name=$2 68 bench_name=$3 69 nthr=$4 70 71 usecs_op=$( grep ^${bench_name} $test_out | awk '{ printf "%.1f", $3 }' ) 72 mb_sec=$( grep ^${bench_name} $test_out | awk '{ printf "%.1f", $5 }' ) 73 ops=$( grep "^Count:" $test_out | awk '{ print $2 }' ) 74 ops_sec=$( echo "scale=0; (1000000.0 * $nthr) / $usecs_op" | bc ) 75 avg=$( grep "^Count:" $test_out | awk '{ printf "%.1f", $4 }' ) 76 p50=$( grep "^Min:" $test_out | awk '{ printf "%.1f", $4 }' ) 77 echo -e "$ops_sec\t$mb_sec\t$usecs_op\t$avg\t$p50\t$test_name" \ 78 >> $output_dir/report.txt 79} 80 81function run_fillseq { 82 # This runs with a vector memtable and the WAL disabled to load faster. It is still crash safe and the 83 # client can discover where to restart a load after a crash. I think this is a good way to load. 84 echo "Loading $num_keys keys sequentially" 85 cmd="./db_bench --benchmarks=fillseq \ 86 --use_existing_db=0 \ 87 --sync=0 \ 88 $params_w \ 89 --threads=1 \ 90 --seed=$( date +%s ) \ 91 2>&1 | tee -a $output_dir/benchmark_fillseq.v${value_size}.log" 92 echo $cmd | tee $output_dir/benchmark_fillseq.v${value_size}.log 93 eval $cmd 94 summarize_result $output_dir/benchmark_fillseq.v${value_size}.log fillseq.v${value_size} fillseq 1 95} 96 97function run_change { 98 operation=$1 99 echo "Do $num_keys random $operation" 100 out_name="benchmark_${operation}.t${num_threads}.s${syncval}.log" 101 cmd="./db_bench --benchmarks=$operation \ 102 --use_existing_db=1 \ 103 --sync=$syncval \ 104 $params_w \ 105 --threads=$num_threads \ 106 --seed=$( date +%s ) \ 107 2>&1 | tee -a $output_dir/${out_name}" 108 echo $cmd | tee $output_dir/${out_name} 109 eval $cmd 110 summarize_result $output_dir/${out_name} ${operation}.t${num_threads}.s${syncval} $operation $num_threads 111} 112 113function run_readrandom { 114 echo "Reading $num_keys random keys" 115 out_name="benchmark_readrandom.t${num_threads}.log" 116 cmd="./db_bench --benchmarks=readrandom \ 117 --use_existing_db=1 \ 118 $params_w \ 119 --threads=$num_threads \ 120 --seed=$( date +%s ) \ 121 2>&1 | tee -a $output_dir/${out_name}" 122 echo $cmd | tee $output_dir/${out_name} 123 eval $cmd 124 summarize_result $output_dir/${out_name} readrandom.t${num_threads} readrandom $num_threads 125} 126 127function run_readwhile { 128 operation=$1 129 echo "Reading $num_keys random keys while $operation" 130 out_name="benchmark_readwhile${operation}.t${num_threads}.log" 131 cmd="./db_bench --benchmarks=readwhile${operation} \ 132 --use_existing_db=1 \ 133 --sync=$syncval \ 134 $params_w \ 135 --threads=$num_threads \ 136 --writes_per_second=$writes_per_second \ 137 --seed=$( date +%s ) \ 138 2>&1 | tee -a $output_dir/${out_name}" 139 echo $cmd | tee $output_dir/${out_name} 140 eval $cmd 141 summarize_result $output_dir/${out_name} readwhile${operation}.t${num_threads} readwhile${operation} $num_threads 142} 143 144function now() { 145 echo `date +"%s"` 146} 147 148report="$output_dir/report.txt" 149schedule="$output_dir/schedule.txt" 150 151echo "===== Benchmark =====" 152 153# Run!!! 154IFS=',' read -a jobs <<< $1 155# shellcheck disable=SC2068 156for job in ${jobs[@]}; do 157 158 if [ $job != debug ]; then 159 echo "Start $job at `date`" | tee -a $schedule 160 fi 161 162 start=$(now) 163 if [ $job = fillseq ]; then 164 run_fillseq 165 elif [ $job = overwrite ]; then 166 run_change overwrite 167 elif [ $job = readrandom ]; then 168 run_readrandom 169 elif [ $job = readwhilewriting ]; then 170 run_readwhile writing 171 elif [ $job = debug ]; then 172 num_keys=1000; # debug 173 echo "Setting num_keys to $num_keys" 174 else 175 echo "unknown job $job" 176 exit 177 fi 178 end=$(now) 179 180 if [ $job != debug ]; then 181 echo "Complete $job in $((end-start)) seconds" | tee -a $schedule 182 fi 183 184 echo -e "ops/sec\tmb/sec\tusec/op\tavg\tp50\tTest" 185 tail -1 $output_dir/report.txt 186 187done 188