Embeddableなkey value storeについてのメモ
はじめに
書き込みも読み取りも低遅延なキーバリューストアが欲しいということで調べてみたメモです。ただし、このメモに書いたキーバリューストアがそうであるかは不明です。
sled
- spacejam/sled: the champagne of beta embedded databases
- READMEのperfomanceの項に “LSM tree-like write performance with traditional B+ tree-like read performance” と書かれていて魅力的。
- Remove old io_uring support before rewrite by spacejam · Pull Request #1424 · spacejam/sledでrioへの依存がなくなっていた。
marble
- komora-io/marble: garbage-collecting on-disk object store, supporting higher level KV stores and databases.
- READMEに “Marble is sled’s future storage engine.” とあった。
- https://github.com/komora-io のPeopleはsledの作者のspacejamさん1人。Twitterアカウントを見ると所在地はドイツのベルリンらしい。
redb
- cberner/redb: An embedded key-value database in pure Rust
- RFC: redb (embedded key-value store) nearing version 1.0 : r/rustで知った。
- 作者のコメントによるとしばらく前にmmapを外したとのこと。
- この記事はもうすぐ1.0というタイトルだが、 https://github.com/cberner/redb/releases を見るとここ数日で 1.0.1, 1.0.2, 1.0.3 とpanicするバグの修正リリースが出ている。
LevelDB
- google/leveldb: LevelDB is a fast key-value storage library written at Google that provides an ordered mapping from string keys to string values.
- READMEのLimitationsに “Only a single process (possibly multi-threaded) can access a particular database at a time.” とあった。
agatedb
- tikv/agatedb: A persistent key-value storage in rust.
- READMEによるとTiKVの experimental engine として開発中とのこと。
LMDB
Mozillaで2018年に採用検討したときのドキュメント
- Design Review: Key-Value Storage
- Summaryの冒頭に “There is no one-size-fits-all solution for storage.” とあった。
- “You can get a quite good performance out of the box, without any fuss or configuration like RocksDB.” という意見があった。
- LMDB vs. LevelDB
- Referencesからリンクされていた2013年の記事 LMDB: The Leveldb Killer? - by Paul Banks
- Design Review: Key-Value Storage
redbに付属のベンチマークを試してみた
- 試したバージョン 1.0.3
cargo bench
で実行したベンチマークの結果のうち、benches/lmdb_benchmark.rsの表の部分を抜粋。
+---------------------------+--------+--------+---------+--------+-----------+
| | redb | lmdb | rocksdb | sled | sanakirja |
+============================================================================+
| bulk load | 4080ms | 1417ms | 9710ms | 7828ms | 29011ms |
|---------------------------+--------+--------+---------+--------+-----------|
| individual writes | 58ms | 116ms | 44ms | 45ms | 95ms |
|---------------------------+--------+--------+---------+--------+-----------|
| batch writes | 4577ms | 3481ms | 703ms | 1067ms | 5787ms |
|---------------------------+--------+--------+---------+--------+-----------|
| random reads | 1968ms | 1036ms | 9649ms | 2591ms | 1132ms |
|---------------------------+--------+--------+---------+--------+-----------|
| random reads | 1553ms | 917ms | 9755ms | 2379ms | 1128ms |
|---------------------------+--------+--------+---------+--------+-----------|
| random range reads | 3548ms | 1470ms | 14841ms | 6819ms | 1662ms |
|---------------------------+--------+--------+---------+--------+-----------|
| random range reads | 3518ms | 1474ms | 14822ms | 6858ms | 1702ms |
|---------------------------+--------+--------+---------+--------+-----------|
| random reads (4 threads) | 451ms | 207ms | 2679ms | 587ms | 359ms |
|---------------------------+--------+--------+---------+--------+-----------|
| random reads (8 threads) | 240ms | 108ms | 1522ms | 317ms | 717ms |
|---------------------------+--------+--------+---------+--------+-----------|
| random reads (16 threads) | 161ms | 71ms | 1438ms | 205ms | 2233ms |
|---------------------------+--------+--------+---------+--------+-----------|
| random reads (32 threads) | 170ms | 77ms | 1474ms | 226ms | 5345ms |
|---------------------------+--------+--------+---------+--------+-----------|
| removals | 3042ms | 972ms | 4775ms | 3421ms | 2691ms |
+---------------------------+--------+--------+---------+--------+-----------+
個人の感想
個人的な感想としては、LMDBは individual writes が比較的遅いもののそこまででもないし、readやremovalsは他よりかなり速いので、総合的にはLMDBが良いという印象。
あと、要件として、書き込みは1箇所のみで良いけど、読み取りは1台のサーバー上の複数プロセスから行いたいというのがあるのを思い出しました。するとメモリマップトファイルを使う方式のほうがありがたいわけです。キャッシュなどのデータ構造をメモリ上に持つ方式だとプロセスごとにコピーを持つことになるので。あ、でもプロセスごとに別のキーを参照するケースが多い場合は別々にメモリ上にキャッシュ持つほうが、キャッシュのヒット率が高いという可能性はあるのか。
Are You Sure You Want to Use MMAP in Your Database Management System? (CIDR 2022)が気になるところですが、mmapbench/mmapbench.cpp at main · viktorleis/mmapbench · GitHubを見ると、ファイルサイズ2TiBと巨大な場合の話なので、そこまで大きくなければ大丈夫なのではないかと思いたいところですが、どうなんでしょうね。上のページの動画に出てきた Buffer Pool の動画のリンク 05 - Buffer Pools (CMU Intro to Database Systems / Fall 2021) - YouTube も貼っておきます。
あと、Glauber Costaさんの2020年の記事 Modern storage is plenty fast. It is the APIs that are bad. | by Glauber Costa | ITNEXT も気になったのでメモ。
上の記事からリンクされている Direct I/O writes: the best way to improve your credit score. | by Glauber Costa | ITNEXT も興味深かったです。