Reputation: 1911
I'm attempting to use xodus as a store, because I want a store of that type, and the benchmarks make it out to be fast.
However, in practice, the writes seem to be really slow.
I'm setting up two stores with a pattern like this:
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);
}
});
Then, I write with a pattern like this:
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);
});
Feeding the data into this pattern, I have a couple of threads, each reading and parsing data - 1 for each environment that I am populating.
I had expected my read / parse to the the bottleneck... but in practice, the bottleneck is in the xodus write.
I had thought that I could have xodus write in parallel, so I did my writes in a thread pool - but that made the performance even worse. To date, the best performance seems to happen when I disable the garbage collector, and only allow 1 thread to write to the xodus store.
Am I doing something wrong? With one thread, the slow part is everything that happens below ReadWriteTransaction.doCommit(). With multiple threads, they all just block and wait on ReentrantTransactionDispatcher.waitForPermits().
I could probably use two different environments, which would probably help by 1/2.... but it just feels like something is quite wrong, if I can't have two threads writing unrelated keys to xodus at the same time, without them contending.
As a side note, is this the best place to talk about xodus usage? I didn't see a forum or anything.
Upvotes: 0
Views: 335
Reputation: 2053
Concurrent writes to a single Environment always contend even if written data seems to be completely decoupled (unrelated). There are two ways to reduce the contention:
executeInExclusiveTransaction
method instead of executeInTransaction
. This approach will arrange not only user transactions, but background GC transactions as well. The disadvantage is that it orders also a preparatory work for writes (defined in a lambda passed to the method) which probably could be executed in parallel.exodus.log.cache.shared=false
. In addition, different Environments can be physically isolated on different storage devices.Upvotes: 1