Embeddableなkey value storeについてのメモ

はじめに

書き込みも読み取りも低遅延なキーバリューストアが欲しいということで調べてみたメモです。ただし、このメモに書いたキーバリューストアがそうであるかは不明です。

sled

marble

redb

LevelDB

agatedb

LMDB

redbに付属のベンチマークを試してみた

+---------------------------+--------+--------+---------+--------+-----------+
|                           | 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 も興味深かったです。