Sep 27, 2007

mt-searchがどうこうという話

「検索結果テンプレート」の修正でMTの検索結果表示にどの程度の効果があるか? (Junnama Online (Mirror))

面白いデータですね。

私が「下手な最適化」と書いたのは、

記事のメタ情報について「タグ」や「カテゴリー」を利用しているけど、エントリーの概要欄やキーワード欄、追記欄を利用していない、という場合はこれらのフィールドをできるだけ活用して他のテーブルにクエリを投げる回数を減らしてやる (MTからデータベースへのクエリの発行回数を減らす (mt-search.cgiを例にとって)。 (Junnama Online (Mirror)))

ようなハックのことです。高速化したければ、外部メタ情報の抽出をO(1)でできるような手段を下位レイヤーで提供するのが筋で、既知のデータベースの構造を元に局所的な最適化を行うのは二次的な方法に過ぎません。「局所的」と言ったのは、データベースの構造が変わった途端に有効でなくなるからです。「MTEntryDateは定数時間で取り出せるが、MTEntryCommentCountはそうではない」という知識は有用ですが、恒真ではありませんし、テンプレート作成者が「最適化」と称して再利用性の低いテンプレートを作り出すことも望ましいことではありません。

実のところ、MT4はそのような、つまり外部メタ情報の抽出を定数時間で取り出すための、手段を提供しています。FastCGI環境かmemcachedを使った環境で試すと分かりますが、エントリのコメント数などの外部メタデータはキャッシュされます。エントリーのコメント数を得る場合を考えてみると、初回はO(N)、2回目以降はO(1)、したがって平均的にはO(1)で得られるはずです。Junnamaさんの環境がどのようなものかは分からないので何とも言えませんが、もしFastCGI環境ならキャッシュハンドリングに改善の余地があるのでしょう。

2007-09-30追記: 仔細にコードを読んでいたらFastCGI環境では外部メタ情報をキャッシュしないことが分かりました。もう少し詳しい話は別のエントリで書く予定です。

あと実験に関して付け加えると、やや公正さに欠けると思います。2.が「ブログ記事のメタデータ」モジュールのみ外した状態になっているのは比較上問題があります。利用するテンプレートの個数が異なりますから。それなら最初からflatteningしたテンプレートを使って比較すべきです。

また、計測時間はMT::Builder::build()メソッドの実行時間を計測したものとほぼ同じとみなせると思いますが、ということは、スクリプトの呼び出しオーバーヘッドや検索本体の処理、テンプレートのコンパイル時間などを含まないということです。これらの時間が全体の実行時間においてdominantなら効果は限定的となりますね。実際のところは分からないわけですが。


ちょっと試しに計ってみました。単位は全部「秒」。

オリジナル
MaxResults レンダリング トータル 差分
10 0.304314 1.528 1.224
20 0.517478 1.868 1.351
40 0.927628 2.364 1.436
60 1.343529 2.865 1.521
80 1.786946 3.451 1.664
100 2.208508 3.996 1.787
メタ情報のうちコメント・トラックバックに関するものを削除したもの
MaxResults レンダリング トータル 差分
10 0.168146 1.406 1.238
20 0.237147 1.543 1.306
40 0.376270 1.795 1.419
60 0.514390 2.058 1.544
80 0.659881 2.309 1.649
100 0.821395 2.606 1.785

相変わらずふざけるなってくらい遅いです、特にオリジナルの方。MaxResultsを大きくすればするほど全体時間に占めるレンダリングの割合が増加していて、オリジナルの場合には50%を越えています。やはり10〜20が実用域ですね。私の感覚からすると、0.5秒を切らないと常用する気は起きません。

Sep 25, 2007

MT4プラグインの多言語化 Tips

MT4のプラグインの多言語化機能は一部の部位にしか有効でない。

例えば、下記リンクから得られるような多言語化済みサンプルプラグインを考える。

MT4-L10N-Example.zip (リンク切れ直しました)

このプラグインは、プラグイン設定画面、ダッシュボードウィジェット、ダッシュボードウィジェットから起動できるポップアップ画面を備え、それぞれ多言語化してある(ダッシュボードウィジェットやポップアップ画面の作り方などはRegistering Dashboard Widgets | Movable Type DocsCreating a New Screen Inside the Application | Movable Type Docsなどを参照のこと)。

実際に動かしてみると、プラグインの設定画面はローカライズされる。

また、ウィジェットの選択メニューの項目もローカライズされる。が、ウィジェット本体とポップアップ画面はローカライズされない。

これはウィジェットやMT::App::build_pageを使って生成されるページなどは、プラグインの言語辞書ではなく、コアコンポーネントの言語辞書を用いてローカライズされるからである。これは結構鬱陶しい。

そこでプラグインのクラス(サンプルではMT::Plugin::Example1)に以下のメソッドを追加する。

sub load_tmpl {
    my $plugin = shift;
    my $tmpl = $plugin->SUPER::load_tmpl(@_);
    $tmpl->text($plugin->translate_templatized($tmpl->text));
    $tmpl;
}

これはプラグインの用意したテンプレートを読み込んだ直後にそのテンプレートの内容をローカライズするように、デフォルトのload_tmplメソッドをオーバーライドするものである。通常は(1)テンプレートを読み込み、(2)テンプレートに含まれるMTタグを評価し、(3)コアコンポーネントの辞書を使ったローカライズを行うことでページ生成している。これに対して、上記のメソッドを追加すると、(1)テンプレートを読み込み、(2)プラグインの辞書を使ったローカライズを行い、(3)テンプレートに含まれるMTタグを評価し、(4)コアコンポーネントの辞書を使ったローカライズを行う(実際には変換すべきタグがないので何もしない)ことになる。

結果は以下のようになる。

めでたしめでたし。

このTipsの有効期限はMT4がこの問題に対処するまで、だけど。

Sep 21, 2007

FastCGI環境で MT4を使うなら MT-Dispatchを使うといいよ

前振り。FastCGIプロセスのリサイクリングを目的としてFastCGIスクリプトファイルをtouchするというプラグインがある。

TouchMe (Junnama Online (Mirror))

相手はJunnamaさんだということで安心して忌憚のないところ言えば、美しくない。ファイルにtouchしたらリロードするというのは特定のFastCGI実装が備えている機能でしかない。もちろんそのことを承知の上で、限られた条件下で機能するツールを作ったのだろう。だよね?


さて本題。この記事ではまずMovable TypeのデフォルトのFastCGIサポートは使いものにならないことを言明しておきたい。なぜなら、LaunchBackgroundTasksが使えないからである。この欠陥はあまり広く認識されていないようにも見える。これに比べればプロセスリサイクリングの手段が(コマンドラインで行う以外に)存在しないというのは瑣末事なのに、である。この記事の目的はこの問題を周知せしめることと、より良い方法を紹介することである。ここで紹介する方法は、TouchMeが実現しようとしているFastCGIプロセスリサイクリングの「より優れた解」にもなっている(これが前振りの理由)。

まず、LaunchBackgroundTasksが使えるCGI環境と使えないFastCGI環境とを比較するならどちらを選ぶべきだろうか。速度の点で後者を選ぶべきだろうか。私なら迷わず前者を選ぶ。

なぜかと言えば、後者の方がタイムアウトしやすいからだ。例えば、トラックバックの一覧画面からスパムに分類されていないスパムトラックバックを200個ほどまとめて削除してみればよい。LaunchBackgroundTasksが使えない環境では、おそらくフロントエンドプロセス(つまり、画面レンダリングを行うのと同一のプロセス)で一度に大量のエントリーを再構築することになるはずである。それゆえ容易にタイムアウトを起こし得る。これに対してLaunchBackgroundTasksが使える環境では、エントリーの再構築はforkシステムコールで生成されたバックエンドプロセスで行われるので、フロントエンドプロセスがタイムアウトすることは...まずない。

プロセスの常駐化による高速化より、タイムアウトしないシステム(=正常に動作するシステム)の方が重要なのは明らかである。だから、Movable TypeのデフォルトのFastCGIやmod_perlサポートは使いものにならない。

ではどうすればよいかと言うとハックするしかない。私がMT 3.2から移行できないのも主にこの改造が原因なのだが、そうしたシガラミがないのであれば、Reed A. CartwrightのMT-Dispatchを使うのが現状最も簡便で効果的な「ハック」である。

De Rerum Natura: MT-Dispatch

日本語で解説された文書が見当たらないところを見ると比較的マイナーなのだと思う。MT-Dispatchを使うと、FastCGI環境でもLaunchBackgroundTasksが利用可能になる。また、MT4に対応したversion 1.4からはダッシュボードからすべてのMTインスタンスを再起動できるようになっており、プラグインの脱着やmt-config.cgiの設定変更などの反映を簡便に行える。

以下は、Apache 2.2 + mod_fcgid 2.1での設定方法について簡単に説明&自分用のメモ。

  1. FCGI, FCGI::ProcManager, Sub::Override, File::Slurpなど必要なPerlモジュールをインストールしておく。
  2. 上記リンクより入手できるMT-Dispatch-1.4.tar.gzをMT4のpluginsディレクトリに展開する。
    $ cd /PATH/TO/MT/plugins; tar xfz ~/MT-Dispatch-1.4.tar.gz
  3. mt.cgiなどの拡張子をfcgiにリネームする。
    $ mv mt.{,f}cgi
    $ mv mt-comments.{,f}cgi
    $ mv mt-tb.{,f}cgi
    
  4. mt-config.cgiに必要なディレクティブを追加する。
      AdminScript mt.fcgi
      CommentScript mt-comments.fcgi
      TrackbackScript mt-tb.fcgi
      
      LaunchBackgroundTasks 1
    
  5. Apacheのhttpd.confに以下のように追加する。
      LoadModule fcgid_module modules/mod_fcgid.so
      
      <IfModule mod_fcgid.c>
          # DefaultInitEnv MT_HOME /PATH/TO/MT/
          DefaultInitEnv PERL_FCGI_MAX_REQUESTS 250
          DefaultInitEnv PERL_FCGI_CHILDREN 4
          DefaultInitEnv PERL_FCGI_LOG /var/log/apache22/mt-dispatch.log
          <Directory "/PATH/TO/MT">
              AddHandler fcgid-script .fcgi
              Options ExecCGI
              allow from all
              FCGIWrapper /PATH/TO/MT/plugins/MT-Dispatch/mt-dispatch.fcgi .fcgi
          </Directory>
      </IfModule>
    
    MT_HOMEは設定する必要はない。複数のMT4を同一ドメインにインストールした場合には、インストール場所ごとにMT_HOMEが異なるはずなのでむしろ設定しない方がよい。PERL_FCGI_LOGはFastCGIプロセスから書き込み可能なファイルを指定すること。デフォルトでは/var/log/mt-dispatch.logに書き込むようになっていて嵌まるので要注意。
  6. apachectl restart。

こんな感じ。すでにFastCGI環境を使っている人なら特に滞りなく設定できるだろう。

Sep 20, 2007

HatenaBookmarker Plugin 0.10公開

Movable Typeのブログ記事やウェブページをはてなブックマークにポストするプラグインを作ったので公開しておきます。MT4専用。はてな大好きな人専用。

HatenaBookmarker - ogawa - Google Code

HatenaBookmarkerプラグインは、Movable Typeのブログ記事やウェブページをはてなブックマークにポストするのをアシストするプラグインです。おおまかに言って以下の2つの機能を提供します。

  • 新規に公開状態のブログ記事を追加したり、公開状態のブログ記事を更新したりしたときに、そのブログ記事をはてなブックマークに追加する機能
  • 「ブログ記事の一覧」画面などから選択したブログ記事をはてなブックマークに追加する機能

このプラグインは、以前作ったAddToHatenaBookmarkプラグインをMT4に対応させ、機能拡張を行ったものになっています。私にしては珍しくバージョン番号が0.10から始まっているのはそういうわけです。

Sep 18, 2007

TheSchwartzStats Plugin 0.02公開

TheSchwartzジョブのステータスを表示したり、バックグラウンドで実行したりできるダッシュボード・ウィジェットを作ったので公開しておきます。MT4専用。

TheSchwartzStats - ogawa - Google Code

Movable Type 4.0以降ではTheSchwartzを使ったバックグラウンド・リビルドが可能になっていますが、その進行状況をモニターする方法がないため、本当に実行されているのかどうかよく分かりません。TheSchwartzStatsプラグインは、バックグラウンド・リビルドの進行状況をダッシュボード上に表示するためのウィジェットを実現します。また、TheSchwartzジョブをバックグラウンド実行する機能も実現しています。

このプラグインでちょっと悩んでいるのは、ダッシュボード・ウィジェットやMT::App::CMSに追加したメソッドの表示をローカライズする方法がよく分からないということですね。

Sep 14, 2007

ModifiableSetVarBlock Plugin 0.01公開

MTSetVarBlockタグでmodifierを使えるようにするプラグインを作ったので公開しておきます。MT4専用。

ModifiableSetVarBlock - ogawa - Google Code

詳しくは上記ページを参照してください。

このプラグインの肝は、「MT4ではCoreコンポーネントのタグ定義を変更する方法が提供されている。使ってみたかった。」です。

MT3まではこのような書き方をしていたのですが、

use MT::Template::Context;
no warnings 'redefine';
*MT::Template::Context::_hdlr_XXXX = sub { ... };

MT4ならプラグインのクラスに以下のようなメソッドを定義してやればよくなりました。

sub init {
    my $plugin = shift;
    $plugin->SUPER::init(@_);
    my $registry = MT->component('core')->registry('tags', 'block');
    $registry->{XXXX} = sub { ... };
}

直感的ですね。

Sep 13, 2007

BlogSkeletonCloner Plugin 0.01公開

複製ネタ・その2。Movable Typeのブログのスケルトンのみを複製するためのプラグインを作ったので公開しておきます。

BlogSkeletonCloner - ogawa - Google Code

BlogSkeletonClonerプラグインは、ブログのスケルトンのみを複製するためのプラグインです。MT 4.0に標準添付されているWeblogClonerプラグインはブログ記事やコメントやトラックバックも含めてブログをまるごと複製する機能を提供しますが、このプラグインはブログのコンテンツ以外の部分のみを複製するので、例えばデザインやテンプレートのみ共通の複数のブログを作りたい場合などに便利です。

このプラグインでは同時に複製できるブログの数を4個に制限しています。これは複製中にタイムアウトなどが発生しないようにするためです。標準のWeblogClonerは同時処理数を1個に制限していますからそれよりは簡便に大量の複製を作ることができます。意味ないけど。

Movable Type 4.0の機能を利用して実現しているため、3.xでは動作しません。

DuplicateEntries Plugin 0.02公開

複製ネタ・その1。Movable Typeのブログ記事・ウェブページ・テンプレートを複製するためのプラグインを作ったので公開しておきます。

DuplicateEntries - ogawa - Google Code

DuplicateEntriesプラグインは、MT CMSの「ブログ記事の一覧」画面、「ウェブページの一覧」画面、「ブログのテンプレート」画面から、選択したアイテムをコピーして新しいブログ記事・ウェブページ・テンプレートを作る機能を実現します。複製されたアイテムは「下書き」状態である点を除いてオリジナルのアイテムの完全な複製となります。

Movable Type 4.0の機能を利用して実現しているため、3.xでは動作しません。

Sep 12, 2007

横審は全員退任してくれ。

ここんとこ忙しくてまったくスルーしていた。

横審から朝青龍に引退勧告の声 - デイリースポーツ - Yahoo!スポーツ

横審は全員退任してくれ。頼むから。

協会も横審もマスコミも横綱に対するリスペクトが足りなさ過ぎる。朝青龍は白鵬みたいな小物の横綱とは違う。状況と時間が許せばありとあらゆる大相撲の歴史を塗り替えることができる唯一無二の存在である。その朝青龍へのリスペクトが足りない。朝青龍をスポイルすることの損失の甚大さ加減が分かっていない。巡業を仮病で休んでサッカーしたっていいじゃないか。それをテレビで観てみんな愉しんだろう? それが新しい歴史になるだけだ。むしろもう90年代の初頭から続いているであろう巡業の興行としての不振、あるいは力士や部屋にとって望ましい(儲かる)興行ではないことの方が問題だろう。いずれにせよ、朝青龍をいかにして横綱として引き止め、未来の偉大な記録を達成なさしめるかというのが協会と横審の考えるべきことだ。それもしないどころか追い出しにかかるような連中が横綱だの大相撲の権威だのについて語るなど笑止だ。

重要なのは力士、その中でもとりわけ、強い力士だ。強さが「主」で、道徳観が「従」。それが分からない裏方は黙ってろと言いたい。

About Me

My Photo

つくばで働く研究者

Total Pageviews

Amazon

Copyright 2012 Ogawa::Buzz | Powered by Blogger
Design by Web2feel | Blogger Template by NewBloggerThemes.com