|
|
事例編〜Web 2.0サービスの中を見せます |
第6回:データベースの負荷分散とまとめ
著者:はてな 伊藤 直也 2006/11/1
|
|
|
1 2 3 次のページ
|
|
データベースの負荷分散
|
Webサーバーも順調に増えた、となると次はデータベースが悲鳴を上げる頃です。データベースの増設と行きましょう。
はてなではデータベースにはMySQLを利用しています。MySQLは組み込みでレプリケーションをサポートしているので、これを使わない手はありません。レプリケーションを行い、マスターDBのコピーであるスレーブDBサーバーを作り2台構成にします。
レプリケーションは、データベースを複数台に増やし、且つその複数のデータベースが保持するデータを同期させるための仕組みです。レプリケーションされたデータベースのうち、元々あったデータベースが親、それ以外が子という親子関係になります。
親はマスター、子はスレーブと呼ばれ、マスターへの更新処理と同じ処理をスレーブに伝播させることでデータの同期が行われます。実際にはマスターからスレーブへ処理が伝播するのではなく、スレーブがポーリングを行ってマスターと同期を取ることになります。
MySQLによるレプリケーションの設定方法の詳細はここでは割愛しますが、設定はそれほど難しくはありません。マニュアルなどを参考にされても良いでしょうし、多くのMySQL関連の書籍などにも詳しい手順が掲載されているかと思います。
|
Perl側のCRUD処理に手を加える |
単純にレプリケーションを行って台数を増やしただけでは負荷分散は行えません。2つのサーバーにデータベースクエリーが分散されるよう、アプリケーション側に手を入れる必要があります。このときの振り分け方ですが、マスター/スレーブによるレプリケーションを行った場合データベースのCRUD(CREATE(INSERT)/READ(SELECT)/UPDATE/DELETE)処理を、
- R(参照系処理)はスレーブへ
- CUD(更新系処理)はマスターへ
というようにクエリーが発行されるようにする必要があります。
MySQLのレプリケーションでは、マスターが更新されるとスレーブにその更新内容が伝わり常に同期が取られるようになっています。この同期はマスターからスレーブへの一方通行です。スレーブ側に更新処理を発行してしまった場合、両者の同期は行われず矛盾が発生してしまいますので注意が必要です。
MVCフレームワークを利用している場合、通常データベースへの処理はモデルクラスに集中しているので、ここに手を入れてCRUDの振り分けを実装するのがセオリーです。はてなではモデルクラスの実装として自前のO/Rマッパーを持っており、ここにその処理を実装しています。
O/Rマッパーのクラス階層の中で、データベースへの接続を管理しているクラスにおいて、マスターDBへの接続とスレーブへの接続それぞれのデータベースハンドラを生成し保持しておきます。参照系処理、つまりSQLのSELECTコールはスレーブ用ハンドラへ、CUD(INESRT/UPDATE/DELETE)はマスター用ハンドラへクエリーが発行されるようにしています。
モデルの実装にCPANモジュール、例えばClass::DBIを利用している場合はClass::DBI::Replicationなどを利用すると良いでしょう。データベース接続が抽象化されたO/Rマッパーなどを使っていれば、プログラマはマスター/スレーブどちらのサーバーにクエリーを発行しているかを意識せずにコードを記述できます。はてなのO/Rマッパーもそうですし、Class::DBIやDBIx::ClassなどのCPANモジュールを利用している場合も同じくです。
SQLをあちこちに書いてはいけない、というのはもはやすべてのWebアプリケーションプログラマの知るところですが、その理由の一つに、こういった複数のデータベースに対する処理をプログラマに意識させないための実装を行えるようにする、という点が含まれているわけですね。
|
1 2 3 次のページ
|
|
|
|
著者プロフィール
株式会社はてな 伊藤 直也
取締役最高技術責任者
ブログサービスやソーシャルブックマークなど、はてなの各種サービスの企画、開発を行う。著書に「BlogHacks」(オライリージャパン刊)。「続・初めてのPerl」(オライリージャパン)、「Perl救命病棟」(翔泳社刊)では監訳を務めた。
|
|
|
|