Pgpool-II 4.1 新機能: reserved_connections【第3回】

この記事はPgpool-II 4.1の紹介【第1回】の中のreserved connections 機能について詳しく紹介します。

Pgpool-IIにおけるクライアントからの接続管理

reserved_connections機能を説明する前に、今までのクライアントからの接続管理について復習しておきましょう。reserved_connectionsは、今までの管理方法とは違う管理方法を導入するので、比較のためにもおさらいしておくのがわかりやすいと思います。Pgpool-IIでは、複数のサーバプロセスがクライアントからの接続を待ち受けており、クライアントからの接続要求があると、そのうちの一つのプロセスが接続要求を受け付けます。待受プロセスの数はnum_init_childrenという設定パラメータで決まります。

では、すでにnum_init_children分のプロセスがすべてクライアントからの接続を受付中で、待受プロセスが無い場合はどうなるのでしょう?
そのときはOSが新しいクライアントからの接続要求を一旦保留してキューに入れます。どれかのPgpool-IIプロセスへのクライアントからの接続が終了すると、そのプロセスは再びクライアントからの接続要求を待ち受ける状態になるので、OSはそのプロセスに接続要求を割り当てます。
つまり、クライアントから見ると、空きプロセスが出るまで接続要求は待たされることになります。

PostgreSQLが順調に処理を行っていればこの方式は問題なく動きます。しかし、PostgreSQLの処理能力が追いつかない状態になったり、あるクライアントがPgpool-IIに接続したまま長い時間何もせずに接続を専有したりすると、OSのキューが満杯になり、いつまでたっても新しいクライアントがPgpool-IIに接続できなくなります。それどころか、システムに重い負荷がかかり、システム全体の状態が不安定になることもあります。

reserved_connectionsによる接続管理の改善

この問題を解決するのがPgpool-II 4.1で導入された新しい設定パラメータreserved_connectionsです。このパラメータが1以上に設定されていると、(num_init_childrenreserved_connections)以上のクライアントからの接続はブロックされるのではなく受け付けられず、”Sorry, too many clients already”というエラーになります。 たとえば、reserved_connections = 1で、num_init_children = 32なら、32番目のクライアントからの接続は拒否されます。これにより、PostgreSQLが忙しい場合でもOSにこれ以上負担がかからずに済みます。そのかわり、クライアントは接続に失敗したらしばらくたってから再度接続を試みるなどの対応が必要になります。
この挙動はPostgreSQLと同じで、PostgreSQLのmax_connectionsを越えた接続をしようとして”Sorry, too many clients already”のエラーが出てしまった経験をお持ちの方も多いと思います。ですから、reserved_connectionsを導入することによるこうした挙動の変化は、PostgreSQLユーザであればあまり違和感のないところでしょう。
逆に、システムの処理能力に十分余裕があり、クライアントが待ち状態になることがほとんどないようなシステムでは、今までどおりの挙動を維持するために、reserved_connectionsを0に設定するのがおすすめです。(ちなみにreserved_connections = 0がデフォルト設定です)
なお、reserved_connectionsを有効にしたい場合、できればその設定値を1ではなく、もう少し余裕を持たせると良いでしょう。具体的には、num_init_childrenの10%位をreserved_connectionsに割り当てます。Pgpool-IIのプロセスはクライアントの接続が解放されてから待ち受け状態に戻るまでに少し時間がかかることがあり、その分の余裕を見たいからです。

まとめ

今回、Pgpool-II 4.1の新しいパラメータreserved_connectionsについて説明しました。
reserved_connectionsを導入することにより、常に高負荷に悩まされているシステムでは改善が見込めることがあるので、是非お試しください。