package net.rubyeye.xmemcached.pressure; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.atomic.AtomicInteger; import net.rubyeye.xmemcached.MemcachedClient; import net.rubyeye.xmemcached.MemcachedClientBuilder; import net.rubyeye.xmemcached.XMemcachedClientBuilder; import net.rubyeye.xmemcached.utils.AddrUtil; public class MemcachedClientPressureTest { private static final class ClockWatch implements Runnable { private long startTime; private long stopTime; public synchronized void run() { if (this.startTime == -1) { this.startTime = System.nanoTime(); } else { this.stopTime = System.nanoTime(); } } public synchronized void start() { this.startTime = -1; } public synchronized long getDurationInNano() { return this.stopTime - this.startTime; } public synchronized long getDurationInMillis() { return (this.stopTime - this.startTime) / 1000000; } } static class TestThread extends Thread { int repeat; int start; int size; MemcachedClient client; AtomicInteger failure; AtomicInteger success; CyclicBarrier barrier; public TestThread(int repeat, int start, int size, MemcachedClient client, AtomicInteger failure, AtomicInteger success, CyclicBarrier barrier) { super(); this.repeat = repeat; this.start = start; this.size = size; this.client = client; this.failure = failure; this.success = success; this.barrier = barrier; } public void run() { byte[] value = new byte[size]; try { barrier.await(); for (int i = 0; i < repeat; i++) { String key = String.valueOf(start + i); try { if (!client.set(key, 10, value)) throw new RuntimeException("set failed"); byte[] v = client.get(key); if (v == null || v.length != size) throw new RuntimeException("get failed"); if (!client.touch(key, 10)) throw new RuntimeException("touch failed"); if (!client.delete(key, 10)) throw new RuntimeException("delete failed"); success.incrementAndGet(); } catch (Exception e) { e.printStackTrace(); failure.incrementAndGet(); } } barrier.await(); } catch (Exception e) { // ignore; } } } public static void main(String[] args) throws Exception { if (args.length < 1) { throw new RuntimeException("Please provide memcached servers."); } final int threads = 100; final int repeat = 50000; int size = 1024; String servers = args[0]; final AtomicInteger failure = new AtomicInteger(); final AtomicInteger success = new AtomicInteger(); MemcachedClientBuilder builder = new XMemcachedClientBuilder( AddrUtil.getAddresses(servers)); //builder.setCommandFactory(new BinaryCommandFactory()); MemcachedClient client = builder.build(); ClockWatch watch = new ClockWatch(); CyclicBarrier barrier = new CyclicBarrier(threads + 1, watch); for (int i = 0; i < threads; i++) { new TestThread(repeat, i * repeat * 2, size, client, failure, success, barrier).start(); } new Thread() { public void run() { try { while (success.get() + failure.get() < repeat * threads) { Thread.sleep(1000); System.out.println("success:" + success.get() + ",failure:" + failure.get()); } } catch (Exception e) { e.printStackTrace(); } } }.start(); watch.start(); barrier.await(); barrier.await(); long secs = watch.getDurationInMillis() / 1000; int total = 4 * repeat * threads; long tps = total / secs; client.shutdown(); System.out.println("duration:" + secs + " seconds,tps:" + tps + " op/seconds,total:" + total + " ops"); } }