2016-09-25 7 views
2

私はorient db embeddedのjmhテストをセットアップしようとしています。次のようにテストスイートは、次のとおりです。orientdbにjmh testingを組み込む方法は?

@State(Scope.Benchmark) 
public class OrientDbTest { 
    private OObjectDatabaseTx db; 
    private Person[] personList; 

    @Setup 
    public void setUp() throws IOException { 
     deleteDir("/tmp/orientdb/"); 
     db = new OObjectDatabaseTx("plocal:/tmp/orientdb/person").create(); 
     ODatabaseRecordThreadLocal.INSTANCE.set(db.getUnderlying()); 
     loadData(); 
    } 

    @TearDown 
    public void cleanUp() { 
     if (db != null) { 
      ODatabaseRecordThreadLocal.INSTANCE.set(db.getUnderlying()); 
      db.commit(); 
      db.drop(); 
      db.close(); 
     } 
    } 

    @Benchmark 
    @BenchmarkMode(Mode.AverageTime) 
    @OutputTimeUnit(TimeUnit.MICROSECONDS) 
    public void benchmarkInsertCompany() { 
     ODatabaseRecordThreadLocal.INSTANCE.set(db.getUnderlying()); 
     db.getEntityManager().registerEntityClass(Person.class); 

     for (Person person : personList) { 
      db.save(person); 
     } 
    } 

    void loadData() throws IOException { 
     InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("data.json"); 
     ObjectMapper objectMapper = new ObjectMapper(); 
     personList = objectMapper.readValue(inputStream, Person[].class); 
    } 

    void deleteDir(String dirName) { 
     File file = new File(dirName); 
     if (file.exists()) { 
      File[] files = file.listFiles(); 
      if (files != null) { 
       for (File child : files) { 
        if (child.isDirectory()) { 
         deleteDir(child.getAbsolutePath()); 
        } else { 
         child.delete(); 
        } 
       } 
      } else { 
       file.delete(); 
      } 
     } 
    } 
} 

このプロジェクトは、Gradleのプロジェクトであり、私はGradleの-JMHプラグインを使用して実行しています。ここではbuild.gradleファイルにJMH設定は次のとおりです。

jmh { 
    jmhVersion = '1.14' 
    iterations = 10 // Number of measurement iterations to do. 
    fork = 2 // How many times to forks a single benchmark. Use 0 to disable forking altogether 
    jvmArgs = '-server -XX:MaxDirectMemorySize=15986m' 
    resultsFile = project.file("${project.buildDir}/reports/jmh/results.txt") // results file 
    profilers = ['cl', 'gc', 'hs_thr'] // Use profilers to collect additional data. Supported profilers: [cl, comp, gc, stack, perf, perfnorm, perfasm, xperf, xperfasm, hs_cl, hs_comp, hs_gc, hs_rt, hs_thr] 
    resultFormat = 'CSV' // Result format type (one of CSV, JSON, NONE, SCSV, TEXT) 
    threads = 4 // Number of worker threads to run with. 
    timeUnit = 'ms' // Output time unit. Available time units are: [m, s, ms, us, ns]. 
    warmupForks = 2 // How many warmup forks to make for a single benchmark. 0 to disable warmup forks. 
    warmupIterations = 10 // Number of warmup iterations to do. 
} 

私がテストを実行しているとき、私はエラーの下に取得しています:

INFO: OrientDB auto-config DISKCACHE=10,384MB (heap=3,554MB direct=15,986MB os=15,986MB) 
<failure> 

com.orientechnologies.orient.core.exception.OStorageExistsException: Cannot create new storage 'plocal:/tmp/orientdb/person' because it is not closed 
     DB name="person" 
     at com.orientechnologies.orient.core.storage.impl.local.OAbstractPaginatedStorage.create(OAbstractPaginatedStorage.java:423) 
     at com.orientechnologies.orient.core.storage.impl.local.paginated.OLocalPaginatedStorage.create(OLocalPaginatedStorage.java:125) 
     at com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx.create(ODatabaseDocumentTx.java:429) 
     at com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx.create(ODatabaseDocumentTx.java:389) 
     at com.orientechnologies.orient.core.db.ODatabaseWrapperAbstract.create(ODatabaseWrapperAbstract.java:75) 
     at org.dizitart.no2.benchmark.OrientDbTest.setUp(OrientDbTest.java:24) 
     at org.dizitart.no2.benchmark.generated.OrientDbTest_benchmarkInsertCompany_jmhTest._jmh_tryInit_f_orientdbtest0_G(OrientDbTest_benchmarkInsertCompany_jmhTest.java:400) 
     at org.dizitart.no2.benchmark.generated.OrientDbTest_benchmarkInsertCompany_jmhTest.benchmarkInsertCompany_AverageTime(OrientDbTest_benchmarkInsertCompany_jmhTest.java:149) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
     at java.lang.reflect.Method.invoke(Method.java:498) 
     at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:430) 
     at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:412) 
     at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
     at java.lang.Thread.run(Thread.java:745) 

私はここの設定に間違って何をしているのですか?

EDIT

次のようにthisを読んだ後、私は、コードを変更:

public class OrientDbTest { 

    @State(Scope.Benchmark) 
    public static class TestState { 
     private OObjectDatabaseTx db; 
     private Person[] personList; 
     private BenchmarkTestHelper testHelper = new BenchmarkTestHelper(); 

     @Setup(Level.Trial) 
     public void setUp() throws IOException { 
      System.out.println("started setup code"); 
      testHelper.deleteDir("/tmp/orientdb/"); 

      try { 
       db = new OObjectDatabaseTx("plocal:/tmp/orientdb/person").open(null, null); 
       db.getEntityManager().registerEntityClass(Person.class); 
       personList = testHelper.loadData(); 
      } finally { 
       if (db != null) { 
        db.close(); 
       } 
      } 
     } 

     @TearDown(Level.Trial) 
     public void cleanUp() { 
      System.out.println("started cleanup code"); 
      if (db != null) { 
       ODatabaseRecordThreadLocal.INSTANCE.set(db.getUnderlying()); 
       db.commit(); 
       db.drop(); 
       db.close(); 
      } 
     } 
    } 

    @Benchmark 
    @BenchmarkMode(Mode.AverageTime) 
    @OutputTimeUnit(TimeUnit.MICROSECONDS) 
    public void benchmarkInsertCompany(TestState state, Blackhole blackhole) { 
     OObjectDatabaseTx db = state.db; 
     Person[] personList = state.personList; 

     ODatabaseRecordThreadLocal.INSTANCE.set(db.getUnderlying()); 
     for (Person person : personList) { 
      blackhole.consume(db.save(person)); 
     } 
    } 
} 


class BenchmarkTestHelper { 
    Person[] loadData() throws IOException { 
     InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("data.json"); 
     ObjectMapper objectMapper = new ObjectMapper(); 
     return objectMapper.readValue(inputStream, Person[].class); 
    } 

    void deleteDir(String dirName) { 
     File file = new File(dirName); 
     if (file.exists()) { 
      File[] files = file.listFiles(); 
      if (files != null) { 
       for (File child : files) { 
        if (child.isDirectory()) { 
         deleteDir(child.getAbsolutePath()); 
        } else { 
         child.delete(); 
        } 
       } 
       file.delete(); 
      } else {     
       file.delete(); 
      } 
     } 
    } 
} 

新しいセットアップした後、私はエラーの下に取得しています:

# JMH 1.14 (released 19 days ago) 
# VM version: JDK 1.8.0_77, VM 25.77-b03 
# VM invoker: /home/anindya/app/jdk1.8.0_77/jre/bin/java 
# VM options: -server -XX:MaxDirectMemorySize=15986m 
# Warmup: 10 iterations, 1 s each 
# Measurement: 10 iterations, 1 s each 
# Timeout: 10 min per iteration 
# Threads: 4 threads, will synchronize iterations 
# Benchmark mode: Average time, time/op 
# Benchmark: org.dizitart.no2.benchmark.OrientDbTest.benchmarkInsertCompany 

# Run progress: 50.00% complete, ETA 00:01:28 
# Warmup Fork: 1 of 2 
# Warmup Iteration 1: started setup code 
Sep 26, 2016 11:15:57 AM com.orientechnologies.common.log.OLogManager log 
INFO: OrientDB auto-config DISKCACHE=10,384MB (heap=3,554MB direct=15,986MB os=15,986MB) 
started setup code 
started setup code 
started setup code 
<failure> 

com.orientechnologies.orient.core.exception.OStorageExistsException: Cannot create new storage 'plocal:/tmp/orientdb/person' because it is not closed 
     DB name="person" 
     at com.orientechnologies.orient.core.storage.impl.local.OAbstractPaginatedStorage.create(OAbstractPaginatedStorage.java:423) 
     at com.orientechnologies.orient.core.storage.impl.local.paginated.OLocalPaginatedStorage.create(OLocalPaginatedStorage.java:125) 
     at com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx.create(ODatabaseDocumentTx.java:429) 
     at com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx.create(ODatabaseDocumentTx.java:389) 
     at com.orientechnologies.orient.core.db.ODatabaseWrapperAbstract.create(ODatabaseWrapperAbstract.java:75) 
     at org.dizitart.no2.benchmark.OrientDbTest$TestState.setUp(OrientDbTest.java:28) 
     at org.dizitart.no2.benchmark.generated.OrientDbTest_benchmarkInsertCompany_jmhTest._jmh_tryInit_f_teststate1_G(OrientDbTest_benchmarkInsertCompany_jmhTest.java:409) 
     at org.dizitart.no2.benchmark.generated.OrientDbTest_benchmarkInsertCompany_jmhTest.benchmarkInsertCompany_AverageTime(OrientDbTest_benchmarkInsertCompany_jmhTest.java:153) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
     at java.lang.reflect.Method.invoke(Method.java:498) 
     at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:430) 
     at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:412) 
     at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
     at java.lang.Thread.run(Thread.java:745) 

... 

# Run progress: 87.50% complete, ETA 00:00:18 
# Fork: 2 of 2 
# Warmup Iteration 1: started setup code 
Sep 26, 2016 11:16:38 AM com.orientechnologies.common.log.OLogManager log 
INFO: OrientDB auto-config DISKCACHE=10,384MB (heap=3,554MB direct=15,986MB os=15,986MB) 
started setup code 
started setup code 
started setup code 
<failure> 

java.lang.ClassCastException: com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx cannot be cast to com.orientechnologies.orient.object.db.OObjectDatabaseTx 
     at org.dizitart.no2.benchmark.OrientDbTest$TestState.setUp(OrientDbTest.java:28) 
     at org.dizitart.no2.benchmark.generated.OrientDbTest_benchmarkInsertCompany_jmhTest._jmh_tryInit_f_teststate1_G(OrientDbTest_benchmarkInsertCompany_jmhTest.java:409) 
     at org.dizitart.no2.benchmark.generated.OrientDbTest_benchmarkInsertCompany_jmhTest.benchmarkInsertCompany_AverageTime(OrientDbTest_benchmarkInsertCompany_jmhTest.java:153) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
     at java.lang.reflect.Method.invoke(Method.java:498) 
     at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:430) 
     at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:412) 
     at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
     at java.lang.Thread.run(Thread.java:745) 


Sep 26, 2016 11:16:49 AM com.orientechnologies.common.log.OLogManager log 
INFO: Orient Engine is shutting down... 
Sep 26, 2016 11:16:49 AM com.orientechnologies.common.log.OLogManager log 
INFO: - shutdown storage: person... 
+0

これはJMHフォルトのようには見えません。作成/クリーンアップ手順が正しく動作するかどうかを確認します。それらを 'main'にヤンクし、create-cleanup-create-cleanupを連続して実行しようとします。私はあなたが実際にすべてのフォルダを削除した(例えば、フォルダの内容を削除した後の) 'deleteDir'とは思わない。 –

+0

同じオリエンテーションインスタンスを使用する他のプロセスがありますか? –

+0

いいえテストインスタンスの外側からではありません。しかし、私が疑うところは、別のスレッドがそれを作成しようとしている間、何らかの理由で他のjmhスレッドがdbを保持しているということです。 –

答えて

1

わかりましたので、トラブルのカップルがある:

A)setUp()方法自体はバギー、それはスロー:

java.lang.ClassCastException: com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx cannot be cast to com.orientechnologies.orient.object.db.OObjectDatabaseTx 
    at jmh.demo.OrientDbTest$TestState.setUp(OrientDbTest.java:30) 
    at jmh.demo.generated.OrientDbTest_benchmarkInsert_jmhTest._jmh_tryInit_f_teststate1_G(OrientDbTest_benchmarkInsert_jmhTest.java:409) 
    at jmh.demo.generated.OrientDbTest_benchmarkInsert_jmhTest.benchmarkInsert_AverageTime(OrientDbTest_benchmarkInsert_jmhTest.java:153) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
... 

B)を@State(Benchmark)ため@Setup方法は一度だけ実行されるようになっています。しかし、bug in JMHのために、上記の例外で最初のスレッドが失敗した場合、他のスレッドはと入力しようとします@Setupを入力しようとすると、データベースは開こうとしますが、

実際、障害(a)は元の投稿でも表示され、@Setupと入力された複数のスレッドから報告される例外は、幸運に左右されます(これはJMH 1.14.1で改善されました)。 threads = 1に設定すると、適切な例外が発生しても確実に失敗します。また、setUp()のクリーンアップパスがtearDown()と一致していないため、再入力されたスレッドがDBを開くことができない理由を説明している可能性があります。

ボトムライン:マルチスレッドテストを行う前に、シングルスレッドを実行してください。

+0

コメントありがとうございます。フォークを使用することが原因でした。私は答えに作業コードを投稿しました –

+0

待って、いいえ!あなたのテストが 'fork(0)'で動作し、 'fork(1)'ではない場合、テストは中断されます。異なる試行の間にデータを共有することは想定されていません。また、JMHの半分がゼロフォークで正常に動作していないため、恐ろしいメッセージが出力されます。 –

+0

私はfork(1)で試しましたが、その後、このコードでorientdbに何らかのデッドロックが発生しました。ログの場合、私のようにしか得られません - (割り込み*)(割り込み*)... –

0

db.drop(); ISN実行されていないため、エラーが発生しています:Cannot create new storage because it is not closed

0

アレクシーの答えは、のフォークを使用していることがわかりました。テストでは間違っていました。私は質問にもっと混乱を避けるためにここに作業コードを掲示しています。

public class OrientDbTest { 

    @State(Scope.Benchmark) 
    public static class TestState { 
     private OObjectDatabaseTx db; 
     private Person[] personList; 

     @Setup(Level.Trial) 
     public void setUp() throws IOException { 
      System.out.println("started setup code"); 
      try { 
       personList = loadData(); 
       deleteDir("/tmp/orientdb/"); 
       db = new OObjectDatabaseTx("plocal:/tmp/orientdb/person"); 
       if (db.exists()) { 
        db.open("admin", "admin"); 
        db.drop(); 
       } 
       db.create(); 
       db.getEntityManager().registerEntityClass(Person.class); 
       db.getEntityManager().registerEntityClass(Address.class); 
       db.getEntityManager().registerEntityClass(PrivateData.class); 
      } catch (Throwable e) { 
       System.out.println("error in creating db "); 
       e.printStackTrace(); 
      } 
     } 

     @TearDown(Level.Trial) 
     public void cleanUp() { 
      System.out.println("started cleanup code"); 
      if (db != null) { 
       ODatabaseRecordThreadLocal.INSTANCE.set(db.getUnderlying()); 
       db.commit(); 
       db.close(); 
      } 
     } 

     private void deleteDir(String dirName) { 
      File file = new File(dirName); 
      if (file.exists()) { 
       File[] files = file.listFiles(); 
       if (files != null) { 
        for (File child : files) { 
         if (child.isDirectory()) { 
          deleteDir(child.getAbsolutePath()); 
         } else { 
          child.delete(); 
         } 
        } 
        file.delete(); 
       } else { 
        file.delete(); 
       } 
      } 
     } 

     private Person[] loadData() throws IOException { 
      InputStream inputStream = Thread.currentThread() 
        .getContextClassLoader().getResourceAsStream("data.json"); 
      ObjectMapper objectMapper = new ObjectMapper(); 
      return objectMapper.readValue(inputStream, Person[].class); 
     } 
    } 

    @Benchmark 
    @BenchmarkMode(Mode.AverageTime) 
    @OutputTimeUnit(TimeUnit.MICROSECONDS) 
    @Fork(0) 
    public void benchmarkInsert(TestState state, Blackhole blackhole) { 
     OObjectDatabaseTx db = state.db; 
     Person[] personList = state.personList; 

     if (db == null) { 
      System.out.println("db null.. exiting"); 
      System.exit(0); 
     } 

     ODatabaseRecordThreadLocal.INSTANCE.set(db.getUnderlying()); 
     for (Person person : personList) { 
      blackhole.consume(db.save(person)); 
     } 
    } 
関連する問題