PgBouncerを限界突破!スループットを4倍に爆速化させた話
We scaled PgBouncer to 4x throughput
We scaled PgBouncer to 4x throughput
PgBouncerのスループットを4倍に引き上げることに成功しました。具体的なチューニング手法や改善の記録を共有します。
記事には以下のconfigを載せるべきだよ:
[pgbouncer]
listen_addr = 0.0.0.0
listen_port = 6432
so_reuseport = 1
peer_id = 1
unix_socket_dir = /tmp/pgbouncer1
[peers]
1 = host=/tmp/pgbouncer1
2 = host=/tmp/pgbouncer2
3 = host=/tmp/pgbouncer3
4 = host=/tmp/pgbouncer4
興味深いね。うちはKubernetes上でpgbouncerを動かしてるから、1台のマシンで複数のpgbouncerプロセスを立ち上げるのは簡単だったよ。複数マシンへの分散も楽だし、Azure上で運用してるとVMメンテナンスで容赦なくローリングアウトが発生するから、分散しておくと助かるんだよね…
これは実用というより趣味でやったことだけど、rqbit bittorrentクライアントに似たような機能をハックして組み込むのはめちゃくちゃ楽しかったよ。
so_reuseportを使って、トレントごとに'rqbit download'のインスタンスを立ち上げるようにしたかったんだ。ピアが接続してくるとランダムなインスタンスに振り分けられるから、インスタンス同士が互いを見つけてデータをプロキシしたり、あるいは必要なインスタンスへソケットを直接fdパスして渡したりする、ランデブーシステム全体を構築したよ。インスタンス間のやり取りにはpostcard rpcを使ってる。
Clickhouseのso_reuseportによるランデブーのニーズは明らかに全然違うものだけど、こういうso_reuseportの活用事例を見るのは楽しいね(もっと実用的なユースケースとしてだけど)!
いろんなアプリで使える汎用的なピアリングプロトコルがあれば最高だよね。自分のアプリでやったことはかなりやりすぎ感があったし、実際使う予定もないんだけど、面白い試みだったよ。だから、より広範なプロトコルが一体何のためのものになるのか、何に使えるのかはよく分からない。でも、すごくクールなアイデアだと思う!正直、RPCシステムより共有Tursoデータベースを使う方がたぶん実用的だろうけどね。ハハ。
https://github.com/rektide/rqbit/tree/peering (https://github.com/rektide/rqbit/tree/peering)
HAProxyと複数のPGBouncerインスタンスを組み合わせる方法だと、何かデメリットがあるのかな?
https://github.com/yandex/odyssey (https://github.com/yandex/odyssey) を使えばいいよ :) スケーラブルなPgBouncerだから。
自分はpgdog (https://github.com/pgdogdev/pgdog (https://github.com/pgdogdev/pgdog)) を使ってるけど、自分の用途にはすごく合ってて上手くいってるよ!
so_reuseportという言葉を初めて聞いたけど面白いね。セットアップの肝はそれとピアリングみたいだけど、ピアリングってPgBouncerに組み込まれてる機能なの?設定は簡単かな?
もう46歳になるけど、23歳のときにPostgresの重いコネクションモデルに衝撃を受けたことを今でも覚えてるよ。
それから状況は改善されてないってことかな?
キャンセル命令が、そのクエリを全く知らないプロセスに届くと、何も起きない。
ピアリングでこれが解決する。プロセス同士が互いを認識しているから、間違ったプロセスに届いたキャンセル命令を、実際にセッションを保持しているプロセスへ転送できるんだ。
ここで言う「ピアリング」という概念は理解できるけど、PostgreSQLで試したことはないな。ちょっと聞いてもいいかな:
A) PostgreSQLには、ピアリングを簡単に行えるようなモードや設定があるのかな?例えば、ラウンドロビンでpeersにキャンセル命令を送り続ける(エラーが返ってこなくなるまで)仕組みとか、あるいはキャンセルリクエストにメタデータを仕込んで、宛先を間違えたプロセスが正しいプロセスを特定できるような仕組みとか。
B) もしそうなら、どんな仕組みを使ってるの?もし全てのPostgreSQLプロセスがso_reuseport経由でクライアントをリッスンしてるなら、ピアリングのやり取りには何か別のIPCメソッドを使ってるはずだよね。