大規模SNSのボトルネックとソリューション大規模サイトの舞台裏(3/4 ページ)

» 2008年08月29日 08時00分 公開
[藤本真樹,ITmedia]

フックメソッドの追加

 当然ですが、データ更新時にフックをかけるためには、データの更新パスを可能な限り絞り込んでおく*(ソースコード中に同じような処理が散らばらないようにする)必要があります。GREEでは、テーブルごとにデータベースインタフェースが定義されていて、更新処理が行われるのはINSERT/UPDATE/DELETEを行う3種類のSQL文だけなので、「あるテーブルが更新されるパス」は簡単に絞り込めます*

 ですので、これらのSQL文を呼んでいる個所に、次のようなコードを追加することで安全にフックをかけることができます。

function add(……) {

        :

        :

  Gree_Hook::profile_update(……);

}


 とはいえ、データベースアクセスレイヤーにフック処理を追加するのは設計上美しくないですし、実際問題このようなフック機構を実装しようとすれば、

  • フックメソッドに必要な情報を渡すことができない
  • コンテキストによっては無用なフックをかけてしまう

といった問題が出てくることがあります。このため、もしアプリケーションをきちんと設計できるのでしたら、データベースアクセスレイヤーのもう1つ上のレイヤーでフックをかけるのがよいのではないかと思います。

 ということで、日記エントリを追加するメソッドに次のようなコードを追加します。


function addEntry(……) {
        :    ← 日記エントリを追加するいろいろな処理
        :
  $this->scheduleOperation($blog_uri_str,
    $primary_author_uri_str, $entry_uri_str, 'blogEntryAdded',
    array('remote_ip_addr' => $this->_remote_ip_addr)
  );
}

フックメソッドの内部処理

 フックメソッドの処理は単純で、必要な情報をイベントキューに追加するだけです。例えば上記のコードの場合、blogEntryAddedというイベント名と追加された日記エントリのID、追加したユーザーのIDと追加情報がイベントキューに追加されます。なお、イベントキューはデータベース上のテーブルとして存在し、スキーマはリスト2のようになっています。また、blogEntryAddedのキューは、リスト3のような内容になります。


+---------------+-----------+------+-----+---------+----------------+
| Field         | Type      | Null | Key | Default | Extra          |
+---------------+-----------+------+-----+---------+----------------+
| id            | int(11)   |      | PRI | NULL    | auto_increment |
| situation_uri | char(127) |      | MUL |         |                |
| initiator_uri | char(127) |      | MUL |         |                |
| subject_uri   | char(127) |      | MUL |         |                |
| operation     | char(127) |      | MUL |         |                |
| parameter     | char(255) |      |     |         |                |
+---------------+-----------+------+-----+---------+----------------+

リスト2 イベントキューのスキーマ

id:            1
situation_uri: urn:gree:blog:1
initiator_uri: urn:gree:person:1
subject_uri:   urn:gree:blog:entry:1
operation:     blogEntryAdded
parameter:     {"remote_ip_addr":"0.0.0.0"}

リスト3 blogEntryAddedのキューに入るデータの例

 以上で日記エントリ追加時の処理は完了です(ちなみに、イベントキューを追加するだけなので、負荷はわずかで済みます)。

このページで出てきた専門用語

データの更新パスを可能な限り絞り込んでおく

ある関数が開始してから実行を終了するまでの区間を閉じ込めてしまう「Point Cut」という手法が使えるとうれしい。PHPでは難しいのだが……。

「あるテーブルが更新されるパス」は簡単に絞り込めます

このように気を使っているのは更新系のSQLだけで、逆にSELECTはさまざまなメソッドを通じて行われる。


Copyright © ITmedia, Inc. All Rights Reserved.

注目のテーマ