PostgreSQLの高可用性を追求!Connection Managerでデータベースへの接続を瞬時に切り替える
PostgreSQLインサイド

松村 量

富士通株式会社
ソフトウェアプロダクト事業本部 データマネジメント事業部

 

専門分野

  • データベース

入社以来、データベースに携わってきた。富士通が独自開発したSymfoware Serverのトランザクション管理や復旧機能の開発を経て、現在はPostgreSQLをベースとした「FUJITSU Software Enterprise Postgres」の様々な機能を開発している。

データベースシステムの可用性向上のためにはシステムを冗長化し、サーバーに障害が発生した場合においては業務に支障がないよう迅速にスタンバイサーバーに切り替えることは非常に重要です。そのためには、サーバー側だけでなくアプリケーション側の考慮も必要であり、どんなに早くスタンバイサーバーに切り替わってもアプリケーションからの接続先の切り替えに時間がかかっては意味がありません。PostgreSQLのクライアントドライバーにも可用性を考慮した、アプリケーションとサーバー間との接続を維持するための機能が実装されていますが、FUJITSU Software Enterprise Postgres 12(以降、Enterprise Postgresと略す)では、その接続性をさらに強化した機能「Connection Manager(コネクション マネージャー)」を提供しています。
本特集では、Connection Manager機能の開発担当である「松村 量」が、機能をわかりやすく解説するとともに、機能開発への思いや将来に向けた展望について語ります。

Connection Managerとは何か

はじめに、Connection Managerとはどういうものなのか、簡単な紹介をお願いします。

松村
データベースシステムにおいて、システム規模が大きくなればなるほど業務継続への要求は高くなります。この要求に対してPostgreSQLでは、レプリケーションというシステム構成をとることで、万が一に備えた対策を講じるのが定石です。さらに、別サーバー上で稼働しているアプリケーションとデータベースサーバーとの接続を維持することも考慮しなくてはいけません。このアプリケーションとデータベースサーバーとの接続を制御するのがConnection Managerです。アプリケーションがどのサーバーにつながっているのか、また障害が発生した場合にどのサーバーに切り替えるのかといった接続に関する制御を高速に行います。

Connection Managerとは、「アプリケーションとデータベースとの間の接続を監視 / 制御する機能」なのですね。

松村
はい、Connection Managerは、アプリケーションとデータベースサーバーをつなぎ、可用性を向上させることで安定した業務継続を実現する機能です。大きく2つの機能から構成されています。
1つは、アプリケーションの透過的接続を行う機能です。例えば、レプリケーション構成の場合、アプリケーション側からデータベースサーバーに接続するときに、指定された属性をもつサーバーに速やかに接続します。属性とはレプリケーション構成のプライマリーやスタンバイのことです。
もう1つは、アプリケーションとデータベースサーバーの生死監視機能です。アプリケーションが動作するサーバーとデータベースサーバー間を相互に監視することで、各サーバーで異常が発生したりネットワークの健全性が損なわれたときに、アプリケーション側とデータベースサーバー側に異常を通知します。

アプリケーションから速やかに接続するための仕組み

では早速、それらの機能についてお聞きしていきたいと思います。まず、アプリケーションの透過的接続機能ですが、既に多くのクライアントドライバーで、接続時にサーバー属性を指定するといった同様の機能が実装されているように思います。これとは、どこが違うのでしょうか?

松村
例えば、PostgreSQLのクライアントドライバー「libpq」で使用するtarget_session_attrsパラメーターが類似機能に相当します。クライアントドライバーで実装されているこのような機能を使った接続で、レプリケーション構成へ接続しようとすると、データベースサーバーやネットワークの状況、タイムアウトの設定時間によっては、速いときと遅いときとで何倍もの差が出てしまいます。データベースシステムにおいて、接続時に要する時間の不安定さは致命的です。そこで、Connection Managerでは、「一定時間内に速やかに接続ができること」、また接続に失敗した場合も「一定時間内にエラーが通知されること」を目指しました。

接続を安定させるということですね。それぞれの仕組みの違いを教えてください。

松村
まず、クライアントドライバーによる実装では、ユーザーが指定した接続情報(IPアドレスとポート番号)をもとに、そこに記載された記述順に接続を試行します。順番に接続してサーバーの属性を確認する必要があるということです。仮に、サーバーAとサーバーBの2台で構成されたレプリケーションシステムがあり、「サーバーAがプライマリー」、「サーバーBがスタンバイ」の属性を持つと仮定します。ユーザーが指定した接続順は、「サーバーA、サーバーB」の順とします。ここで、クライアントドライバーがプライマリーの属性を持つサーバーに接続しようとした場合、通常の状態では、サーバーAに接続されるため何も問題はありません。しかし、何らかのトラブルでプライマリーがサーバーBに切り替わってしまった場合でも、サーバーAから順に接続を試みるため、接続に時間がかかってしまいます。

不要な接続処理が発生するわけですね。

松村
そのとおりです。この問題を解決するのが、Connection Managerなのです。Connection Managerは、アプリケーションサーバーに専用プロセス(conmgr)を常駐させています。このプロセスは、接続先のすべてのデータベースサーバーの属性や状態を常に監視するプロセスです。ユーザーは、アプリケーションからデータベースサーバーへの接続時に、このconmgrプロセスに接続するための情報(ポート番号など)を指定します。アプリケーションは、指定されたconmgrプロセスに接続することで、データベースサーバーのIPアドレスとポート番号を知ることができます。その後は、そのIPアドレスとポート番号を使って、アプリケーションが直接データベースサーバーに接続するというわけです。この仕組みにより、接続に要する時間も最小限にとどめることができます。

conmgrプロセスは、データベースの属性変更があった場合、例えば、現在、どのサーバーがプライマリーなのかということをどのように認識するのでしょうか?

松村
先ほど、アプリケーション側にconmgrプロセスが存在すると説明しましたが、データベースサーバー側にもwatchdogプロセスという専用プロセスを常駐させています。このwatchdogプロセスはサーバーの属性を常にチェックしており、その属性をconmgrプロセスに通知します。この仕組みにより、conmgrプロセスはサーバーの属性が変更されたことをタイムリーに知ることができます。

プライマリー検出の仕組み

他にも似たような機能を提供するPostgreSQLのOSSツールなどがあると思いますが、これらとはどこが異なるのでしょうか。

松村
Pgpool-IIやpgbouncerですね。これらは、アプリケーションとデータベースサーバーの間で稼働するプロキシソフトウェアです。アプリケーションとデータベースサーバーとの通信をこれらのソフトウェアが中継しています。これによって、コネクションプーリングが可能になったり、ロードバランス(SQLの内容を解析することでアクセスするデータベースサーバーを振り分ける)などの様々な機能を生み出すことができます。その一方で通信の中継によってレイテンシーが悪化することを免れません。
これに対して、Connection Managerでは、コネクションプーリングやロードバランスなどの高度な機能を提供しない代わりに、アプリケーションとデータベースサーバーを直接、接続します。SQLのレスポンスの素早さを重視する場合には、Connection Managerを使っていただき、コネクションプーリングなどの機能を利用したい場合にはPgpool-IIやpgbouncerを使っていただく、というように棲み分ける関係であると理解していただけると良いと思います。

Enterprise Postgresのクライアントドライバーは、ユーザーによって指定されたサーバーに接続するだけではないのですね。これは、PostgreSQLのクライアントドライバーの動作とは違うように思います。

松村
はい。この動作のために、オリジナルのクライアントドライバーを改造しています。Pgpool-IIなどのオープンソースソフトウェアでは、このようにクライアントドライバーの改造を必要とするようなアーキテクチャーを採用することはできません。しかし、Enterprise Postgresは、PostgreSQLのすべてのクライアントドライバーも同梱するので、このような高速レスポンスを実現できるアーキテクチャーを採用できるのです。

サーバー間のハートビートで異常を検知

では、もう1つの機能である生死監視機能について教えてください。

松村
この機能は、アプリケーションが動作するサーバーとデータベースサーバーの相互監視を行うことで、長時間、無応答になってしまうようなネットワーク不通やサーバーダウンを素早く検知して、データベースサーバー側でのリソース回収とアプリケーションに対するエラー返却を行うものです。

この機能には、具体的にどのようなメリットがあるのですか?

松村
アプリケーションとデータベースサーバーとは、TCPで通信していますが、プロトコル上は、通信やサーバーの異常を検知する仕組みが存在しません。そのため、相手側が通信の閉鎖手続きを取らない限りは、相手が通信を続ける可能性があると判断しなければなりません。
例えば、相手側がオペレーションシステムごとダウンしていたり、あるいは、ネットワークが不通となっている場合でも、閉鎖手続きが取られていないので、その相手との通信のための環境を維持しておかなければならないということです。これを、アプリケーションとデータベースサーバーとの通信に当てはめると、アプリケーション側ではデータベースサーバー側からSQLの応答が返る可能性を信じて待ち続けることに相当します。データベースサーバー側では、アプリケーションからのクエリを待つために必要なメモリを確保し続けたり、トランザクションをオープンしたままにすることに相当します。
これに対して、Connection Managerは、通信やサーバーに何らかの異常が生じた場合、所定の時間内にそのことを検知し、クライアントドライバーを通してアプリケーションに異常を通知します、また、データベースサーバー側ではSQL接続を強制回収するため通信の環境を維持し続けておく必要がなく、アプリケーション側からは直ちに接続のリトライが可能となるわけです。

異常が発生した場合に接続を維持し続けることがなくなるわけですね。しかし、TCP通信での異常検知には、keepalive機能が有効であるように思います。

松村
keepalive機能を使用する場合、本来ならば、keepalive機能を有効にするだけでなく、オペレーティングシステム全体に影響が及ぶTCPパケットの再送回数や時間の上限値の設定も必要なのですが、適切な値を設定することが難しく、設定自体が見過ごされることが多いです。keepalive機能を有効にするだけでは、例えば、アプリケーションによるSQL文の送信中にネットワーク切断などを検知できないのです。これらを設定せずに異常を検知するには、アプリケーション層で異常検知のプログラムが不可欠になりますが、Connection Managerがこれを担うということです。

keepalive機能で異常が検知できない問題をConnection Managerではどのように解決したのですか?

松村
異常を検知するための一般的な方法としてハートビートと呼ばれる手法があります。心臓の鼓動(ハートビート)のように、サーバー間で相互に、一定間隔でデータを送信しあい、このデータを一定期間内に受信できなければ相手のサーバーがダウンしたか、ネットワークが不通になったとみなす手法です。しかし、この手法をクライアントドライバーに適用することは困難が伴います。なぜならば、ユーザーのアプリケーションロジックとは非同期にハートビートで通信しあう必要があるからです。そこで、Connection Managerでは、さきほど登場したconmgrプロセスとwatchdogプロセスとの間でハートビート送受信を行うようにしました。これにより、アプリケーションロジックと独立させることができるわけです。そして、Enterprise Postgresのクライアントドライバーとconmgrプロセスは常に接続を保持しているので、conmgrプロセスがハートビートでタイムアウトを検知するとすぐにクライアントドライバーに異常が通知されます。

ハートビートの仕組み

watchdogプロセスとconmgrプロセス間のハートビートと、アプリケーションとconmgrプロセス間で保持された接続がConnection Managerの特長的な仕組みであると感じました。

松村
はい、先ほど、アプリケーションとデータベースサーバーが直接、接続することで高レスポンスを実現していることをお話ししました。このとき、アプリケーションとデータベースサーバーとの接続にconmgrプロセスが経由されていないので、conmgrプロセスで異常が検知された場合、それをアプリケーションにどのように伝えるのかがポイントです。この異常の通知にアプリケーションとconmgrプロセス間の接続が使用されているわけです。

データベースの監視と接続先の決定をConnection Managerに任せることで、アプリケーション開発者の負担が大きく軽減できますね。最後に、今後の取り組みなどを教えてください。

松村
Enterprise Postgres 12では、Connection Managerに対応したクライアントドライバーは、libpqライブラリーと、これを使用するC言語の埋め込みSQL(ECPG)、COBOL言語の埋め込みSQL(ECOBPG)、psqlコマンドに限られています。今後は、JDBCドライバー、ODBCドライバー、Npgsqlなどでも利用できるようにする計画です。また、現在は、適応するプラットフォームもLinuxのみのため、Windowsなど他のプラットフォーム展開にも取り組みます。

クライアントドライバーやプラットフォームに限定されず、今後は、さまざまなアプリケーションにおいても可用性向上につながりますね。高信頼を追求するEnterprise Postgresにおいて、その一翼を担う機能ということで、これからも注目です。ありがとうございました。

2020年8月28日公開

本コンテンツに関するお問い合わせ

お電話でのお問い合わせ

Webでのお問い合わせ

当社はセキュリティ保護の観点からSSL技術を使用しております。

ページの先頭へ