Motivation
One of the major changes in ArangoDB 2.2 was the introduction of the write-ahead log (abbreviated WAL).
The introduction of the WAL changed how documents are stored internally in ArangoDB. A lot of things have been changed for it under the hood, and it has been a lot of work to implement it.
During the implementation, we refactored some code parts and made them considerably faster. From these changes we expected a positive effect on the database performance. But due to the fact that shape information is now also saved in the write-ahead log, there may also be some negative effect.
We developers were of course very interested in seeing the net effects, so we ran some tests for a few use cases. We compared ArangoDB 2.1.2 (still without the WAL) with ArangoDB 2.2.1 (with the WAL). The results are interesting.
Test setup
To get a broad overview of performance changes, we ran a few different test cases:
- document: inserts a document
- crud: inserts a document, fetches it, updates it, and deletes it
- crud-append: inserts a document, fetches it, updates it, and fetches it again
- multi-collection: transactionally save two documents in two collections
- random-shapes: save documents with completely different structures/shapes
All tests were run with the arangob
benchmark tool, with various concurrency levels,
complexity settings and repeated several times. arangob
was invoked like this:
1 2 3 4 5 |
|
Both ArangoDB servers and arangob
were located on the same server. Only one
ArangoDB server was active during each test run, and the other was shut down so
it didn’t compete for system resources.
Test results
Following are the results for the different test cases.
In the result tables, the columns have the following meanings:
- Complexity: the number of attributes for the test documents, used as parameter
--complexity
forarangob
- Requests: the number of operations executed, used as parameter
--requests
forarangob
- Concurrency: the number of client threads started by
arangob
, used a parameterconcurrency
forarangob
- Time 2.1: test execution time (in seconds) for ArangoDB 2.1
- Time 2.2: test execution time (in seconds) for ArangoDB 2.2
- T2.1/T2.2: relative performance of ArangoDB 2.1 compared to ArangoDB 2.2. Values less than one indicate that ArangoDB 2.1 was faster than ArangoDB 2.2. Values greater than one indicate that ArangoDB 2.1 was slower than ArangoDB 2.2. A value of one means that both versions had equal speed.
Please note that the absolute execution times aren’t too interesting in the results shown here. We haven’t used the most powerful server on earth for running these tests. We were most interested in how ArangoDB 2.2 compared to ArangoDB 2.1.
Inserting documents
The document
test appends new documents (with an identical structure) to a
collection. Here are the results for inserting a million documents with 100
attributes each:
1 2 3 4 5 |
|
Following are the results for 100,000 documents with 1,000 attributes each:
1 2 3 4 5 |
|
The results for 5,000 documents with 10,000 attributes each:
1 2 3 4 5 |
|
As we can see in the results above, ArangoDB 2.2 is faster than ArangoDB 2.1 for all tested configurations. The difference is negligible if the test client is single-threaded (one insert thread), but ArangoDB 2.2 is considerably faster than ArangoDB 2.1 with more concurrent clients.
CRUD operations (I)
The crud
test case inserts a document, fetches it, updates it, fetches it again
and finally deletes it. Executing 1 million crud operations on documents with 100
attributes each results in the following execution times:
1 2 3 4 5 |
|
Running 100,000 crud operations on documents with 1,000 attributes each:
1 2 3 4 5 |
|
And here are the test results for running 5,000 crud operations on documents with 10,000 attributes each:
1 2 3 4 5 |
|
The results of all these tests show that performance for the tested workload hasn’t changed between ArangoDB 2.1 and 2.2. This is somewhat expected, as the WAL should not affect the performance of read and delete operations much: reading a document does not require writing to the WAL at all, and removing a document only requires writing a very small remove marker to the WAL.
CRUD operations (II)
The crud-append
test case inserts a document, fetches it, updates it, and fetches
it again. Executing 1 million crud operations on documents with 100 attributes each
results in the following execution times:
1 2 3 4 5 |
|
Running 100,000 crud operations on documents with 1,000 attributes each:
1 2 3 4 5 |
|
And here are the test results for running 5,000 crud operations on documents with 10,000 attributes each:
1 2 3 4 5 |
|
Again, ArangoDB 2.1 and 2.2 are pretty much the same speed for the tested operations.
Multi-collection write transactions
The multi-collection
test stores two documents in two different collections
transactionally. Here are the results for executing 100,000 transactions for
documents with 100 attributes each:
1 2 3 4 5 |
|
Executing 10,000 transactions on documents with 1,000 attributes each:
1 2 3 4 5 |
|
And finally, the results for executing 500 transactions on documents with 10,000 attributes each:
1 2 3 4 5 |
|
The above results show that ArangoDB 2.2 is much faster than ArangoDB 2.1 for executing transactions that write to two collections.
We expected that! Multi-collection (write) transactions in ArangoDB 2.2 require
far less calls to msync
than in ArangoDB 2.1. ArangoDB 2.2 can sync operations
of multiple transactions together in one call to msync
. ArangoDB 2.1 needed to
synchronize each transaction separately.
(Fully) heterogenous documents
The random-shapes
test inserts documents that have different structures each.
For each inserted document a new shape will need to be stored. Inserting one million
documents with 100 attributes each results in the following figures:
1 2 3 4 5 |
|
The results show that ArangoDB 2.2 is considerably faster than ArangoDB 2.1 for these cases – even with the storage overhead of writing the shapes to the WAL.
Now we inserted 100,000 documents with 1,000 document attributes each:
1 2 3 4 5 |
|
In these cases, the storage overhead of writing all shapes to the WAL seems to start to matter, and ArangoDB 2.2 gets slower than ArangoDB 2.1 in this test case.
The same was true when we inserted 5,000 documents with 10,000 attributes each:
1 2 3 4 5 |
|
Note that the random-shapes
test case is an extreme test case. We do not
consider it realistic that all documents in a collection have completely different
attribute names. Still we included it in our tests because we were sure that this
would be a case in which the overhead of the WAL would be clearly measurable.
Note that there is a way to make ArangoDB 2.2 faster than ArangoDB 2.1 even for
this test case: setting the option --wal.suppress-shape-information
to true
will make ArangoDB not write shape information to the WAL, making document write
operations much faster in case all documents have heterogenous structures.
The option won’t help much if a shapes repeat a lot. In this case, the WAL overhead shouldn’t matter too much already, or ArangoDB 2.2 should already be faster than 2.1 (as shown in the results above).
Summary
The tests revealed that the overhead of the WAL in ArangoDB 2.2 seems to be negligible for most of the tested workloads. In many cases, ArangoDB 2.2 with the WAL is even faster than ArangoDB 2.1 that did not have a WAL at all.
There is one notable exception: when documents have fully heterogenous structures,
the overhead of the WAL is measurable and significant. Though we consider this
to be a rather hypothetical case, we have added the configurtion option
--wal.suppress-shape-information
. This can be used to turn off storing
shape information in the WAL. This is not safe when the server is to be used
as a replication master, but should work in cases when replication is not used.
The option should not have a big effect if documents are greatly or at least somewhat homogenous. For these cases, ArangoDB 2.2 with its WAL should already be as fast as 2.1 (or even faster).