GREE Engineering

HyperDBとlsyncdを使用したWordPress冗長構成

HyperDBとlsyncdを使用したWordPress冗長構成

こんにちは。開発統括本部の勝又 健太です。
このエントリは GREE Advent Calendar 2013 4日目の記事です。

自己紹介

はじめての投稿なので簡単に自己紹介させて頂きますと、言語はC++/C#/Perl/Java/Ruby/Python/PHP、開発フレームワークはMFC/.NET Framework/Struts/Ruby on Rails/Django/各種PHPフレームワーク、DBに関してはOracle/SQLServer/MySQL/Postgresqlなどなど色々と経験しておりまして、なんでも屋的な雑食系エンジニアです。昔はマンガ作成用グラフィックソフトとか動画キャプチャソフトとかも作っとりました。

Windows/ASP.NET系の開発を8年ほど経験して、その後Linux系に転向して今に至ります。インフラ周りやミドルウェアなども大好物です。(今後はスマホネイティブ系の開発とかデータ解析系の業務とかもやっていきたいなーと思ってます)

あとちょっと前までbokete職人やってました。(星11000獲得経験あり)

本題

ということで今回はタイトル通り「WordPress冗長構成」に関して書かせて頂きたいと思います。

実はこちらのエンジニアブログもWordPressを使用しているのですが、WordPressとMySQLのバージョンがかなり古くなってきたこと、および冗長構成がとられていなかったということもあり、先日新サーバーへの移行作業を行いました。

移行後のサーバー構成図は下記のようになります。

servers05

LVSとWebサーバーがそれぞれ2台、そしてサーバー台数をなるべく節約したいということで、DBサーバーとWebサーバーは同じサーバーを使用する方式を採用しました。

今回の場合、この構成の下で以下の3つの要件を実現する必要があります。

  1. DBへの更新処理は常にマスタDBに対して行われる必要がある。
  2. WordPressのテーマファイルが修正されたり画像等のコンテンツがアップされた場合、両方のWebサーバーのファイルを同期する必要がある。
  3. どちらか一方のWebサーバーがダウンしても、閲覧処理は正常に行える必要がある。(更新処理は行えなくてよい)

まず1の要件に関してですが、こちらはWordPressの「HyperDBプラグイン」を使用することで簡単に実現できます。

HyperDB は、複数のデータベース環境において標準の wpdb クラスを置き換えるものです。HyperDB はデータのパーティションおよびレプリケーションに対応しています。
HyperDB では複数サーバーの設定・複数ルートの設定が可能です。もし最初のサーバーにアクセスできない場合は2番目のサーバーへのアクセスを試行し、それもダウンしている場合は3番目…というようになります。
http://wpdocs.sourceforge.jp/HyperDB

HyperDBの設定方法に関しては下記のdogmap.jpさんの情報が非常に参考になると思います。
HyperDB でお手軽に WP の MySQL サーバを複数分散

次に2の要件に関してですが、こちらは上記構成図にも記載されているように、「lsyncd」を使用することで実現できます。

Lsyncd watches a local directory trees event monitor interface (inotify or fsevents). It aggregates and combines events for a few seconds and then spawns one (or more) process(es) to synchronize the changes. By default this is rsync. Lsyncd is thus a light-weight live mirror solution that is comparatively easy to install not requiring new filesystems or blockdevices and does not hamper local filesystem performance.
http://code.google.com/p/lsyncd/

詳細に関しては上記ページからリンクされているマニュアルをご参照頂ければと思いますが、ご参考までにエンジニアブログのweb1サーバーで使用しているlsyncdの設定ファイルのsync節を下記に記載いたします。(ディレクトリパスやIPアドレス等はダミーです。web2サーバーの方のlsyncd設定ファイルもIPアドレス以外は同じ内容になります。下記の場合、hogeユーザーはweb1/web2の両方にSSHでアクセス可能で、sudoしてrsyncコマンドを実行できる必要があります)

sync{
        default.rsync,
        source = "/path/to/labs",
        target = "hoge@192.168.0.12:/path/to/labs",
        rsyncOpts = {"-a",
                "--rsh=ssh -i /home/hoge/.ssh/private_key",
                '--rsync-path=sudo rsync',
                },
        maxDelays = 1
}

※上記はlsyncd 2.0系の設定になります。2.1系とは設定項目名等が異なりますのでご注意ください。

補足:sudoでrsyncコマンドを実行できるように設定する理由
一般ユーザのアカウントでSSHログインして普通にrsyncしようとすると、パーミッションが不足してバックアップ漏れが発生する可能性があります。かといってrootアカウントでSSHログインできるように設定を変更するのは非常に危険です。そこで、rsyncを実行させたい一般ユーザのアカウントに対して、rsyncコマンドのみをsudoで実行できるように、下記のような設定をsudoersに追加して対応する方式が一般的です。
hoge ALL=(ALL) NOPASSWD:/usr/bin/rsync

最後に3の要件に関してですが、1で導入したHyperDBの機能により、どちらか一方のWebサーバーもしくはMySQLがダウンしても閲覧処理に関しては問題なく行うことができます。(マスタ側のサーバーが生きていれば更新処理も可能です)

まとめ

この作業をするまでlsyncdの存在を全く知らなかったのですが、少数のサーバー間でコンテンツを同期したい場合には非常に有用だなあと思いました。(サーバー数が増えてくるとlsyncdの設定ファイルの管理/更新が大変なので、そういう場合は別の方式を採用した方が良いとは思いますが)

WordPressを冗長構成にしたいというニーズがどのくらいあるのかは分からないのですが、企業のコーポレイトブログ等、重要度の高いサービスの場合には役に立つと思いますので、何かのご参考になれば幸いです。

明日は岡崎さんです。よろしくお願いします。