2010/11/08

DECOLOGでのMySQL BlackHoleエンジンの使い方


こんにちわ、ミツバチワークス stoneです。

DECOLOGでは、データベースにMySQLを使用しています。
ストレージエンジンのメインはInnoDBなのですが、他にもMyISAM、BlackHole、Archiveエンジンを使っています。
今回は、その中でBlackHoleエンジンについて、DECOLOG内での利用方法をご紹介したいと思います。


BlackHoleエンジンについて


BlackHoleエンジンは、何もしません。
insert、update、deleteを行っても、データは全く変更されませんし、selectをしても、データは何も返ってきません。
実際のデータファイルを見てみても、テーブル定義ファイルの.frm以外のファイルは作成されません。
/dev/nullと似ているイメージです。

が、BlackHoleのテーブルに対して発行されたinsert、update、deleteは、binlogには残ります。
そのため、レプリケーションを行っている場合、slave側で何か実体のあるストレージエンジンでレプリケーションしていれば、その変更は、slave側に保存されることになります。

また、内部的には、何もしていないので、サーバーからの応答は、すごく速いです。


記事データの配置


以前は、DECOLOGでも、データベースもそれほど系統分けされていなくて、記事に関連するデータは、すべて、1台のサーバーがマスターとして稼働していました。



記事内の画像は、もちろん、本文データも大きくなってしまう傾向にあるので、
別テーブルとして運用しています。


ユーザーの投稿の滞留が発生


DECOLOGはデコメを専用アドレスに送ることによって記事投稿するブログです。受信メールサーバでは、受信したメールをPHPに渡すことによってDBへの登録を行っています。
ユーザーがどんどん増えてきて、1日あたりの記事投稿の件数が増えてくると、受信したメールをデータベースへ登録するシーケンスでメールの滞留が発生するようになりました。
よくよく状況を調べてみると、新規のテキストデータ・画像データをinsertする際、MyISAMでのテーブルロックが発生していました。
ご存知のように、MyISAMエンジンの場合、データに何かしら変更が入る場合、テーブル全体がロックされます。
このテーブルロックが、多発していて、それにより投稿されたメールの処理が遅れ、滞留するようになっていました。


対策1 マスターをBlackHole化


記事のテキストデータ・画像データはともに、マスターのサーバーへselectすることはなく、
また、insertされてから、投稿したユーザーがページへアクセスして、記事を表示(select)されるまで、少なくとも数秒程度のタイムラグがあります。
この特性を利用して、masterをBlackHole化することにしました。

手順としては。。。。。
masterのサーバーで
mysql> alter table (テキストテーブル) rename to (テキストテーブル)_saved;
mysql> create table (テキストテーブル) like (テキストテーブル)_saved;
mysql> alter table (テキストテーブル) engine=BlackHole;
として、テーブルをBlackHole化した後、 slaveのサーバー上で、
mysql> drop table (テキストテーブル);
mysql> alter table (テキストテーブル)_saved rename to (テキストテーブル);
として、テーブルを元に戻します。



対策2 memcachedを併用


「対策1」を導入した後に気づいたのですが、投稿したユーザー本人はその記事を見るまでに、数秒のタイムラグがあるのですが、人気があって頻繁にアクセスされているブログの場合、投稿されたそのタイミングで、他のユーザーからのアクセスがある場合があるんですね。
そうすると、テキストデータ・画像データのレプリケーションがまだ追いついていないケースがあって、その記事が正常に表示できないという問題が出てしまいます。

そこで、記事テキストと記事画像については、投稿のタイミングで、データベースよりも先に、memcachedにもデータをストアしておいて、レプリケーションのタイムラグを表面化しないようにしました。



次回は、DECOLOGでのArchiveエンジンの使い方について、ご紹介する予定でいます。

では、また次回に♪