xodus用并行线程写性能?

时间:2018-06-04 21:19:53

标签: xodus

我正在尝试将xodus用作商店,因为我想要一个这种类型的商店,并且基准测试可以让它变得更快。

然而,在实践中,写入似乎非常慢。

我正在设置两个商店,其模式如下:

environment = Environments.newInstance(xodusDBFolder);  
Store initialStateStore = environment.computeInTransaction(new TransactionalComputable<Store>()
    {
        @Override
        public Store compute(@NotNull final Transaction txn)
        {
            return environment.openStore("initialStateStore", StoreConfig.WITHOUT_DUPLICATES, txn);
        }
    });

然后,我用这样的模式写:

environment.executeInTransaction((Transaction txn) -> {
    ArrayByteIterable key = IntegerBinding.intToEntry(c.getNid());
    ByteIterable oldValue = store.get(txn, key);    
    ArrayByteIterable value;
    if (oldValue != null)    
    {
        //merge contents...
    }
    ....
   value = new ArrayByteIterable(rawData);
   store.put(txn, key, value);
});

将数据提供给这种模式,我有几个线程,每个线程读取和解析数据 - 我填充的每个环境都有1个。 我原本以为我的读/解是瓶颈......但实际上,瓶颈在xodus写中。

我原本以为我可以并行编写xodus,所以我在线程池中写了 - 但这使得性能更差。到目前为止,当我禁用垃圾收集器并且只允许1个线程写入xodus存储时,似乎会发生最佳性能。

我做错了吗?使用一个线程,慢速部分是ReadWriteTransaction.doCommit()下面发生的所有事情。对于多个线程,它们都只是阻塞并等待ReentrantTransactionDispatcher.waitForPermits()。

我可能会使用两种不同的环境,这可能会对1/2提供帮助....但是如果我不能让两个线程同时将不相关的密钥写入xodus,那么它就会感觉非常错误,没有他们的竞争。

作为旁注,这是讨论xodus使用的最佳地点吗?我没有看到论坛或其他任何内容。

1 个答案:

答案 0 :(得分:1)

即使写入的数据似乎完全解耦(无关),对单个环境的并发写入也始终存在争议。有两种方法可以减少争用:

  1. 使用executeInExclusiveTransaction方法而不是executeInTransaction按顺序写入。此方法不仅会安排用户事务,还会安排后台GC事务。缺点是它还要求编写一个准备工作(在传递给方法的lambda中定义),这可能是并行执行的。
  2. 将单个环境拆分为多个环境。如果同时写入的数据实际上是无关的(即至少它不需要一些一致性),它可以保存在不同的事务中不同的环境中。除非您定义exodus.log.cache.shared=false,否则使用单个JVM中创建的数百个环境可以很好地记录共享缓存。此外,可以在不同的存储设备上物理隔离不同的环境。