みんな大好きPostgreSQL。
複数DBマルチテナントシステムを構築するなら忘れてはいけないコネクションプーリング。
大量コネクションを扱うなら都度forkやpre-fork式ではちょっと辛い、イベントベースが好ましい。
もうお分かりですね。pgbouncer1.6の話題です。
PostgreSQL界隈では有名なコネクションプーリングの実装が2つあります。 pgpool-II と pgbouncer。
ざっくり言うと高機能の pgpool-II に対して、軽量・大規模向けの pgbouncer という棲み分けがあると言えるでしょう。
pgpool-II は最近は日本の トレジャーデータ社の Prestogres ( https://github.com/treasure-data/prestogres ) という痺れるようなプロジェクトのベースとして採用されていることで名前を聞いたことのある方もいるのではないでしょうか。
pgbouncer は少し古いですが LastFM( http://www.lastfm.jp/user/Russ/journal/2008/02/21/zd_postgres_connection_pools:_pgpool_vs._pgbouncer )の事例が有名でしょう。Instagram も使ってますネ。
pgbouncerは現行のバージョンは1.5系で、最新は1.5.5です。1.6系は8月1日にリリースされ、複数DBマルチテナントシステムに向けた大規模な機能強化が行われています。
この1.6系では複数DBマルチテナントシステム開発者にとって嬉しい機能がたくさん搭載される予定です。本番運用に投入する前に一足お先にリリースノートを読んで夢を感じましょう。
本バージョン、2013年ぐらいからリリースノートは準備されているのにさっぱりリリースされなくて関係者をやきもきさせていました。(想像)
本記事では以下のリリースノートをもとにザックリ読み解いたものです。
http://pgbouncer.github.io/2015/08/pgbouncer-1-6/
・接続ユーザーやパスワードハッシュをDBからロードできるようになった
・プーリングモードの設定をデータベース毎、ユーザー毎に設定できるようになった
・データベース毎、ユーザー毎にコネクションの最大接続数を制御できるようになった
・新しいコネクション確立を避けるための DISABLE/ENABLE コマンドが追加された
・新しい推奨のDNSバックエンド c-ares が追加された
・設定ファイルに include ディレクティブを追加した
新しく以下のパラメータが追加された
1.5までのpgbouncerは userlist.txt というテキストに静的に接続ユーザを書かなければいけませんでした。
これは動的に接続先ユーザーが増えるようなマルチテナントシステムを構築するのに不向きという事です。
タイトルがすべてを物語ってます。柔軟にできますねぇ('∀`)
ただ、私にはちょっと有用な利用シーンが思いつかなかったです。
たとえば分析用ユーザーではトランザクションなんて使わないので statement モードにしてコネクションの消費を抑えたりできるという事でしょうか。
max_db_connections と max_user_connections という設定が追加されます。
テナント毎にユーザーを分けているような複数DBマルチテナントシステムにとって必須といえる機能です。
特定のユーザーのリクエストにコネクションをすべて占有されてしまい、他のユーザーにサービスできないという事態を避けることができるようになるでしょう。
特定のデータベースの新しいコネクション確立を抑止・再開することができます。
c-ares は名前解決の非同期化を行うためのライブラリです。c-aresは名前解決をブロックしないし、いろいろな方式の名前解決に対応している唯一のプロダクトとのこと。
名前解決をブロッキングしてしまうようではpgbouncerのような大規模向けシステムでは役に立たないのだというpgbouncerの強い意志を感じる。
というか、ドキュメントを見る限り pgbouncer は名前解決にかなりこだわりを持っているらしい。それだけそこが重要ということでしょう
(個人的には困ったことがないのでそこまでだわる理由はよくわからない。)。
UNIXドメインソケットで接続しているクライアントと、TCPまたはUNIXドメインソケットで接続しているサーバーでremote_pidを取得できるようになりました。
tcp serverの場合、pid はキャンセルキーから取得できる。(?ドキュメントから意味が読み取れず)
キャンセルキーとは何でしょうね。ちょっとリリースノートからは判断できませんでした。
pg_cancel_backend とかに使えるPIDだよという事なのでしょうか。
DBの数なんてもはや何台あるかわからない。ホスト名の解決はもはやDNSで行っておるよという皆様にとって必須の機能。
…なのでしょうが、ちょっとこの機能が必要となるようなシステムとはどんなものなのか、私も未経験なのでよくわからないです。
この設定は application_name_add_host=on にすることで有効となる。
今や接続元アプリケーション名がWebだとかBatchだとか区別できるだけで問題が解決するような時代ではない。
どのホスト(ポート)レベルで区別しないと。という事なんだろう。
「おお、Webサーバーから死ぬほど重いクエリが飛んでる、今すぐ調べないと!で、どのWebサーバーよ?100台あるんだぜ」みたいなときに助かりますね。
設定ファイルが大規模化してくると、切り出して整理したいという要望はどうしてもでてくるもの。
データベース毎、ユーザー毎に設定できる項目が増えてきたので必要になったという事でしょう。
以降はバグフィックスとかクリーンアップだとかで自分はあまり興味がないので各自読むように。
本番運用に突撃するPostgreSQL界の猛者の報告待ってます。
MySQL percona や MariaDB じゃダメ・・・・なのかい?