豪鬼メモ

一瞬千撃

DBサービスを作ろう その10 更新ログによるインクリメンタルバックアップ

Tkrzw-RPCのレプリケーション機能を実現するために、Tkrzw本体に更新ログ機能をつけた。更新ログ機能は任意のコールバックを呼び出す実装になっていて、それにメッセージキューを接続すると、マルチリーダで任意の後処理ができるようになる。今回は、メッセ…

DBサービスを作ろう その9 更新ログのメッセージキュー化

前回の記事で、レプリケーション機能の実装を見越して、データベースの更新ログ機能を設計した。実装を進めながら思ったのは、データベースに更新があった旨をログとして記録して、またそれを外部に通知するという動作は、メッセージキューと同じ要件を持つ…

DBサービスを作ろう その8 レプリケーションを踏まえた更新ログの要件

データベースの堅牢性を高めるために、データベース本体とは別に更新内容を保存する、更新ログという手法がある。さらに、更新ログを逐次別サーバに転送して適用すれば、レプリケーションが成立する。この記事では、レプリケーションにも使える更新ログの要…

DBサービスを作ろう その7 シャーディング最強説

シャーディングによってデータベースを分割することで、通常運用の並列処理性能を向上させることができる。それだけでなく、バックアップ作成などの、他のスレッドをブロックさせうる操作の影響を最小限に留めることができる。その運用方法について説明する。

キャストに関わるGCCの謎挙動

GCCの不可解な挙動に悩まされている。以下のコードは、負数を出力しないことが期待されるが、-O2以上の最適化をすると負数が出力されてしまう。 #include <cstdint> #include <cstdio> int main(int argc, char** argv) { constexpr uint32_t modulo = 2039; for (int32_t i =</cstdio></cstdint>…

DBサービスを作ろう その6 非同期化による性能向上

前回の記事にて、バッチ化とストリーム化によってgRPCの性能が向上することを示した。残る高速化の手段は、非同期APIを利用することである。結論としては、サーバ側では非同期APIを利用すると性能がかなり向上する。これを実装したTkrzw-RPC 0.7.1をリリース…

DBサービスを作ろう その5 バッチ化とストリーム化による性能向上

前回の記事で述べた性能評価によって、gRPCによる操作が同一マシン上なら2万QPSのスループットで実行できることが分かった。これはデータベース自体の性能に比べると遅すぎるので、より高いスループットが出せるようにgRPCの使い方を工夫したくなる。今回は…

DBサービスを作ろう その4 gRPCの性能測定

Tkrzw-RPCの基本機能を実装したので、バージョン0.5.0をリリースした。簡易的な性能測定をして、gRPCのオーバーヘッドについて考えてみる。

DBサービスを作ろう その3 ストリームAPIでイテレータを実装

前回の記事で、GetやSetなどの、通常のデータベースの個々のレコードを操作するAPIを実装した。CountやRebuildなどの、データベース全体に対する操作も同様に実装できる。しかし、データベース内を横断して個々のレコードを取り出すイテレータは、進捗状態を…

DBサービスを作ろう その2 基本APIの設計と実装

前々回の記事で、gRPCインストールとアプリケーションのビルド方法を確認し、RPCの基本機能を使ってみた。前回の記事で、ログと起動終了という基本的な管理機能を備えたサーバプログラムが出来ている。今回はいよいよAPIの設計と実装に入る。

DBサービスを作ろう その1 ログとデーモン化

前回に引き続き、DBサービスの設計について検討していく。サービスと言えば、ログを記録せねばならない。また、起動プロセスと分離してデーモン化する必要がある。gRPCベースのサービスでそれらを行うにはどうすべきか考える。

DBサービスを作ろう その0 準備

Tkrzw本体でやりたい事をやり切ったので、データベースサービスでも作ってみよう。既にガチなデータベースサービスは山ほどあるので、レッドオーシャンに敢えて飛び込むのも気が引ける。とはいえ、gRPCを使うとかなり気軽に高性能なサービスを実装できるので…

mallocの削減などによる性能向上

メモリの使い方を工夫しただけで、ハッシュデータベースのスループットが28%向上し、B+木データベースのメモリ使用量が14%または35%減ったという話。

各種メモリアロケータによる性能評価

C言語のmallocやC++言語のnewオペレータが呼ぶメモリアロケータをシステム標準の実装から変更した場合の、各種DBMクラスの動作速度とメモリ使用量を調べてみた。glibc標準のmalloc、jemalloc、tcmalloc、mimallocを比較した。

Tkrzw 1.0の性能評価

データベースライブラリTkrzwのバージョンを1.0にした機会に、改めてベンチマークテストをしてみた。最も典型的なデータベースクラスであるファイルハッシュデータベースにて、1億レコードのSetで200万QPS以上、同じく1億レコードのGetで500万QPS以上のスル…

共有ロックによる並列B+木操作の保護

順序付きデータベースの重要なデータ構造であるB+木だが、それを並列に更新する方法についておさらいして、それを保護するミューテクスの種類について考察してみよう。最近実装したアップグレード付き共有ロックを活用して性能向上できるかについても検討す…

スピン共有ロックの優先度制御とアップグレード機能

標準のstd::shared_mutexを自前のスピンロックに変えるとスループットが改善するという話を以前の記事に書いた。今回はそれを改良して、優先度のポリシーを変えたり、共有ロックを保持したまま排他ロックに格上げするアップグレード機能を実装したりする。

ネイティブ非同期APIとゴルーチンの性能比較

Tkrzwの非同期APIをGoインターフェイスでもサポートした。しかし、性能測定してみた結果、Go自体が備えているゴルーチンが強力すぎるので、ネイティブ側の非同期APIは要らなかったかもという結論に至った話。

スピンロックによる並列処理の高速化

C++標準のstd::shared_mutexを自前のスピンロックによる実装に置き換えたところ、スループットが激烈に向上した。その経緯と実装と性能評価について説明する。

Javaインターフェイスで2倍の高速化

TkrzwのJavaインターフェイスがGoインターフェイスの半分の性能しか出ないというのは、さすがに遅すぎるだろうという話があった。JNIのオーバーヘッドが高いからというのを遅い理由として挙げていたが、うまく書けばそれを下げられることが分かったので、や…

Python/Rubyの非同期APIとコルーチン

PythonとRubyではマルチスレッドを使うと性能がむしろ悪化する。そんな話を以前の記事で書いた。グラフに現れているように、1スレッドだとGoと同じくらいの性能なのに、マルチスレッドにするとスループットが激減してしまうのだ。ところで、ゲームやその他の…

C言語での非同期API

C++に引き続いて、C言語でも非同期APIを整備した。非同期APIはC++のpromise/future機構を使えば簡単にできるのだが、それをCから使うにはそれなりの工夫が必要だった。

TkrzwのGo言語インターフェイスをリリース

並列処理性能を重視したデータベースライブラリTkrzwだが、ついにGo言語をサポートした。並列処理が簡単に書けるGo言語と並列に読み書きできるDBMの親和性は高い。ここでは、各言語の性能比較をした上で、Goでの簡単な使い方について説明する。

Go言語勉強中

TkrzwのGo言語インターフェイスを鋭意製作中であるが、今更ながら、「プログラミング言語Go」を読んだ。20年前に愛読した「プログラミング言語C」や「プログラミング作法」や「UNIXプログラミング環境」のカーニハン先生が著者の一人なので、なんか懐かしい…

非同期APIの性能評価

非同期APIでは、該当の処理をバックグラウンドで実行するためにスレッドを使う。と同時に、バッチ処理やサーバプログラムなどではフォアグラウンドに相当するスレッドが複数個同時に実行される。となると、性能評価はフォアグラウンドのスレッド数とバックグ…

非同期APIでデータベースを操作する

データベースライブラリの既存の同期的なAPIをラップして、非同期のAPIを作ったという話。C++のstd::futureクラスと独自のスレッドプールを使っている。std::futureのおかげで、スレッドプログラミングの知識が全く無いプログラマでも簡単に非同期処理機能を…

C++標準async+futureとスレッドプールの性能比較

C++11標準以降のasyncとfutureによる非同期処理は非常に使いやすく、とても簡単に非同期処理を実装することができる。それによって、マルチスレッドでは複数の処理を並列実行できた場合には、スループットが向上させられる。一方で、単一の処理をシングルス…

C++/Java/Ruby/Pythonの並列I/O用ファイルインターフェイス

ファイルの読み書きをマルチスレッドで並列に行うための仕組みを、各種プログラミング言語(C++、C、Java、Ruby、Python)で利用できるようにライブラリを整備した。メモリマップI/O、通常I/O、ダイレクトI/Oを同じインターフェイスで利用できる。Tkrzw-0.9.…

TkrzwのC言語インターフェイス

C++言語で書かれているデータベースライブラリTkrzwは、当然ながらC++のAPIを提供するが、C言語からは使えない。なので、主要機能をクラスでない関数でラップしたC言語のAPIも提供することにした。C言語のプロジェクトで使えることはもちろん、その他の言語…

再構築しない復旧処理

データベースファイルを開いたプロセスが突然死した場合、次回にそのファイルを開いた際には自動的に復旧処理が走るようになっている。従来のバージョンでは、復旧に際して、データベース内の全レコードをスキャンして、データベースを再構築するのが専らで…