RocksDB: Как исправить снижение производительности с помощью двухзаписного потока в многопоточном тесте? - PullRequest
0 голосов
/ 29 января 2019

Я тестирую многопотоковую производительность записи RocksDB с помощью Java.

Я использовал 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();
        }
    }

}

...