Package org.jredis.bench

Source Code of org.jredis.bench.JRedisBenchmark$BenchmarkWorker

/*
*   Copyright 2009 Joubin Mohammad Houshyar
*
*   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 org.jredis.bench;

import static org.jredis.bench.Util.getRandomString;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
//import org.jredis.ClientRuntimeException;
//import org.jredis.JRedis;
//import org.jredis.RedisException;
//import org.jredis.bench.Util.Timer;
//import org.jredis.protocol.Command;
//
import org.jredis.ClientRuntimeException;
import org.jredis.JRedis;
import org.jredis.RedisException;
import org.jredis.bench.Util.Timer;
import org.jredis.protocol.Command;

/**
* Runs a few benchmarks for the {@link SocketConnection}, using a concurrent set of workers, each with its own
* unique connection to the Redis server. 
* @author Joubin Houshyar (alphazero@sensesay.net)
*/
public abstract class JRedisBenchmark {
 
  /** password used to AUTH with redis select -- password is: jredis */
  public static final String password = "jredis";

  // ------------------------------------------------------------------------
  // Helper methods
  // ------------------------------------------------------------------------

  // ------------------------------------------------------------------------
  // For test data
  // ------------------------------------------------------------------------
  final static Random     random = new Random(System.currentTimeMillis());
 
  /**  */
  byte[]       fixedbytes;

  /**  */
  static List<String>    stringList = new ArrayList<String>();
   
  protected boolean quitOnRunEnd = true;
  /**
     * @param b
     */
    protected void quitOnRunEnd (boolean flag) { this.quitOnRunEnd = flag; }
  // ------------------------------------------------------------------------
  // Extension Points
  // ------------------------------------------------------------------------
  protected abstract Class<? extends JRedis> getImplementationClass();
  /**
   * Define this method to test a specific JRedis implementation.
   *
   * @param host
   * @param port
   * @return
   */
  protected abstract JRedis newConnection(String host, int port, int db, String password) throws ClientRuntimeException;

  /**
   * Runs a set of command primitives test runs using concurrent clients. [TODO: add all commands - this is a sampling of a few.]
   * <p><b>Be advised that this will FLUSH the db specified.</b>  Defaults to database at index 13:  i.e. <code>jredis.select(13).flushdb()</code>.
   * This bench will use <code>AUTH</code> to make sure you do not accidentally destroy important data
   * when runnign the benchmark.  (If you don't have a password on your db, it can't be that important, right?)
   *
   * <p>Further note that this will use the password <code><b>jredis</b></code> so either
   * make sure the redis.conf <code>requirepass</code> is set appropriately or simply comment it out.
   *
   * @param host
   * @param port
   * @param threadCnt
   * @param reqCnt
   * @param size
   * @param db
   */
 
  protected final void  runBenchmarks(String host, int port, int threadCnt, int reqCnt, int size, int db)
  {
//    random = new Random(System.currentTimeMillis());
   
    fixedbytes = new byte[size];
    random.nextBytes(fixedbytes);
    /** setup data */
    for(int i=0; i<reqCnt; i++){
//      keys.add(getRandomString (48));
//      patternList.add(getRandomString(random.nextInt(10)+2) + patternA + getRandomString(random.nextInt(10)+2));
//      uniqueSet.add(getRandomString(48));
//      commonSet.add(getRandomString(48));
//      set1.add("set_1" + getRandomString(20));
//      set2.add("set_2" + getRandomString(20));
//      dataList.add(getRandomBytes (128));
      stringList.add(getRandomString (128));
//      objectList.add(new TestBean("testbean." + i));
//      intList.add(random.nextInt());
//      longList.add(random.nextLong());
    }
    BenchmarkWorker[] workers = new BenchmarkWorker[threadCnt];

    System.out.println ();
    System.out.println("-------------------------------------------------------------------- JREDIS ----");
    System.out.println("---");
    System.out.format ("--- Benchmarking JRedis provider: %s\n", getImplementationClass().getName());
    System.out.format ("--- host:%s:%d (db:%d) | bytes:%d | threads:%d | reqs/conn:%d \n", host, port, db, size ,threadCnt, reqCnt);
    System.out.println("---");
    System.out.println("--------------------------------------------------------------------------------\n\n");

    for(int i=0;i<threadCnt;i++) workers[i] = newPingWorker (host, port, db);
    Benchmarker.runBenchmark (Command.PING, reqCnt, threadCnt, workers);

    for(int i=0;i<threadCnt;i++) workers[i] = newSetWorker (host, port, db);
    Benchmarker.runBenchmark (Command.SET, reqCnt, threadCnt, workers);

    for(int i=0;i<threadCnt;i++) workers[i] = newSetWorker (host, port, db);
    Benchmarker.runBenchmark (Command.GET, reqCnt, threadCnt, workers);

    for(int i=0;i<threadCnt;i++) workers[i] = newSetnxWorker (host, port, db);
    Benchmarker.runBenchmark (Command.SETNX, reqCnt, threadCnt, workers);

    for(int i=0;i<threadCnt;i++) workers[i] = newIncrWorker (host, port, db);
    Benchmarker.runBenchmark (Command.INCR, reqCnt, threadCnt, workers);

    for(int i=0;i<threadCnt;i++) workers[i] = newDecrWorker (host, port, db);
    Benchmarker.runBenchmark (Command.DECR, reqCnt, threadCnt, workers);

    for(int i=0;i<threadCnt;i++) workers[i] = newIncrbyWorker (host, port, db);
    Benchmarker.runBenchmark (Command.INCRBY, reqCnt, threadCnt, workers);

    for(int i=0;i<threadCnt;i++) workers[i] = newDecrbyWorker (host, port, db);
    Benchmarker.runBenchmark (Command.DECRBY, reqCnt, threadCnt, workers);

    for(int i=0;i<threadCnt;i++) workers[i] = newDbsizeWorker (host, port, db);
    Benchmarker.runBenchmark (Command.DBSIZE, reqCnt, threadCnt, workers);

    for(int i=0;i<threadCnt;i++) workers[i] = newLPushWorker (host, port, db);
    Benchmarker.runBenchmark (Command.LPUSH, reqCnt, threadCnt, workers);

    for(int i=0;i<threadCnt;i++) workers[i] = newRPushWorker (host, port, db);
    Benchmarker.runBenchmark (Command.RPUSH, reqCnt, threadCnt, workers);

    for(int i=0;i<threadCnt;i++) workers[i] = newLPopWorker (host, port, db);
    Benchmarker.runBenchmark (Command.LPOP, reqCnt, threadCnt, workers);

    for(int i=0;i<threadCnt;i++) workers[i] = newRPopWorker (host, port, db);
    Benchmarker.runBenchmark (Command.RPOP, reqCnt, threadCnt, workers);

    for(int i=0;i<threadCnt;i++) workers[i] = newLLenWorker (host, port, db);
    Benchmarker.runBenchmark (Command.LLEN, reqCnt, threadCnt, workers);

    for(int i=0;i<threadCnt;i++) workers[i] = newScardWorker (host, port, db);
    Benchmarker.runBenchmark (Command.SCARD, reqCnt, threadCnt, workers);

   
    for(int i=0;i<threadCnt;i++) workers[i] = newSaddWorker (host, port, db);
    Benchmarker.runBenchmark (Command.SADD, reqCnt, threadCnt, workers);

    for(int i=0;i<threadCnt;i++) workers[i] = newSremWorker (host, port, db);
    Benchmarker.runBenchmark (Command.SREM, reqCnt, threadCnt, workers);

    //    for(int i=0;i<connectionCnt;i++) workers[i] = newSmembersWorker();
//    Benchmarker.runBenchmark (Command.SMEMBERS, reqCnt, connectionCnt, workers);
   
  }
  // ------------------------------------------------------------------------
  // The workers
  // ------------------------------------------------------------------------
 
  /** does the PING */
  public  final BenchmarkWorker newPingWorker (String host, int port, int db) {
    return new BenchmarkWorker (host, port, db){
      @Override
      protected void prep() {}
      @Override
      protected void work() {
        for(int i=0; i<reqCnt; i++){
          try {
            jredis.ping();
          }
          catch (RedisException e) { e.printStackTrace(); }
        }
      }
    };
  }
 
  /** does the DBSIZE */
  public  final BenchmarkWorker newDbsizeWorker (String host, int port, int db) {
    return new BenchmarkWorker (host, port, db){
      @Override
      protected void prep() {}
      @Override
      protected void work() {
        for(int i=0; i<reqCnt; i++){
          try {
            jredis.dbsize();
          }
          catch (RedisException e) { e.printStackTrace(); }
        }
      }
    };
  }

  /** does the SADD */
  public final BenchmarkWorker newSaddWorker (String host, int port, int db) {
    return new BenchmarkWorker (host, port, db){
      String key = "num_" + id;
      @Override
      protected void prep() { }
      @Override
      protected void work() {
        for(int i=0; i<reqCnt; i++) {
          try {
            jredis.sadd (key, i);
          }
          catch (RedisException e) { e.printStackTrace(); }
        }
      }
    };
  }
 
  /** does the SREM */
  public final BenchmarkWorker newSremWorker (String host, int port, int db) {
    return new BenchmarkWorker (host, port, db){
      String key = "num_" + id;
      @Override
      protected void prep() {
        for(int i=0; i<reqCnt; i++) {
          try {
            jredis.sadd (key, i);
          }
          catch (RedisException e) { e.printStackTrace(); }
        }
      }
      @Override
      protected void work() {
        for(int i=0; i<reqCnt; i++) {
          try {
            jredis.srem (key, i);
          }
          catch (RedisException e) { e.printStackTrace(); }
        }
      }
    };
  }
 
  /** does the SCARD */
  public final BenchmarkWorker newScardWorker (String host, int port, int db) {
    return new BenchmarkWorker (host, port, db){
      String key = "num_" + id;
      @Override
      protected void prep() {
        for(int i=0; i<reqCnt; i++) {
          try {
            jredis.sadd (key, i);
          }
          catch (RedisException e) { e.printStackTrace(); }
        }
      }
      @Override
      protected void work() {
        for(int i=0; i<reqCnt; i++) {
          try {
            jredis.scard (key);
          }
          catch (RedisException e) { e.printStackTrace(); }
        }
      }
    };
  }
 
  /** does the LLEN */
  public final BenchmarkWorker newLLenWorker (String host, int port, int db) {
    return new BenchmarkWorker (host, port, db){
      String key = "num_" + id;
      @Override
      protected void prep() {
        for(int i=0; i<reqCnt; i++) {
          try {
            jredis.lpush (key, 1);
          }
          catch (RedisException e) { e.printStackTrace(); }
        }
      }
      @Override
      protected void work() {
        for(int i=0; i<reqCnt; i++) {
          try {
            jredis.llen (key);
          }
          catch (RedisException e) { e.printStackTrace(); }
        }
      }
    };
  }
 
  /** does the LPOP */
  public final BenchmarkWorker newLPopWorker (String host, int port, int db) {
    return new BenchmarkWorker (host, port, db){
      String key = "num_" + id;
      @Override
      protected void prep() {
        for(int i=0; i<reqCnt; i++) {
          try {
            jredis.lpush (key, 1);
          }
          catch (RedisException e) { e.printStackTrace(); }
        }
      }
      @Override
      protected void work() {
        for(int i=0; i<reqCnt; i++) {
          try {
            jredis.lpop (key);
          }
          catch (RedisException e) { e.printStackTrace(); }
        }
      }
    };
  }

  /** does the RPOP */
  public final BenchmarkWorker newRPopWorker (String host, int port, int db) {
    return new BenchmarkWorker (host, port, db){
      String key = "num_" + id;
      @Override
      protected void prep() {
        for(int i=0; i<reqCnt; i++) {
          try {
            jredis.lpush (key, 1);
          }
          catch (RedisException e) { e.printStackTrace(); }
        }
      }
      @Override
      protected void work() {
        for(int i=0; i<reqCnt; i++) {
          try {
            jredis.rpop (key);
          }
          catch (RedisException e) { e.printStackTrace(); }
        }
      }
    };
  }

  /** does the LPUSH */
  public final BenchmarkWorker newLPushWorker (String host, int port, int db) {
    return new BenchmarkWorker (host, port, db){
      String key = "num_" + id;
      @Override
      protected void prep() { }
      @Override
      protected void work() {
        for(int i=0; i<reqCnt; i++) {
          try {
            jredis.lpush (key, i);
          }
          catch (RedisException e) { e.printStackTrace(); }
        }
      }
    };
  }

  /** does the RPUSH */
  public final BenchmarkWorker newRPushWorker (String host, int port, int db) {
    return new BenchmarkWorker (host, port, db){
      String key = "num_" + id;
      @Override
      protected void prep() { }
      @Override
      protected void work() {
        for(int i=0; i<reqCnt; i++) {
          try {
            jredis.rpush (key, i);
          }
          catch (RedisException e) { e.printStackTrace(); }
        }
      }
    };
  }

  /** does the INCR */
  public final BenchmarkWorker newIncrWorker (String host, int port, int db) {
    return new BenchmarkWorker (host, port, db){
      String key = "num_" + id;
      @Override
      protected void prep() { }
      @Override
      protected void work() {
        for(int i=0; i<reqCnt; i++) {
          try {
            jredis.incr (key);
          }
          catch (RedisException e) { e.printStackTrace(); }
        }
      }
    };
  }

  /** does the DECR */
  public final BenchmarkWorker newDecrWorker (String host, int port, int db) {
    return new BenchmarkWorker (host, port, db){
      String key = "num_" + id;
      @Override
      protected void prep() { }
      @Override
      protected void work() {
        for(int i=0; i<reqCnt; i++) {
          try {
            jredis.decr (key);
          }
          catch (RedisException e) { e.printStackTrace(); }
        }
      }
    };
  }
  /** does the INCRBY */
  public final BenchmarkWorker newIncrbyWorker (String host, int port, int db) {
    return new BenchmarkWorker (host, port, db){
      String key = "num_" + id;
      @Override
      protected void prep() { }
      @Override
      protected void work() {
        for(int i=0; i<reqCnt; i++) {
          try {
            jredis.incrby (key, 10);
          }
          catch (RedisException e) { e.printStackTrace(); }
        }
      }
    };
  }

  /** does the DECR */
  public final BenchmarkWorker newDecrbyWorker (String host, int port, int db) {
    return new BenchmarkWorker (host, port, db){
      String key = "num_" + id;
      @Override
      protected void prep() { }
      @Override
      protected void work() {
        for(int i=0; i<reqCnt; i++) {
          try {
            jredis.decrby (key, 10);
          }
          catch (RedisException e) { e.printStackTrace(); }
        }
      }
    };
  }

  /** does the SET */
  public  final BenchmarkWorker newSetWorker (String host, int port, int db) {
    return new BenchmarkWorker (host, port, db){
      byte[] data = fixedbytes;
      String key = id + ":fixedbytes:string";
      @Override
      protected void prep() {  }
      @Override
      protected void work() {
        for(int i=0; i<reqCnt; i++){
          try {
            jredis.set(key, data);
          }
          catch (RedisException e) { e.printStackTrace(); }
        }
      }
    };
  }

  /** does the SETNX */
  public  final BenchmarkWorker newSetnxWorker (String host, int port, int db) {
    return new BenchmarkWorker (host, port, db){
      byte[] data = fixedbytes;
      String key = id + ":fixedbytes:string";
      @Override
      protected void prep() {  }
      @Override
      protected void work() {
        for(int i=0; i<reqCnt; i++){
          try {
            jredis.setnx (key, data);
          }
          catch (RedisException e) { e.printStackTrace(); }
        }
      }
    };
  }
  /** does the GET */
  public  final BenchmarkWorker newGetWorker (String host, int port, int db) {
    return new BenchmarkWorker (host, port, db){
      byte[] data = fixedbytes;
      String key = id + ":fixedbytes:string";
      @Override
      protected void prep() {
        try {
          for(int i=0; i<reqCnt; i++){
            jredis.set(key, data);
          }
        }
        catch (RedisException e) { e.printStackTrace(); }
      }
      @Override
      protected void work() {
        try {
          for(int i=0; i<reqCnt; i++){
            jredis.get("fixedbytes_"+id);
          }
        }
        catch (RedisException e) { e.printStackTrace(); }
      }
    };
  }
  /** does the SMEMBERS */
  public  final BenchmarkWorker newSmembersWorker (String host, int port, int db) {
    return new BenchmarkWorker (host, port, db){
      List<String>  values = JRedisBenchmark.stringList;
      String key = id + ":stringList:set";
      @Override
      protected void prep() {
        try {
          for(int i=0; i<values.size(); i++){
            jredis.sadd (key, values.get(i));
          }
        }
        catch (RedisException e) { e.printStackTrace(); }
      }
      @Override
      protected void work() {
        try {
          for(int i=0; i<reqCnt; i++){
            jredis.smembers(key);
          }
        }
        catch (RedisException e) { e.printStackTrace(); }
      }
    };
  }
 
  // ------------------------------------------------------------------------
  // The Benchmarker
  // ------------------------------------------------------------------------
 
  public static class Benchmarker {
    public static final void runBenchmark(final Command cmd, final int reqCnt, final int threadCnt, final BenchmarkWorker[] workers) {
      new Benchmarker(cmd, reqCnt, threadCnt, workers).runBenchmark();
    }
    private Command cmd;
    private BenchmarkWorker[] workers;
    private int threadCnt;
    private int reqCnt;
    private Benchmarker (final Command cmd, final int reqCnt, final int threadCnt, final BenchmarkWorker[] workers) {
      this.cmd = cmd;
      this.reqCnt = reqCnt;
      this.threadCnt = threadCnt;
      this.workers = workers;
    }
   
    private void runBenchmark () {
     
      String host = workers[0].host;
     
      final long[]         deltas = new long[threadCnt];
      final CountDownLatch   completion = new CountDownLatch(threadCnt);
      final CountDownLatch   ready = new CountDownLatch(threadCnt);
      final CountDownLatch   mark = new CountDownLatch(1);

      for(int i=0; i<threadCnt; i++){
        workers[i].id = i;
        workers[i].completion = completion;
        workers[i].mark = mark;
        workers[i].ready = ready;
        workers[i].reqCnt = reqCnt;
        workers[i].deltas = deltas;
        new Thread (workers[i]).start();
      }
     
      try {
        /* run benchmark workers */
        ready.await();                    // ready
        Timer timer = Timer.startNewTimer();        // set
        mark.countDown();                   // go
       
        System.out.print(" ...\n");
        completion.await();                 // ... done

        timer.mark();
       
        /* report */
          // overall - this is throughput
        System.out.format("===== %s =====\n",cmd.code);
        System.out.format("%d concurrent clients (%d %ss each) [host: %s]\n", threadCnt, reqCnt, cmd.code, host);
        System.out.format("  ==> %d total requests @ %f seconds\n", threadCnt*reqCnt, (float)timer.deltaAtMark(TimeUnit.SECONDS));
        System.out.format("  ==> %f/second\n", (float)timer.opsPerSecAtMark((long)threadCnt*reqCnt));
        System.out.println();
       
          // report for each - this is response time
        long max = Long.MIN_VALUE;
        long min = Long.MAX_VALUE;
        for(int i=0; i<threadCnt; i++){
          min = deltas[i]<min ? deltas[i] : min;
          max = deltas[i]>max ? deltas[i] : max;
        }
        System.out.format("\t\t\tmin: %s msecs\n\t\t\tmax: %s msecs\n\n", min, max);
      }
      catch (Exception e) {
        e.printStackTrace();
      }
    }
  }
 
  // ------------------------------------------------------------------------
  // Base for all workers
  // ------------------------------------------------------------------------
 
  /**
   * Abstract base class for all benchmark workers.  This is a runnable that
   * uses the template pattern in the run method and takes care of common
   * time keeping tasks for the specific (child class) workers.
   */
  public abstract class BenchmarkWorker implements Runnable {
    final String host;
    final int port;
   
    long[] deltas;
    CountDownLatch ready;
    CountDownLatch completion;
    CountDownLatch mark;
    int reqCnt;
    int id;
    int db;

    JRedis jredis = null;
   
    public BenchmarkWorker (String host, int port, int db) {
      this.host = host;
      this.port = port;
      this.db = db;
    }
   
    /**
     * <p>1 - connects to the redis server
     * <p>2 - calls the {@link BenchmarkWorker#prep()} -- subclasses will implement this
     * <p>3 - waits for the mark signal to start the calls
     * <p>4 - gets the sys time, and ..
     * <p>5 - calls the {@link BenchmarkWorker#work()} method -- subclasses will implement this
     * <p>6 - gets the sys time -- this is the time delta for this worker
     * <p>7 - closes the connection, and signals completion to the benchmarker.
     */
    public void run() {
      try {

        jredis = newConnection (host, 6379, db, password);
        try {
//          jredis.auth (password).select(db).flushdb();
          jredis.flushdb();
        }
        catch (RedisException e) {       
          System.err.format("BENCHMARK::REDIS %s ERROR => %s\nWorker will stop.\n", e.getCommand(), e.getLocalizedMessage());
          System.exit (1);
        }
       
        prep();
        ready.countDown();
        mark.await();    // wait sig
        long start=0;
        start = System.currentTimeMillis();
        work();
        deltas[id] = System.currentTimeMillis() - start;
       
        if(quitOnRunEnd)
          jredis.quit();
        completion.countDown()// sig done
      }
      catch (Exception e){
        System.err.format("BENCHMARK::Exception => %s\nWill stop.\n", e.getLocalizedMessage());
      }
    }
    /** anything that needs to be done to setup the calls -- typically all time consuming data setup tasks go here ...*/
    protected abstract void prep();
    /** Typically just a tight loop calling the redis server for the given test and using the data prep'd in {@link BenchmarkWorker#prep()} */
    protected abstract void work();
  }
}
TOP

Related Classes of org.jredis.bench.JRedisBenchmark$BenchmarkWorker

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.