3.2-ja 再構築時のパフォーマンス(その3)
改善版が出るようですのでお知らせまで。
去る9月29日より出荷を開始しました、「Movable Type 3.2日本語版」について、Berkeley DBをご利用のお客様で、以下の現象を確認いたしましたので、ご案内いたします。
本ブログでの関連エントリーも改めて挙げておきます。
先のエントリーでも書いていますが、メモリ増加の不具合については英語版ですでに発生しています。この時点まで顕在化されなかったのは、例えばアーカイブページでメニューリストを表示する・しないという文化の違いがあるのでしょうか。
デフォルトテンプレートのアーカイブページにはそもそもメニューリストがありませんし。
3.2-ja アップグレード方法
3.x-ja から 3.2-ja のアップグレード方法です。1項のバックアップについては一番下に掲載しているベータサイトのリンクが参考になります。また3項の設定ファイルの編集で具体的な設定内容は割愛しておりますので現在使用中の mt.cfg の内容を確認して設定してください。
新規インストールにつきましては、以前書いたMovable Type 3.2 新規インストール方法を参照ください。
1.データのバックアップ
万が一に備えて、これまでのデータのバックアップをとります。エントリーのバックアップは管理メニューの「読み込み/書き出し」をクリックして、次ページの一番下にある「?からエントリーを書き出す」のリンクをクリックします。詳細はMovable Type のバックアップ方法をご覧ください。
2.パッケージのダウンロード
Movable Type 公式サイトのダウンロードのページよりアーカイブをダウンロードします。リンクで進んだ次のページに限定個人ライセンス(無償)があります。なおこれまでのようにアップグレード/フルインストールの区別はありませんので、ZIP形式・tar.gz形式のいずれかを選択します。
3.設定ファイルの編集
パッケージを解凍し、その中にある mt-config.cgi-original を mt-config.cgi にリネーム(またはコピー)して、任意のエディタで開いて編集します。下記は mt-config.cgi で設定が最低限必要な部分を抜粋しています。赤の CGIPath と StaticWebPath は必須項目です。その間に挟まれたデータベースの設定は、MySQL/PostgreSQL/SQLite/BerkeleyDB のいずれかについて、そのまま継続する場合はこれまでに設定されていたものをそのまま転記します。パスワードが必要なデータベースを使用されている場合、mt-db-pass.cgi がなくなりましたので、このファイルに記述していたパスワードを DBPassword に設定します。なお設定を有効にする場合、行頭の # と半角空白は削除してください。
StaticWebPath は3.1xまで任意の項目でしたが3.2より必須となります。mt-static というディレクトリまでをURLで指定します。レンタルサーバの場合、cgi-bin ディレクトリにこのディレクトリをおいても正常に動作しない可能性が高いため、index.html が生成されるURL直下に mt-static ディレクトリを配置すると良いでしょう。
# Movable Type uses the CGIPath setting to construct links back to
# CGI scripts; for example, the MT tag <$MTCGIPath$> is substituted
# with the value of the CGIPath setting. You will need to change this
# value when you first install MT. This should be set to the URL
# used to access mt.cgi but *without* mt.cgi appended to the end.
CGIPath http://www.example.com/cgi-bin/mt/
(MySQL の場合)
### MySQL Configuration - Add the name of your database, username
# password and, optionally database host given to you by your web
# hosting provider.
#
# ObjectDriver DBI::mysql
# Database <database-name>
# DBUser <database-username>
# DBPassword <database-password>
# DBHost localhost
(PostgreSQL の場合)
### PostgreSQL Configuration - Add the name of your database, username,
# password and, optionally database host given to you by your web
# hosting provider.
#
# ObjectDriver DBI::postgres
# Database <database-name>
# DBUser <database-username>
# DBPassword <database-password>
# DBHost localhost
(SQLite の場合)
### SQLite Configuration - SQLite requires only the path to your SQLite
# database file.
#
# ObjectDriver DBI::sqlite
# Database /path/to/sqlite/database/file
(BerkeleyDB の場合)
### BerkeleyDB Configuration - BerekelyDB requires only the path to your
# database directory.
#
# DataSource /path/to/database/directory
:
# If you place all of your MT files in a cgi-bin directory, you
# will need to place the directory containing your static files
# (mt-static) elsewhere, so that the webserver will not try to execute
# them. StaticWebPath is the path to your mt-static directory.
#
# StaticWebPath http://www.example.com/mt-static
4.ファイルのアップロード
解凍したファイルをすべてアップロードします。mt-static/imagesディレクトリ内のファイルはバイナリーモードで、それ以外はASCIIモードでアップロードします(公式サイトの説明より引用)。またCGIスクリプト (拡張子が .cgi のファイル) のパーミッションを755等に設定します。
5.システムのチェック
ブラウザより mt-check.cgi を実行します。「準備が整いました。」というメッセージを表示した場合、無事に作業が終了したことになります(公式サイトの説明より引用)。
6.セットアッププログラムの実行
なお、インストールについては公式サイトにも説明があります。
3.2-ja 再構築時のパフォーマンス(その2)
3.2-ja 再構築時のパフォーマンスで頂いたコメント・トラックバック等の情報より、再構築時に500エラーが発生する原因と対処方法です。
原因は、「BerkeleyDB 使用で recently_commented_on でのメモリ消費が大きい」ということらしいです。具体的な内容につきましては下記に引用させて頂いた通りです。
recently_commented_onはlastnやdaysオプションと一緒に指定することはできませんでしたが(中略)?3.2では指定された範囲のエントリーを対象に最近コメントされたエントリーをリストアップする機能となりました。(中略)これを実現するために追加されたMTへのナイーブなコード追加が甚大な影響を及ぼしています。
(中略)指定された範囲のMT::Entryオブジェクトをすべてメモリ上に読み込んだ後、それら個々のエントリーに付けられた最終コメント時刻の降順にソートし、recently_commented_onオプションで指定した数だけ先頭から取り出すということを行っています。もっと悪いことには、lastnなどで範囲指定することなく使用すると、上記の操作がすべてのエントリーを対象に行われることになります。
ということで、同エントリーにて対処用パッチも提供されております(3日付で最新版が出ています)。それを該当のスクリプトに適用させることでインデックステンプレートの再構築は問題なく実行できることを確認できました。なおパッチは BerkeleyDB で MTEntryNext 等が正常に動作しない問題の対処も含まれています。
パッチの適用方法は、該当の Perl スクリプトを任意のエディタで開き、パッチの行頭左に「+」マークがある行を追加(「+」は除く)し、「-」マークの行を削除します。作業前に予めバックアップをとってください。またパッチのあてかたを間違えると mt.cgi 実行時に 500エラーになりますのでご注意ください(元に戻せば良いので慌てることはありません)。
2005.10.04 追記:勝手ながら下記にパッチの変更箇所を挙げさせて頂きました。赤色を削除して青色を追加します。これはパッチの修正方法が分からない方のための補助的な位置付けです。パッチの内容は適宜変更される可能性がありますので、基本的には原本を参照してください。
正規のパッチ適用方法はAzrael:Tagwire、MT-XSearch、Cygwin導入メモに詳しく書かれています。
lib/MT/Entry.pm
sub comment_latest {
my $entry = shift;
unless ($entry->{__comment_latest}) {
return undef unless $entry->comment_count;
require MT::Comment;
$entry->{__comment_latest} = MT::Comment->load({
my $iter = MT::Comment->load_iter({
entry_id => $entry->id,
visible => 1
}, {
'sort' => 'created_on',
direction => 'descend',
limit => 1,
});
$entry->{__comment_latest} = $iter->();
}
$entry->{__comment_latest};
}
lib/MT/ObjectDriver/DBM.pm
my $idx;
my(%ids, @ids);
my $unlock;
$args->{'sort'} = '' if $args->{'sort'} eq 'id';
if (my $col = $args->{'sort'}) {
my $idx_file = _db_index($driver, $class, $col);
($this_db, $idx, $unlock) =
:
(略)
:
%object_cache = ();
}
use constant MAX_CACHE_SIZE => 1000;
sub load {
my $driver = shift;
$driver->run_callbacks($_[0] . '::pre_load', \@_);
:
(略)
:
unless (wantarray) {
$unlock->();
if ($terms && !(ref $terms)) {
if (exists $object_cache{$class} && (scalar keys %{$object_cache{$class}} > MAX_CACHE_SIZE)) {
# garbage collection
$object_cache{$class} = {};
}
$object_cache{$class}->{$terms} = $obj;
}
return($obj);
アーカイブテンプレートについては再構築時のメモリ問題が引き続き発生しています。3.2-ja 再構築時のメモリ量増加についてではサブカテゴリーが原因と書きましたが、カテゴリーリスト・月別アーカイブリストも影響を及ぼしているようです。
ということで、もう少し真面目に、3.171-ja と 3.2-ja の日別アーカイブおよびエントリーアーカイブの再構築時の最大メモリ量について計測してみました。結果は下表の通りです。
計測は、例えば日別アーカイブの「カレンダー」は、他の(疑いのある)4つのリストはテンプレートに設定せず、中央カラムのエントリーは公開テンプレートと同じ状態で再構築したものです。
実施環境(DB・エントリー・コメント・トラックバック数等)は3.2-ja 再構築時のメモリ量増加についてと同様です。またいずれも 500エラーにならず正常に完了しています。
| 3.171-ja | 3.2-ja | |
| カレンダー | 約23MB | 約31MB |
| エントリーリスト | 約23MB | 約30MB |
| カテゴリーリスト | 約23MB | 約180MB |
| サブカテゴリーリスト | 約23MB | 約330MB |
| 月別アーカイブリスト | 約23MB | 約130MB |
| 3.171-ja | 3.2-ja | |
| カレンダー | 約22MB | 約24MB |
| エントリーリスト | 約22MB | 約28MB |
| コメントリスト | 約23MB | 約64MB |
| トラックバックリスト | 約23MB | 約26MB |
| カテゴリーリスト | 約23MB | 約70MB |
| サブカテゴリーリスト | 約23MB | 約116MB |
| 月別アーカイブリスト | 約23MB | 約56MB |
3.171-ja が22MB?23MB で安定しているのに対し、3.2-ja ではカテゴリーリスト・サブカテゴリーリスト・月別アーカイブリストのメモリ量が増加しています(赤色)。その3つのリストについて、日別アーカイブがエントリーアーカイブの倍近い値になっているのは、再構築数(エントリーアーカイブ:40/日別アーカイブ:80)の違いでしょうか。
青色の個別エントリーアーカイブのコメントリストはやや高めの値ですが、パッチによって劇的に改善されたものです(パッチ適用前は数百MB上昇して500エラー)。
3.2-ja 再構築時のパフォーマンス
再構築時のパフォーマンスについて、昨日に引き続き記します。新規インストールおよびアップグレートの参考にして頂ければ幸いです。
まず、3.2-ja 再構築時のメモリ量増加についてで、他の方から頂いたコメントや、関連すると思われる他サイトの記事および状況をまとめてみました。
- eizo slash blog:Movable Type 3.2日本語版
- 再構築でCPU100%(500MB以上のメモリを使用)
- やむやむ:MovableType3.2-jaにアップグレード
- カテゴリリスト再構築で500エラー発生
- SWEET WATER Web Server:MT3.2 の CPU 使用率
- すべての再構築でCPU使用率ほぼ100%
- + 馬グナカルタ +:骨折り損のくたびれもうけ?
- インデックステンプレートの再構築で500エラー発生
- V.J.Catkick:Movable Type 3.2 日本語版
- MTEntriesタグの中にrecently_commented_onオプションを付けるとリビルド出来なくなり500エラーを返す
次にインデックステンプレートの再構築時におけるCPU使用率およびメモリ使用量を調べました(前回はアーカイブテンプレート)。
| 3.171-ja | 3.2-ja | |
| CPU使用率(最大) | 約88% | 約90% |
| メモリ使用量(最大) | 約14,700KB | 約142,000KB |
最大CPU使用率はどちらも近い値ですが、3.171-ja が再構築直後の瞬間的な値であるのに比べ、3.2の場合は再構築全体で高い値を示しています。また 3.2-ja のメモリ使用量は 3.171-ja の10倍になっています。
英語版3.2まで遡って再構築の確認をしたところ、同じ事象が発生しています。
まとめると、3.2では新規インストール・アップグレードにかかわらず、インデックステンプレート/アーカイブテンプレートに「最近のコメント(recently_commented_onオプションあり)」「サブカテゴリーリスト」等のメニューを設置している場合、500エラーが発生する可能性があります。
3.2-ja 再構築時のメモリ量増加について
別のサイトでの3.2インストールおよび公開テンプレート確認中に、アーカイブテンプレートの再構築でメモリ量が爆発的に増加するという現象が発生しています。
追記:このエントリーは 3.2-ja を元に測定したものです。3.2-ja-2 での対処方法については Movable Type で再構築エラーになる場合の原因と対処をご覧ください。
原因の切り分けを行ってみたところ、日付アーカイブではサブカテゴリーリスト、エントリーアーカイブではさらに「最近のコメント」リストを削除することで正常?に再構築できるようになりました。が、メモリ量の増加率は 3.171 に比較するとそれでもかなり大きいように感じられます。エントリーアーカイブの再構築では最高1.4GB位まで上昇しました(キャプチャすらできず)。
デフォルトのアーカイブテンプレートには、そのようなメニューリストはそもそも設定されていないのですが、試しに日付アーカイブにサブカテゴリーリストを設定して再構築したところ、同じ事象になりました。またこれらのリストをインデックステンプレートとしてモジュール化した場合は問題なく再構築できました。
ということで、アーカイブテンプレートを再構築すると500エラーが発生する可能性があります(Windows以外の環境では不明)。インデックステンプレートでもメモリ量は急増しますが1ページで終了するため、顕在化しないようです。
以上です。なお当方の動作環境は、WindowsXP Perl 5.6.1 BerkeleyDB。使用したエントリー107、コメント154、トラックバック21、カテゴリーは15(すべてトップレベル)です。
以前のMTタグはほぼそのまま使えるという認識でおりますが、誤り等ございましたらお許しください。
2006.05.05 追記
対処方法へのリンクを追記しました。

