Skip to content

Instantly share code, notes, and snippets.

@rsumbaly
Created June 8, 2010 01:31
Show Gist options
  • Save rsumbaly/429480 to your computer and use it in GitHub Desktop.
Save rsumbaly/429480 to your computer and use it in GitHub Desktop.
Performance tool wrapper
/*
* Copyright 2010 LinkedIn, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package voldemort.performance.benchmark;
import java.util.HashMap;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import org.apache.log4j.Logger;
import voldemort.store.bdb.BdbStorageConfiguration;
import voldemort.utils.Props;
import voldemort.utils.Utils;
/**
* Various performance parameters built on top of Benchmark.
*
*/
public class BenchmarkModels {
private Benchmark benchmark;
/**
* UPDATE HEAVY [Reads - 50%, Updates - 50%, Record Selection - Zipfian]
* Example Application : Session store recording recent actions in a user
* session
*
*/
private Props modelA(int recordCount, int opsCount, int valueSize) throws Exception {
Props workLoadProps = new Props();
workLoadProps.put(Benchmark.RECORD_COUNT, String.valueOf(recordCount));
workLoadProps.put(Benchmark.OPS_COUNT, String.valueOf(opsCount));
workLoadProps.put(Benchmark.VALUE_SIZE, String.valueOf(valueSize));
workLoadProps.put(Benchmark.METRIC_TYPE, Benchmark.SUMMARY_METRIC_TYPE);
workLoadProps.put(Benchmark.READS, "50");
workLoadProps.put(Benchmark.MIXED, "50");
workLoadProps.put(Benchmark.DELETES, "0");
workLoadProps.put(Benchmark.WRITES, "0");
workLoadProps.put(Benchmark.RECORD_SELECTION, Benchmark.ZIPFIAN_RECORD_SELECTION);
return workLoadProps;
}
/**
* READ HEAVY [Reads - 95%, Updates - 5%, Record Selection - Zipfian]
* Example Application : Photo tagging; add a tag is an update, but most
* operations are to read tags
*
*/
private Props modelB(int recordCount, int opsCount, int valueSize) throws Exception {
Props workLoadProps = new Props();
workLoadProps.put(Benchmark.RECORD_COUNT, String.valueOf(recordCount));
workLoadProps.put(Benchmark.OPS_COUNT, String.valueOf(opsCount));
workLoadProps.put(Benchmark.VALUE_SIZE, String.valueOf(valueSize));
workLoadProps.put(Benchmark.METRIC_TYPE, Benchmark.SUMMARY_METRIC_TYPE);
workLoadProps.put(Benchmark.READS, "95");
workLoadProps.put(Benchmark.MIXED, "5");
workLoadProps.put(Benchmark.DELETES, "0");
workLoadProps.put(Benchmark.WRITES, "0");
workLoadProps.put(Benchmark.RECORD_SELECTION, Benchmark.ZIPFIAN_RECORD_SELECTION);
return workLoadProps;
}
/**
* READ LATEST [Reads - 95%, Inserts - 5%, Record Selection - Latest]
* Example Application : User status updates; people want to read the latest
* statuses
*
*/
private Props modelC(int recordCount, int opsCount, int valueSize) throws Exception {
Props workLoadProps = new Props();
workLoadProps.put(Benchmark.RECORD_COUNT, String.valueOf(recordCount));
workLoadProps.put(Benchmark.OPS_COUNT, String.valueOf(opsCount));
workLoadProps.put(Benchmark.VALUE_SIZE, String.valueOf(valueSize));
workLoadProps.put(Benchmark.METRIC_TYPE, Benchmark.SUMMARY_METRIC_TYPE);
workLoadProps.put(Benchmark.READS, "95");
workLoadProps.put(Benchmark.MIXED, "0");
workLoadProps.put(Benchmark.DELETES, "0");
workLoadProps.put(Benchmark.WRITES, "5");
workLoadProps.put(Benchmark.RECORD_SELECTION, Benchmark.LATEST_RECORD_SELECTION);
return workLoadProps;
}
/**
* CUSTOM MODEL
*
*/
private Props modelCustom(int recordCount,
int opsCount,
int valueSize,
int read,
int update,
int delete,
int insert) throws Exception {
Props workLoadProps = new Props();
workLoadProps.put(Benchmark.RECORD_COUNT, String.valueOf(recordCount));
workLoadProps.put(Benchmark.OPS_COUNT, String.valueOf(opsCount));
workLoadProps.put(Benchmark.VALUE_SIZE, String.valueOf(valueSize));
workLoadProps.put(Benchmark.METRIC_TYPE, Benchmark.SUMMARY_METRIC_TYPE);
workLoadProps.put(Benchmark.READS, String.valueOf(read));
workLoadProps.put(Benchmark.MIXED, String.valueOf(update));
workLoadProps.put(Benchmark.DELETES, String.valueOf(delete));
workLoadProps.put(Benchmark.WRITES, String.valueOf(insert));
workLoadProps.put(Benchmark.RECORD_SELECTION, Benchmark.UNIFORM_RECORD_SELECTION);
return workLoadProps;
}
public void LatThroughputVsThreads(Props benchmarkProps) throws Exception {
HashMap<String, Results> resultsMap = null;
benchmark = new Benchmark();
// Warm up once
benchmark.initializeStore(benchmarkProps.with(Benchmark.THREADS, 50));
benchmark.initializeWorkload(modelCustom(benchmarkProps.getInt(Benchmark.RECORD_COUNT),
benchmarkProps.getInt(Benchmark.OPS_COUNT),
1024,
100,
0,
0,
0));
benchmark.runTests(false);
// Changing Client Threads
for(int threads = 10; threads <= 60; threads += 10) {
benchmark.initializeStore(benchmarkProps.with(Benchmark.THREADS, threads));
benchmark.initializeWorkload(modelCustom(benchmarkProps.getInt(Benchmark.RECORD_COUNT),
benchmarkProps.getInt(Benchmark.OPS_COUNT),
1024,
100,
0,
0,
0));
long runTime = benchmark.runTests(true);
resultsMap = Metrics.getInstance().getResults();
if(resultsMap.containsKey(VoldemortWrapper.READS_STRING)) {
Results result = resultsMap.get(VoldemortWrapper.READS_STRING);
double avgLatency = (double) result.totalLatency / (double) result.operations;
System.out.println(VoldemortWrapper.READS_STRING + "\t" + String.valueOf(threads)
+ "\t" + result.minLatency + "\t" + result.maxLatency + "\t"
+ result.medianLatency + "\t" + result.q95Latency + "\t"
+ result.q99Latency + "\t" + avgLatency + "\t"
+ (1000 * benchmarkProps.getInt(Benchmark.OPS_COUNT))
/ (double) runTime);
}
benchmark.close();
}
}
public static void main(String args[]) throws Exception {
Logger.getRootLogger().removeAllAppenders();
OptionParser parser = new OptionParser();
parser.accepts(Benchmark.URL, "url on which to run remote tests")
.withRequiredArg()
.ofType(String.class);
parser.accepts(Benchmark.STORE_NAME, "store name on the remote URL")
.withRequiredArg()
.ofType(String.class);
parser.accepts(Benchmark.RECORD_COUNT, "number of records inserted during warmup phase")
.withRequiredArg()
.ofType(Integer.class);
parser.accepts(Benchmark.OPS_COUNT, "number of operations to do")
.withRequiredArg()
.ofType(Integer.class);
parser.accepts(Benchmark.HELP);
OptionSet options = parser.parse(args);
if(options.has(Benchmark.HELP)) {
parser.printHelpOn(System.out);
System.exit(0);
}
if(!options.has(Benchmark.URL) || !options.has(Benchmark.STORE_NAME)
|| !options.has(Benchmark.RECORD_COUNT) || !options.has(Benchmark.OPS_COUNT)) {
parser.printHelpOn(System.out);
Utils.croak("Missing params");
System.exit(0);
}
Props prop = new Props();
prop.put(Benchmark.URL, (String) options.valueOf(Benchmark.URL));
prop.put(Benchmark.STORE_NAME, (String) options.valueOf(Benchmark.STORE_NAME));
prop.put(Benchmark.RECORD_COUNT, (Integer) options.valueOf(Benchmark.RECORD_COUNT));
prop.put(Benchmark.OPS_COUNT, (Integer) options.valueOf(Benchmark.OPS_COUNT));
// Some basic properties
prop.put(Benchmark.METRIC_TYPE, Benchmark.SUMMARY_METRIC_TYPE);
prop.put(Benchmark.STORAGE_ENGINE_TYPE, BdbStorageConfiguration.TYPE_NAME);
BenchmarkModels model = new BenchmarkModels();
model.LatThroughputVsThreads(prop);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment