Ikeda->Weblog();

Ikedaの徒然雑記。

[メモ] PostgreSQL+pgpool-II+heartbeat でクラスタリング/前編

| 0件のコメント

[メモ] ++ でクラスタリング/前編仕事でPostgreSQLデータベースサーバの冗長化について調査と実験を行っていたんですが、昨日やっと設定が仕上がりました。忘れないようにメモっときますね(メモの割に長い。。)。

某ケーブルテレビ局のWebサーバ群なんですが、導入時から

ファイアウォール(FW)→ロードバランサ(LB)→サーバ群

という経路は冗長化構成にしていました。しかし、データベース(DB)サーバのみ1台で、ここがシングルポイント(冗長化されていない個所)だったんですね。ケーブルテレビ局のWebサイトということで、DBには重要なデータも蓄積されます(問合せやプレゼントの応募などの個人情報とかですね)。

今回、このデータの損失を最大限防ぎ、なおかつシステム全体のダウンを最小限に抑えよ、とのお達しがお代官様上司より下りました。

要件としてはこんな感じ。

  1. データの損失を防ぐ → レプリケーション
  2. DBサーバダウンによるWebシステム全体のダウンを防ぐ → フェイルオーバ
  3. できればレスポンスアップ。 → ロードバランス等
  4. サーバマシンは既存サーバと新規サーバの2台。
DBエンジンはPostgreSQL。そのままではレプリケーションすることはできません。MySQLにしとけばよかったと後悔しつつも、DBMSの変更なしでレプリケートする方法を調べた結果、いくつかのソフトウェアを発見しました。


  • PGCluster
    マルチマスタの同期レプリケーションシステム。レプリケーション/ロードバランス/フェイルオーバが可能。推奨構成として、ロードバランサ・クラスタサーバ・レプリケーションサーバの3台以上構成が推奨されている。NOW()関数もレプリケーション可能。ラージオブジェクトはファイルシステム共有が必要。
  • Slony-I
    シングルマスタの非同期レプリケーションシステム。リアルタイムのレプリケートはできないが、シンプルで軽く、スレーブDBの追加も容易。
  • pgpool
    PostgreSQLのネ申・石井達夫氏によって開発された多機能ミドルウェア。もともとはコネクションプーリングサーバとして開発されたので「pool」と名付けられた(んだと思う)が、フェイルオーバやレプリケーション、ロードバランス機能も搭載されている。オンラインリカバリ機能はなし。レプリケーションできるノード数は最大で2つまで。乱数やOID、シーケンスやNOW()などのクエリについて、同じ値でレプリケートされる保証はない。
  • pgpool-II
    pgpoolを大幅に進化させたミドルウェア。pgpool-Iにあった制限のいくつかが無くなり、さらにオンラインリカバリやパラレルクエリ、クエリキャッシュなど多くの機能が追加された。
他にもいくつものレプリケートできるソフトは存在しますが、日本語情報が豊富であることなどからPGClusterとpgpool-II(pgpool)のどちらか、としました。

機能的には遜色ないものの、NOW()までレプリケートできるPGClusterはかなり理想的です。

が、しかし。

ロードバランサとレプリケーションサーバにはかなりの負荷がかかるため、クラスタサーバとは別マシンで稼動させることが推奨されています。クラスタは当然2台以上。。。。となるとマシンが足りない

また、ロードバランサとレプリケーションサーバも1台ずつだとそこがシングルポイントになります。となると、、、、とてもマシン台数が(汗)

もっと大規模なシステムの時にぜひ試してみたいソフトウェア、ということで今回はお見送りとなりました。

残るはpgpool/pgpool-IIですが、やはりここは高機能なpgpool-IIを試してみましょう。
まず思いつく構成がこれ。

idea_01.png

んー、シンプル。
だがしかし。pgpool-IIがマスタDBにしか居ません。これではマスタDBサーバ自体やpgpool-IIに異常が発生した場合はダウンしてしまいます。つまり、pgpool-IIがシングルポイントになっています。これじゃ入れた意味がないですね。

そこでもう一つ、pgpool-IIをスレーブ側でも稼動させます。

そのままだとDBサーバのアドレスが2つになりますから、アプリケーション側で対応しなければなりません。それではあまりに手間がかかりすぎます。

そこでひねり出した構成がこれ。

idea_02.png

DBサーバアドレスとして専用に仮想IPアドレス(VIP)を用意し、これをマスタDB・スレーブDBのインタフェース(IF)に割り当てることにします。当然、同一セグメントに同一IPは存在できませんから、普段はスレーブDBの仮想IP用IFはDOWNさせておきます。

通常時、アプリケーションはマスタDBのIFに割り当てられた仮想IPに接続します。ここではマスタpgpool-IIが稼動しており、クラスタノードとして自マシン内とスレーブDBにあるPostgreSQLにクエリを投げます。
この時、仮想IPと同じIFでpgpoolを通信させると、ネットワーク異常が起こった際にレプリケートも停止してしまいます。幸い、両DBサーバには1つ余ったNICがありますので、ここをクロスケーブルで直結しレプリケート用通信路として確保しました。PostgreSQLとpgpool-IIでそれぞれListenするIFが異なりますから、ポート番号はデフォルトのままでOKということになります。

さて、問題の障害発生時。障害にもいくつかのパターンが考えられます。
  • PostgreSQLのダウン
これはpgpool-IIが障害を検知し、ダウンしたノードDBを切り離して縮退運転に入ります。データのレプリケートは当然停止しますが、サービスは停止しません。
  • ネットワーク自体のダウン
これはもう致命的。WebサーバからはどうやってもDBにアクセスできませんから、サービス全体に影響します。が、これはDBの問題というよりネットワーク構成の問題なのでこの際考えない事にして、裏SWが壊れないのを祈るのみです(をい)
  • サーバマシンのダウン
  • pgpool-IIのダウン
  • NICのダウン
さて、これら3つの障害時が問題です。どの場合でもアプリケーションからDBへの接続ができません。
監視ツールでこれらを検知し、手動で仮想IPを切り替えるというのもアリですが、夜中や休日に発生した場合はダウンタイムが大きくなってしまいます。

そこでさらにもう一つ、システムを追加します。
  • heartbeat
    マスタ/スレーブサーバがお互いの状態を監視・通知しあうことにより異常を検知し、場合によってはマスタサーバのサービスをスレーブサーバが引き継ぐ、High Availability(高可用性〕システムを実現させてくれるソフトウェア。
    1秒未満の単位で障害を検出でき、CPU使用率も1%未満。
    v1ではアクティブ/スタンバイ構成、v2ではアクティブ/スタンバイに加え、アクティブ/アクティブなど色々な構成がサポートされている。
このheartbeatを使い、マスタとスレーブがお互いの状態を監視、マスタに何かあった時にはすぐにスレーブがサービス(仮想IPやpgpool-II)を起動・引き継ぐ、という仕組みを作ります。

結果、以下のような構成となりました。

idea_03.png

次の記事でもう少し具体的な作業内容をメモります(若干力尽きた)

コメントを残す