Skip to content

Commit

Permalink
Some tweaks for checkpoint stress test
Browse files Browse the repository at this point in the history
 * warmup runs for 2 checkpoint intervals
 * let worker threads run for 20 seconds before we start collecting throughput results
 * print throughput results with timestamps
 * require 60% of throughput results to be in one stddev from average
 * increase default page cache memory from 2g to 4g
  • Loading branch information
lutovich committed Jun 17, 2016
1 parent 9e69d9d commit 93cf957
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 30 deletions.
Expand Up @@ -52,10 +52,10 @@ public class CheckPointingLogRotationStressTesting
private static final String DEFAULT_STORE_DIR = new File( getProperty( "java.io.tmpdir" ), "store" ).getPath(); private static final String DEFAULT_STORE_DIR = new File( getProperty( "java.io.tmpdir" ), "store" ).getPath();
private static final String DEFAULT_NODE_COUNT = "100000"; private static final String DEFAULT_NODE_COUNT = "100000";
private static final String DEFAULT_WORKER_THREADS = "16"; private static final String DEFAULT_WORKER_THREADS = "16";
private static final String DEFAULT_PAGE_CACHE_MEMORY = "2g"; private static final String DEFAULT_PAGE_CACHE_MEMORY = "4g";
private static final String DEFAULT_PAGE_SIZE = "8k"; private static final String DEFAULT_PAGE_SIZE = "8k";


private static final int CHECK_POINT_INTERVAL_SECONDS = 60; private static final int CHECK_POINT_INTERVAL_MINUTES = 1;


@Test @Test
public void shouldBehaveCorrectlyUnderStress() throws Throwable public void shouldBehaveCorrectlyUnderStress() throws Throwable
Expand All @@ -81,15 +81,15 @@ public void shouldBehaveCorrectlyUnderStress() throws Throwable
GraphDatabaseService db = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder( storeDir ) GraphDatabaseService db = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder( storeDir )
.setConfig( GraphDatabaseSettings.pagecache_memory, pageCacheMemory ) .setConfig( GraphDatabaseSettings.pagecache_memory, pageCacheMemory )
.setConfig( GraphDatabaseSettings.mapped_memory_page_size, pageSize ) .setConfig( GraphDatabaseSettings.mapped_memory_page_size, pageSize )
.setConfig( GraphDatabaseSettings.check_point_interval_time, CHECK_POINT_INTERVAL_SECONDS + "s" ) .setConfig( GraphDatabaseSettings.check_point_interval_time, CHECK_POINT_INTERVAL_MINUTES + "m" )
.setConfig( GraphDatabaseFacadeFactory.Configuration.tracer, "timer" ) .setConfig( GraphDatabaseFacadeFactory.Configuration.tracer, "timer" )
.newGraphDatabase(); .newGraphDatabase();


System.out.println("3/6\tWarm up db..."); System.out.println("3/6\tWarm up db...");
try ( Workload workload = new Workload( db, defaultRandomMutation( nodeCount, db ), threads ) ) try ( Workload workload = new Workload( db, defaultRandomMutation( nodeCount, db ), threads ) )
{ {
// make sure to run at least one checkpoint during warmup // make sure to run at least one checkpoint during warmup
long warmUpTimeMillis = TimeUnit.SECONDS.toMillis( CHECK_POINT_INTERVAL_SECONDS + 30 ); long warmUpTimeMillis = TimeUnit.SECONDS.toMillis( CHECK_POINT_INTERVAL_MINUTES * 2 );
workload.run( warmUpTimeMillis, Workload.TransactionThroughput.NONE ); workload.run( warmUpTimeMillis, Workload.TransactionThroughput.NONE );
} }


Expand Down
Expand Up @@ -20,8 +20,13 @@
package org.neo4j.kernel.stresstests.transaction.checkpoint; package org.neo4j.kernel.stresstests.transaction.checkpoint;


import java.io.PrintStream; import java.io.PrintStream;
import java.util.ArrayList; import java.text.DateFormat;
import java.util.List; import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;


import org.neo4j.kernel.stresstests.transaction.checkpoint.workload.Workload; import org.neo4j.kernel.stresstests.transaction.checkpoint.workload.Workload;
Expand All @@ -30,13 +35,16 @@


public class TransactionThroughputChecker implements Workload.TransactionThroughput public class TransactionThroughputChecker implements Workload.TransactionThroughput
{ {
private final List<Double> reports = new ArrayList<>(); private final DateFormat dateFormat = newDateFormat();
private final Map<String,Double> reports = new LinkedHashMap<>();


@Override @Override
public void report( long transactions, long timeSlotMillis ) public void report( long transactions, long timeSlotMillis )
{ {
long elapsedSeconds = TimeUnit.MILLISECONDS.toSeconds( timeSlotMillis ); long elapsedSeconds = TimeUnit.MILLISECONDS.toSeconds( timeSlotMillis );
reports.add( ((double) transactions / (double) elapsedSeconds) ); double throughput = (double) transactions / (double) elapsedSeconds;
String timestamp = currentTime();
reports.put( timestamp, throughput );
} }


public void assertThroughput( PrintStream out ) public void assertThroughput( PrintStream out )
Expand All @@ -47,32 +55,19 @@ public void assertThroughput( PrintStream out )
return; return;
} }


out.println( "Throughput reports (tx/s):" ); printThroughputReports( out );
double sum = 0;
for ( double report : reports )
{
out.println( "\t" + report );
sum += report;
}
out.println();


double average = sum / (double) reports.size(); double average = average( reports.values() );
out.println( "Average throughput (tx/s): " + average ); out.println( "Average throughput (tx/s): " + average );


double powerSum = 0.0; double stdDeviation = stdDeviation( reports.values() );
for ( double report : reports )
{
powerSum += Math.pow(report - average, 2);
}

double stdDeviation = Math.sqrt( powerSum / (double) reports.size() );
out.println( "Standard deviation (tx/s): " + stdDeviation ); out.println( "Standard deviation (tx/s): " + stdDeviation );
double twoStdDeviations = stdDeviation * 2.0; double twoStdDeviations = stdDeviation * 2.0;
out.println( "Two standard deviations (tx/s): " + twoStdDeviations ); out.println( "Two standard deviations (tx/s): " + twoStdDeviations );


int inOneStdDeviationRange = 0; int inOneStdDeviationRange = 0;
int inTwoStdDeviationRange = 0; int inTwoStdDeviationRange = 0;
for ( double report : reports ) for ( double report : reports.values() )
{ {
if ( Math.abs( average - report ) <= stdDeviation ) if ( Math.abs( average - report ) <= stdDeviation )
{ {
Expand All @@ -93,8 +88,8 @@ else if ( Math.abs( average - report ) <= twoStdDeviations )
int inOneStdDeviationRangePercentage = int inOneStdDeviationRangePercentage =
(int) ( (inOneStdDeviationRange * 100.0) / (double) reports.size() ); (int) ( (inOneStdDeviationRange * 100.0) / (double) reports.size() );
System.out.println( "Percentage inside one std deviation is: " + inOneStdDeviationRangePercentage ); System.out.println( "Percentage inside one std deviation is: " + inOneStdDeviationRangePercentage );
assertTrue( "Assumption is that at least 65 percent should be in one std deviation (" + stdDeviation + ")" + assertTrue( "Assumption is that at least 60 percent should be in one std deviation (" + stdDeviation + ")" +
" range from the average (" + average + ") ", inOneStdDeviationRangePercentage >= 65 ); " range from the average (" + average + ") ", inOneStdDeviationRangePercentage >= 60 );


int inTwoStdDeviationRangePercentage = int inTwoStdDeviationRangePercentage =
(int) ( (inTwoStdDeviationRange * 100.0) / (double) reports.size() ); (int) ( (inTwoStdDeviationRange * 100.0) / (double) reports.size() );
Expand All @@ -103,4 +98,49 @@ else if ( Math.abs( average - report ) <= twoStdDeviations )
" range from the average (" + average + ") ", inTwoStdDeviationRangePercentage >= 90 ); " range from the average (" + average + ") ", inTwoStdDeviationRangePercentage >= 90 );
} }


private void printThroughputReports( PrintStream out )
{
out.println( "Throughput reports (tx/s):" );

for ( Map.Entry<String,Double> entry : reports.entrySet() )
{
out.println( "\t" + entry.getKey() + " " + entry.getValue() );
}

out.println();
}

private static double average( Collection<Double> values )
{
double sum = 0;
for ( Double value : values )
{
sum += value;
}
return sum / values.size();
}

private static double stdDeviation( Collection<Double> values )
{
double average = average( values );
double powerSum = 0;
for ( double value : values )
{
powerSum += Math.pow( value - average, 2 );
}
return Math.sqrt( powerSum / (double) values.size() );
}

private String currentTime()
{
return dateFormat.format( new Date() );
}

private static DateFormat newDateFormat()
{
DateFormat format = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss.SSSZ" );
TimeZone timeZone = TimeZone.getTimeZone( "UTC" );
format.setTimeZone( timeZone );
return format;
}
} }
Expand Up @@ -29,15 +29,13 @@


public class Workload implements Resource public class Workload implements Resource
{ {
private final GraphDatabaseService db;
private final int threads; private final int threads;
private final SyncMonitor sync; private final SyncMonitor sync;
private final Worker worker; private final Worker worker;
private final ExecutorService executor; private final ExecutorService executor;


public Workload( GraphDatabaseService db, RandomMutation randomMutation, int threads ) public Workload( GraphDatabaseService db, RandomMutation randomMutation, int threads )
{ {
this.db = db;
this.threads = threads; this.threads = threads;
this.sync = new SyncMonitor( threads ); this.sync = new SyncMonitor( threads );
this.worker = new Worker( db, randomMutation, sync, 100 ); this.worker = new Worker( db, randomMutation, sync, 100 );
Expand Down Expand Up @@ -66,12 +64,14 @@ public void run( long runningTimeMillis, TransactionThroughput throughput )
executor.submit( worker ); executor.submit( worker );
} }


TimeUnit.SECONDS.sleep( 20 ); // sleep to make sure workers are started

long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
long previousReportTime = System.currentTimeMillis(); long previousReportTime = System.currentTimeMillis();
long finishLine = runningTimeMillis + now; long finishLine = runningTimeMillis + now;
long sampleRate = TimeUnit.SECONDS.toMillis( 10 ); long sampleRate = TimeUnit.SECONDS.toMillis( 10 );
long lastReport = sampleRate + now; long lastReport = sampleRate + now;
long previousTransactionCount = 0; long previousTransactionCount = sync.transactions();
Thread.sleep( sampleRate ); Thread.sleep( sampleRate );
do do
{ {
Expand Down

0 comments on commit 93cf957

Please sign in to comment.