RocksDB:如何在多线程测试中解决2写线程导致的性能下降?

时间:2019-01-29 02:37:33

标签: rocksdb

我正在用Java测试RocksDB的多线程写入性能。

我使用了1、2、4和8个线程来编写测试并修改值的长度(100B,1K,2K,10K),但是在所有测试案例中我都遇到了2个线程写性能下降的问题。 1和4线程写入比2线程快。我想知道为什么。

有我的测试代码:

        <dependency>
            <groupId>org.rocksdb</groupId>
            <artifactId>rocksdbjni</artifactId>
            <version>5.15.10</version>
        </dependency>
package com.rdbtest;

import org.rocksdb.*;

import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

//muti test
public class Test6 extends Thread{
    public static final String STR="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

    public static byte[] getRandomString(Random random, int length){
        StringBuffer sb =new StringBuffer(length + 5);
        for(int i=0;i<length;i++){
            int number= random.nextInt(62);
            sb.append(STR.charAt(number));
        }
        return sb.toString().getBytes();
    }
    private RocksDB db;
    private int maxTreadNum;
    private static AtomicInteger writeComplete = new AtomicInteger(0);
    private long length,max;
    private long writeTimeUsed,readTimeUsed;
    byte[][] arrs;
    public long getWriteTimeUsed(){
        return writeTimeUsed;
    }
    public long getReadTimeUsed(){
        return readTimeUsed;
    }
    Test6(RocksDB db, int maxTreadNum, int length, long max, byte[][] arrs) {
        this.db = db;
        this.maxTreadNum = maxTreadNum;
        this.length = length;
        this.max = max;
        this.arrs = arrs;
    }

    @Override
    public void run() {
        Random rand = new Random(System.currentTimeMillis());
//        int max = 1000*10000;
        byte[][] rowkeylist = new byte[(int)this.max][];
        for(int i = 0 ; i< this.max;i++) {
            rowkeylist[i] = String.format("111aaa%010d",rand.nextInt(100000000)).getBytes();
        }
        try{
            long start = System.currentTimeMillis();
            long end  = 0;
            long timeUsed = 0;

            //write qps
            for(int i = 0 ; i < max;i++){

                db.put(rowkeylist[i], arrs[rand.nextInt(10000)]);
            }
            end = System.currentTimeMillis();
            timeUsed = end - start;
            writeTimeUsed = timeUsed;
            float qps = max*1.0f/timeUsed*1000;
            System.out.println("[write]useTime " + timeUsed + " ms, qps: "+qps);
            writeComplete.incrementAndGet();
            while(writeComplete.get() != maxTreadNum) {
                Thread.sleep(10);
            }

            //read qps
            start = System.currentTimeMillis();
            for(int i = 0 ; i < max;i++){
                byte[] ret = db.get(rowkeylist[i]);
            }
            end = System.currentTimeMillis();
            timeUsed = end - start;
            readTimeUsed = timeUsed;
            qps = max*1.0f/timeUsed*1000;
            System.out.println("[read]useTime " + timeUsed + " ms, qps: "+qps);

        }catch (Exception e) {
            System.out.println("error!!!");
            e.printStackTrace();
        }finally {

        }
    }

    public static void main(String[] args) {
        System.out.println("======================================");
        RocksDB.loadLibrary();
        RocksDB db = null;
        String path = args[0];
        int threadNum = Integer.parseInt(args[1]);
        int length = 1000;
        if(args.length >=3 ){
            length = Integer.parseInt(args[2]);
        }
        long max = 1000*10000;
        if(args.length >=4 ){
            max = Long.parseLong(args[3]);
        }
        byte[][] arrs = new byte[10000][];
        Random random=new Random(System.currentTimeMillis());
        for(int i = 0; i< 10000; i++) {
            arrs[i] = getRandomString(random,length);
        }


        System.out.println("Tread Num is :" + threadNum + " length:" + length + " max:" + max);
        try{
            Options options = new Options()
                    .setCreateIfMissing(true);
            options.setMaxBackgroundFlushes(4);
            options.setMaxBackgroundCompactions(4);
            db = RocksDB.open(options, path);
            Test6[] threads = new Test6[threadNum];
            for(int i = 0; i<threadNum;i ++) {
                threads[i] = new Test6(db, threadNum, length, max/threadNum, arrs);
                Thread.sleep(2);
                threads[i].start();
            }
            long maxWriteTime = 0;
            long maxReadTime = 0;
            for(int i = 0; i<threadNum;i ++) {
                threads[i].join();
                maxReadTime = Math.max(maxReadTime, threads[i].getReadTimeUsed());
                maxWriteTime = Math.max(maxWriteTime, threads[i].getWriteTimeUsed());
            }


            System.out.println("final result:");
            System.out.println("     write qps:"+(max*1.0/maxWriteTime*1000));
            System.out.println("     read qps:"+(max*1.0/maxReadTime*1000));
            System.out.println("exe complete");
        }catch (Exception e){
            System.out.println(e);
        }finally {
            db.close();
        }
    }

}

0 个答案:

没有答案