提交 3ddf7cf7 编写于 作者: C Calvin

#171 Redis的Benchmark测试用例, 完整的session性能测试。

上级 8586a1ba
......@@ -3,8 +3,12 @@ package org.springside.examples.showcase.demos.redis;
import java.util.Date;
import org.springside.modules.test.benchmark.BenchmarkBase;
import org.springside.modules.test.benchmark.BenchmarkTask;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Protocol;
/**
* 测试Redis用于做计数器的incr()方法性能.
......@@ -13,48 +17,72 @@ import redis.clients.jedis.Jedis;
*/
public class RedisCounterBenchmark extends BenchmarkBase {
private static final int THREAD_COUNT = 20;
private static final int LOOP_COUNT = 10000;
private static final long LOOP_COUNT = 50000;
private static final int PRINT_INTERVAL_SECONDS = 10;
private static final int COUNTERS = 1;
private static final String HOST = "localhost";
private static final int PORT = Protocol.DEFAULT_PORT;
private static final int TIMEOUT = Protocol.DEFAULT_TIMEOUT;
private final String counterName = "springside.counter";
private String counterName = "springside.counter";
private JedisPool pool;
public static void main(String[] args) throws Exception {
RedisCounterBenchmark benchmark = new RedisCounterBenchmark(THREAD_COUNT, LOOP_COUNT);
benchmark.run();
}
public RedisCounterBenchmark(int threadCount, int loopCount) {
public RedisCounterBenchmark(int threadCount, long loopCount) {
super(threadCount, loopCount);
}
@Override
protected void onStart() {
//remove all keys
Jedis jedis = new Jedis(HOST);
jedis.set(counterName, "0");
jedis.disconnect();
//create jedis pool
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxActive(THREAD_COUNT);
pool = new JedisPool(poolConfig, HOST, PORT, TIMEOUT);
//reset counter
Jedis jedis = pool.getResource();
try {
jedis.set(counterName, "0");
} finally {
pool.returnResource(jedis);
}
}
@Override
protected void onFinish() {
pool.destroy();
}
@Override
protected Runnable getTask(int index) {
return new CounterTask();
return new CounterTask(index, this, PRINT_INTERVAL_SECONDS);
}
public class CounterTask implements Runnable {
public class CounterTask extends BenchmarkTask {
public CounterTask(int index, BenchmarkBase parent, int printInfoInterval) {
super(index, parent, printInfoInterval);
}
@Override
public void run() {
Jedis jedis = new Jedis(HOST);
Jedis jedis = pool.getResource();
Date startTime = onThreadStart();
try {
// start test loop
for (int i = 0; i < loopCount; i++) {
jedis.incr(counterName + (i % COUNTERS));
printInfo(startTime, i);
}
} finally {
onThreadFinish(startTime);
jedis.disconnect();
onThreadFinish();
pool.returnResource(jedis);
}
}
}
......
package org.springside.examples.showcase.demos.redis;
import java.util.Date;
import org.springside.modules.mapper.JsonMapper;
import org.springside.modules.test.benchmark.BenchmarkBase;
import org.springside.modules.test.benchmark.BenchmarkTask;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Protocol;
/**
* 测试Redis批量插入时的性能, 使用PipeLine加速.
*
* @author calvin
*/
public class RedisMassInsertion extends BenchmarkBase {
private static final int THREAD_COUNT = 20;
private static final long LOOP_COUNT = 500000;
private static final int PRINT_INTERVAL_SECONDS = 10;
private static final int BATCH_SIZE = 10;
private static final String HOST = "localhost";
private static final int PORT = Protocol.DEFAULT_PORT;
private static final int TIMEOUT = 40000;
private String keyPrefix = "springside.key_";
private JsonMapper jsonMapper = new JsonMapper();
private JedisPool pool;
public static void main(String[] args) throws Exception {
RedisMassInsertion benchmark = new RedisMassInsertion(THREAD_COUNT, LOOP_COUNT);
benchmark.run();
}
public RedisMassInsertion(int threadCount, long loopCount) {
super(threadCount, loopCount);
}
@Override
protected void onStart() {
//create jedis pool
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxActive(THREAD_COUNT);
pool = new JedisPool(poolConfig, HOST, PORT, TIMEOUT);
//remove all keys
Jedis jedis = pool.getResource();
try {
jedis.flushDB();
} finally {
pool.returnResource(jedis);
}
}
@Override
protected void onFinish() {
pool.destroy();
}
@Override
protected Runnable getTask(int index) {
return new MassInsertionTask(index, this, PRINT_INTERVAL_SECONDS);
}
public class MassInsertionTask extends BenchmarkTask {
public MassInsertionTask(int index, BenchmarkBase parent, int printInfoInterval) {
super(index, parent, printInfoInterval);
}
@Override
public void run() {
Jedis jedis = pool.getResource();
Date startTime = onThreadStart();
try {
Pipeline pl = jedis.pipelined();
// start test loop
for (int i = 0; i < loopCount; i++) {
String key = new StringBuilder().append(keyPrefix).append(threadIndex).append("_").append(i)
.toString();
//set session expired after 100 seconds
Session session = new Session(key);
session.addAttrbute("name", key);
session.addAttrbute("age", i);
session.addAttrbute("address", "address:" + i);
session.addAttrbute("tel", "tel:" + i);
pl.set(session.getId(), jsonMapper.toJson(session));
if (i % BATCH_SIZE == 0) {
pl.sync();
printInfo(startTime, i);
}
}
} finally {
onThreadFinish();
pool.returnResource(jedis);
}
}
}
}
......@@ -4,8 +4,12 @@ import java.util.Date;
import org.springside.modules.mapper.JsonMapper;
import org.springside.modules.test.benchmark.BenchmarkBase;
import org.springside.modules.test.benchmark.BenchmarkTask;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Protocol;
/**
* 测试Redis用于做Session管理的setEx()与get()方法的性能, 并使用JSON格式存储数据.
......@@ -14,63 +18,81 @@ import redis.clients.jedis.Jedis;
*/
public class RedisSessionBenchmark extends BenchmarkBase {
private static final int THREAD_COUNT = 20;
private static final int LOOP_COUNT = 10000;
private static final long LOOP_COUNT = 50000;
private static final int PRINT_INTERVAL_SECONDS = 10;
private static final String HOST = "localhost";
private static final int PORT = Protocol.DEFAULT_PORT;
private static final int TIMEOUT = Protocol.DEFAULT_TIMEOUT;
private final String keyPrefix = "springside.key";
private static JsonMapper jsonMapper = new JsonMapper();
private String keyPrefix = "springside.key_";
private JsonMapper jsonMapper = new JsonMapper();
private JedisPool pool;
public static void main(String[] args) throws Exception {
RedisSessionBenchmark benchmark = new RedisSessionBenchmark(THREAD_COUNT, LOOP_COUNT);
benchmark.run();
}
public RedisSessionBenchmark(int threadCount, int loopCount) {
public RedisSessionBenchmark(int threadCount, long loopCount) {
super(threadCount, loopCount);
}
@Override
protected void onStart() {
//create jedis pool
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxActive(THREAD_COUNT);
pool = new JedisPool(poolConfig, HOST, PORT, TIMEOUT);
//remove all keys
Jedis jedis = new Jedis(HOST);
jedis.flushDB();
jedis.disconnect();
Jedis jedis = pool.getResource();
try {
jedis.flushDB();
} finally {
pool.returnResource(jedis);
}
}
@Override
protected Runnable getTask(int index) {
return new SessionTask(index);
protected void onFinish() {
pool.destroy();
}
public class SessionTask implements Runnable {
private final int index;
@Override
protected Runnable getTask(int index) {
return new SessionTask(index, this, PRINT_INTERVAL_SECONDS);
}
public SessionTask(int index) {
this.index = index;
public class SessionTask extends BenchmarkTask {
public SessionTask(int index, BenchmarkBase parent, int printInfoInterval) {
super(index, parent, printInfoInterval);
}
@Override
public void run() {
Jedis jedis = new Jedis(HOST);
Jedis jedis = pool.getResource();
Date startTime = onThreadStart();
try {
// start test loop
for (int i = 0; i < loopCount; i++) {
//set session expired after 100 seconds
Session session = new Session(keyPrefix + i);
session.addAttrbute("name", new StringBuilder().append("user_").append(index).append("_").append(i)
.toString());
session.addAttrbute("name", new StringBuilder().append("user_").append(threadIndex).append("_")
.append(i).toString());
session.addAttrbute("age", i);
jedis.setex(session.getId(), 100, jsonMapper.toJson(session));
//get it back
String sessionBackString = jedis.get(keyPrefix + i);
Session sessionBack = jsonMapper.fromJson(sessionBackString, Session.class);
printInfo(startTime, i);
}
} finally {
onThreadFinish(startTime);
jedis.disconnect();
onThreadFinish();
pool.returnResource(jedis);
}
}
}
......
......@@ -30,7 +30,7 @@
<logback.version>1.0.9</logback.version>
<commons-lang3.version>3.1</commons-lang3.version>
<commons-io.version>2.4</commons-io.version>
<guava.version>13.0.1</guava.version>
<guava.version>14.0-rc2</guava.version>
<joda-time.version>2.1</joda-time.version>
<dozer.version>5.4.0</dozer.version>
<httpclient.version>4.2.2</httpclient.version>
......
package org.springside.modules.test.benchmark;
import java.math.BigDecimal;
import java.util.Date;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
......@@ -9,12 +8,12 @@ import java.util.concurrent.Executors;
public abstract class BenchmarkBase {
protected int threadCount;
protected int loopCount;
protected long loopCount;
protected CountDownLatch startLock;
protected CountDownLatch finishLock;
public BenchmarkBase(int threadCount, int loopCount) {
public BenchmarkBase(int threadCount, long loopCount) {
this.threadCount = threadCount;
this.loopCount = loopCount;
......@@ -35,48 +34,24 @@ public abstract class BenchmarkBase {
//wait for all threads ready
startLock.await();
System.out.println(this.getClass().getSimpleName() + " start");
//print start message
String className = this.getClass().getSimpleName();
long invokeTimes = threadCount * loopCount;
System.out.printf("%s start. %,d request will be invoked.\n", className, invokeTimes);
Date startTime = new Date();
//wait for all threads finish
finishLock.await();
//print summary message
long timeInMills = new Date().getTime() - startTime.getTime();
long invokeTimes = threadCount * loopCount;
System.out.printf("%s finish.\nThread count is %d, spend %,d ms for %,d request, TPS is %,d.\n", this
.getClass().getSimpleName(), threadCount, timeInMills, invokeTimes,
(invokeTimes * 1000 / timeInMills));
System.out.printf("%s finish.\nThread count is %d, spend %,d ms for %,d request, TPS is %,d.\n", className,
threadCount, timeInMills, invokeTimes, (invokeTimes * 1000 / timeInMills));
} finally {
threadPool.shutdownNow();
onFinish();
}
onFinish();
}
/**
* Must be invoked after each thread finish the prepare job, return the startTime.
*/
protected Date onThreadStart() {
startLock.countDown();
//wait for all threads ready
try {
startLock.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
return new Date();
}
/**
* Must be invoked after the loop finish.
*/
protected void onThreadFinish(Date threadStartTime) {
// notify test finish
finishLock.countDown();
// print result
BigDecimal latency = new BigDecimal((new Date().getTime() - threadStartTime.getTime())).divide(new BigDecimal(
loopCount), 2, BigDecimal.ROUND_HALF_UP);
System.out.println("Thread average latency " + latency + "ms");
}
/**
......@@ -94,5 +69,5 @@ public abstract class BenchmarkBase {
/**
* Return a new benchmark task.
*/
abstract protected Runnable getTask(int index);
abstract protected Runnable getTask(int threadIndex);
}
package org.springside.modules.test.benchmark;
import java.math.BigDecimal;
import java.util.Date;
import com.google.common.util.concurrent.RateLimiter;
public abstract class BenchmarkTask implements Runnable {
protected int threadIndex;
protected RateLimiter rateLimiter;
protected int printInfoInterval; //单位为秒.
protected long previous = 0L;
protected BenchmarkBase parent;
public BenchmarkTask(int threadIndex, BenchmarkBase parent, int printInfoInterval) {
this.threadIndex = threadIndex;
this.parent = parent;
this.printInfoInterval = printInfoInterval;
this.rateLimiter = RateLimiter.create(1d / printInfoInterval);
}
/**
* Must be invoked after each thread finish the prepare job, return the startTime.
*/
protected Date onThreadStart() {
parent.startLock.countDown();
//wait for all other threads ready
try {
parent.startLock.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
return new Date();
}
/**
* Must be invoked after the loop in thread finish.
*/
protected void onThreadFinish() {
// notify test finish
parent.finishLock.countDown();
System.out.printf("Thread %02d finish.\n", threadIndex);
}
/**
* 间隔printInfoInterval的时间打印信息.
*/
protected void printInfo(Date startTime, long last) {
if (rateLimiter.tryAcquire()) {
long totalTime = (new Date().getTime() - startTime.getTime()) / 1000;
long requests = (last - previous) + 1;
long tps = requests / printInfoInterval;
BigDecimal latency = new BigDecimal(printInfoInterval * 1000).divide(new BigDecimal(requests), 2,
BigDecimal.ROUND_HALF_UP);
System.out.printf(
"Thread %02d finish %,d request after %d seconds. Last TPS is %,d. Last latency is %sms.\n",
threadIndex, last, totalTime, tps, latency.toString());
previous = last;
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册