fsyncを使うようにビルドしたLMDBのdebパッケージを作った

はじめに

Introducing Quicksilver: Configuration Distribution at Internet Scale で LMDB というキーバリューストアを知ったので、いろいろ調査したメモ。

Cloudflare での LMDB の使い方

上の記事によると Cloudflare で DNS 用のデータストアに昔は Kyoto Tycoon を使っていたのですが、2015年にシステムを一新する際に LMDB に変えたそうです。

LMDB は値のサイズが大きくなるとそのサイズの連続領域を探すため遅くなり何分もかかるようになってしまったので、値をページサイズのチャンクに分けて回避したそうです。

キー・バリューの単位で CRC のチェックサムを付与して、チャンクを結合したときにチェックするようにしたとのこと。

値は Snappy で圧縮しているそうです。

3 年本番稼働して遭遇した バグ は 1 度だけで、データ破損は 1 度もないとのこと。

秒間 25 億の読み取りリクエスト、 1 日に 3 千万の書き込みリクエスト (秒に換算すると 34 回) を数千のサーバー上の 9 万以上のデータベースでさばいているそうです。

LMDB について調べたメモ

Lightning Memory-Mapped Database - Wikipedia に詳しい説明がありました。

ソースは openldap / OpenLDAP · GitLab 内の libraries/liblmdb ディレクトリに同梱されています。

LMDB/lmdb: Read-only mirror of official repo on openldap.org. Issues and pull requests here are ignored. Use OpenLDAP ITS for issues. に読み取り専用のミラーがあります。 こちらのデフォルトブランチは mdb.master になっているのですが、コミットログを見てみると mdb.master ブランチは古くて gitlab のほうの master ブランチのほうが新しいのでそちらを見るほうが良さそうです。

libraries/liblmdb/intro.doclibraries/liblmdb/lmdb.h · master · openldap / OpenLDAP · GitLab に詳細な説明がありました。

Wikipedia の記事と合わせて概要をメモ。

カスタム deb パッケージを作成

Lightning Memory-Mapped Database - Wikipedia の Reliability の項を見ると GNU/Linux のビルドでは fdatasync を使っていてデータ破損のリスクがあるらしいです。

Ubuntu – focal の liblmdb0 パッケージに関する詳細 のソースをダウンロードしてビルドしてみると確かに fdatasync を使っていました。

そこで fsync を使うように調整して Ubuntu 18.04 LTS 用にバックポートしてみました。

fsync を使うようにした変更のコミットは Use fsync instead of fdatasync · hnakamur/lmdb-deb@c318850 です。変更前はビルドして nm liblmdb.a | grep fdatasync がヒットしたのが、変更後はヒットしなくなったことを確認済みです。