結論だけ先に言うとMovable Typeの管理画面を高速化するプラグイン:CachePermsだけ見てればいい気がします。ここに書かれてる点以外はほとんど効果なし。
惰性でかれこれ10年以上Movable Type使ってるんですが、当初からの悩みが「遅い」こと。昔はしょぼいマシンで動かしていたので仕方ないかなぁと思っていたものの、それなりに最近のマシンに置き換えてもやっぱり遅いので、マジメに対処考えてみることにした。ちなみに、検索が遅いのは自分で検索用PHP書くことで対処してます。
漠然と「遅い」じゃ定量的じゃないので、まずは計ってみます。
[rarul@mana mt]$ time perl mt.cgi > /dev/null
real 0m1.216s
user 0m1.115s
sys 0m0.098s
[rarul@mana ~]$ cat /proc/cpuinfo |grep model |grep name
model name : Intel(R) Celeron(R) CPU N2820 @ 2.13GHz
model name : Intel(R) Celeron(R) CPU N2820 @ 2.13GHz
[rarul@mana ~]$ cat /proc/meminfo |grep MemTotal
MemTotal: 7953060 kB
普段のload averageは0.00、swapなしio詰まりもなし。これで1.2秒とか正気の沙汰じゃない。続けて少しがんばってみます。
[rarul@mana mt]$ perl -d:Profile mt.cgi > /dev/null
[rarul@mana mt]$ cat prof.out
time elapsed (wall): 2.0044
time running program: 1.7945 (89.53%)
time profiling (est.): 0.2099 (10.47%)
number of calls: 32525
number of exceptions: 1
(...snip...)
prof.outを見る限り時間かかっているのは、importと一部の呼び出し回数多いメソッド(MT::Component::registry, YAML::Tiny::_read_hash, YAML::Tiny::_read_hash とか)。てか呼び出し回数多いの基準が1000超えとか設計としてどうなんよと、しかもregistryとかpropertiesとかObjectとかDriverとかTemplateとか明らかにメタなクラスが目立つ。試しに、mt.cgiからlib/MT/Bootstrap.pm,lib/MT/App/CMS.pm,と読み進んでみたんですが、なんというか設計がメタメタ(meta)ですね、なにやってるかまったくわからない。たぶんMovable Typeの開発者もどれだけモジュールが読まれて何回呼ばれていてとか全くわからないんじゃないでしょうか。これを改善するのは厳しい、モジュールの粒度や込み込みを根本から改めて最初から書き直すべき次元でしょう。というわけで、中を変更するのはあきらめて、外から何とかするやり方を考える。
内容がかなり怪しいページっぽいけどMovable Type をめっちゃ高速化する20の方法 - 2013年Xmasバージョンを参考にいろいろトライしてみる。
- 全ステップの再構築は滅多にしないからどうでもいいや。
- 「メモリ<ディスク<DB(SQL)の順に速い。あるいはDB(SQL)>ディスク>メモリの順に遅い。」とか書いてる段落は明らかにミスリードしているので無視すべき。
- 「1.File::Cacheプラグインを使う」の段落、File::Cacheってナニ?ファイルアクセスをディスクアクセスと同一視している時点で説明が怪しいのでスキップ。
- 「2.DBをチューニングする」query_cache_size, sort_buffer_size, key_buffer_size, myisam_max_sort_file_sizeをばかでかくしてもほとんどベンチに差なし。InnoDBに変換してinnodb_buffer_pool_sizeをばかでかくしてもほとんど差なし。
- 「3.不要なプラグインの退避(削除)」CachePerms, Textile, spamlookup以外をやめて、ようやく0.1秒早くなった!
- 「4.再構築オプションの適切な選択をする」すでに最低限しか選んでないし。それ以前に再構築じゃない場面も遅すぎる。
- 「5.PageButeプラグインを使わない」最初から使ってすらいない。
- 「6.mt-static 以下のファイルをminifyする」なにいってるのかわからないけど、今時gzip圧縮&展開ごときでCPUパワー使い切らないし、それ以前に転送量が問題じゃないし・・・
- 「7.テンプレートを最適化する、テンプレートキャッシュを活用する」プラグイン減らそうっていった矢先にまた増やすのは・・・てか再構築じゃなくても遅いんだし・・・
- 「8. psgi/FastCGIを使う」これは効果あった。2/3くらいになった。気持ち的にFastCGI使うのはなぁと思ったけど。(Apacheのmod_fastcgi経由じゃないと動かせないのでベンチは取らず)
- 「9.ハイスペックサーバーにする」N2820がハイスペックだとは言わないけど、いってもCPU速度が倍程度でしょ。
- 「10.クライアントマシン(CMSを操作する側のマシン)をハイスペックにする」明らかにサーバスクリプト処理が遅いのにこの人ナニいってんの・・・
- 「11.PHPアクセラレータを導入する」プラグインとかそもそも最低限にしてるし。
- 「12.不要なプラグインの退避(削除)」いやだから使ってないし。
- 「13.静的化できる部分を静的化する」すでに静的化してるし、mt.cgiのトップにアクセスするのすら遅いのには関係ないし。
- 「14.キャッシュを使う」PHPアドオン使ってないから、Smartyとか関係ない・・・
- 「15.最新版 DynamicMTMLと Memcached」DynamicMTML使ってない・・・
- 「16.Minify、画像のBase64エンコード、gzip圧縮」だから転送量とかgzipのCPU時間とかはまったく影響してないんだってば。
- 「17.フロントサーバーとアプリケーションサーバーの分離、あるいはCDN」たくさんのリクエストを処理したいとかいうスループットの問題じゃなくて、1つのアクセスが完了するまでの時間のレイテンシが問題なんですよ。目の前にあるマシンにアクセスするのにCDNはさすがにない。
- 「18.PerlプラグインではMT->Requestでデータを使いまわす、PHPプラグインでは、$app->stash、$ctx->stashでデータを使いまわす」プラグインは(略
- 「19.PSGIで動かす、キャッシュを活用する」FastCGI使う前提ならPSGIはあんま関係ないような。そうでもないかな。Movable Type 6.0かららしいのでスキップ。「Data APIから取ってキャッシュする」ってMovable Type本体をすでにムシしてるよね。
- 「20.ミッションクリティカルなサービスで、読み出し系のものは、静的JSONのパブリッシュも検討しよう」結局13.とあんま言ってること変わらない。
結局、FastCGIにするのと、不要プラグインを消しまくるのとしか参考にならなかった。
他サイトないかなと探してて見つかったCachePermsが少し効果あり。中身見てみる限り、呼び出し回数が多い __deep_localize_labels や MT::Component::registry の効率悪い書き方の箇所をバイパスしてくれているっぽい。ただ、悲しいな、他にも呼び出し回数多くて遅いサブルーティンあるし、そもそものロードするモジュール多い問題はどうしようもないし。
ちびちびチューニングしたりMovable Type本体バージョンアップしたりしてみたものの、これくらいが限界でした。
[rarul@mana mt]$ time perl mt.cgi > /dev/null
real 0m1.129s
user 0m1.050s
sys 0m0.075s
[rarul@mana mt]$ perl -d:Profile mt.cgi > /dev/null
[rarul@mana mt]$ cat prof.out
time elapsed (wall): 1.8528
time running program: 1.6576 (89.46%)
time profiling (est.): 0.1952 (10.54%)
number of calls: 29947
(...snip...)
→ prof.out httpd経由ではFastCGIにしたので、これの2/3くらいの時間。ましにはなったがそれでも体感的には遅い。
とまぁ、プラグインやアドオンてんこ盛りにしてしまって遅いというならまだしも、デフォ状態でも遅いという話ならばほとんど打つ手なし。早く他のに乗り換えましょう。