Comments
Description
Transcript
Movable Type再構築のチューニングについて
Movable Type再構築のチューニングについて 第1版 2010年06月01日 シックス・アパート株式会社 ! © 2010 Six Apart, Ltd. All rights reserved. • 本資料の記載内容は、できる限り正確を期すよう努めてはおりますが、いかなる明示または暗黙の保証 も責任も負いかねます。 • 本資料の情報は、使用先の責任において使用されるべきものであることを、あらかじめご了承くださ い。 • 掲載情報は不定期に変更されることもあります。他のメディア等に無断で転載する事はご遠慮くださ い。 • 本資料をコピー等で複製することは、執筆者の承諾なしではできません。 • Six Apart、Movable Type、TypePadはSix Aaprt, Ltd.の登録商標です。その他、記載されている製品 名または会社名はそれぞれの各社の商標または登録商標です。 更新履歴 ! 版 日付 1.0.0 2010-06-01 内容 初版 担当 シックス・アパート株式会社 © 2010 Six Apart, Ltd. All rights reserved. 目 次 はじめに 1 1. 再構築とはなにか 2 1-1. ファイル数が増えすぎないようにサイトをデザイン 3 1-2. 再構築の設定を見直す 4 ダイナミックパブリッシングの活用 4 公開キューの活用 5 スケジュールタスクによるワーカープロセスの実行 5 デーモンモードによるワーカープロセスの実行 6 1-3. テンプレートタグの計算処理の最適化 7 テンプレートタグの計算時間の計測 7 サーバーサイドインクルードの活用 サーバーサイドインクルードの利用上の注意 テンプレートモジュールのキャッシュ機能 1-4. データベース (MySQL) のチューニングによる高速化 11 12 mysqltuner.plを利用したチューニング 12 MyISAMとInnoDB 13 2. レスポンスを高めるシステムの設計 14 2-1. システムの構成要素 14 2-2. サーバーの分割によるレスポンスのアップ 15 最初はフロントエンドと管理サーバー データベースサーバーの分割について ! 9 10 15 15 2-3. ウェブキャッシングによるレスポンスのアップ 16 2-4. FastCGIによるCGIスクリプトのレスポンスのアップ 17 2-5. memcachedを利用したデータベースアクセスのレスポンスのアップ 17 参考資料 18 © 2010 Six Apart, Ltd. All rights reserved.! はじめに 導入した当初、気にならなかった再構築の時間が、コンテンツの量の増加に伴い時間がかかり、運用 上無視できなくなったという話をうかがいます。加えて、この再構築の時間に影響され、ウェブの閲 覧のレスポンスが落ちるという現象も発生しているようです。 これらの課題やご要望に対応するには、次の2点を意識したチューニングが必要です。 • スループット: 一定の時間内での処理数 • レスポンス: 処理をリクエストしてから結果を受けとるまでの時間 Movable Typeを導入しているサイトの多くが、ウェブサーバーやデータベースサーバーを1台のハー ドウェアに導入しています。この環境では、Movable Typeのプログラム (例: mt.cgi) は、ローカル接 続のため、データベースサーバーに高速にアクセスできます。ですが、mt.cgiに加えてデータベース サーバーの両方で、1台のハードウェアに負荷がかかります。 この結果、ブログ記事の量が多くなってくると、同じ再構築の処理でもレスポンスが遅くなってしま います。(後述しますが、それだけ再構築の処理は重いのです。) しかし、これらの課題は、ブログを適切に配置する、テンプレートを適切に設計する、インフラ環境 を整備する等のことにより、パフォーマンス問題を解決できます。 本資料では、より快適にMovable Typeをご利用いただくための技術情報をご提供することを目的と しています。 ! © 2010 Six Apart, Ltd. All rights reserved.! 1 1. 再構築とはなにか 普段、何気なく実行している再構築ですが、以下のステップで処理しています。 1. 管理画面で、対象となるブログやアーカイブ (インデックスを含む) を選択します。 2. 選択した内容に基づき、テンプレートやブログの設定情報を、データベースから取得します。 3. データベースから各種データを取得してテンプレートタグを処理し、メモリー上に計算結果を展 開します。 4. 保存するファイル情報をデータベースから取得します。 5. 取得したファイル情報から得たファイルにアクセスし、ファイルの内容を取得します。このファ イルの内容と、メモリー上に展開した計算結果を比較し、更新の有無を確認します。 6. 比較した結果、更新があった場合は、ファイルを書き換えます。 7. 1.で選択した分、2.∼6.を繰り返します。 具体的に、以下の条件のニュースコンテンツ(ブログ)を例に解説します。 【条件】 • 5件/日、5日/週、50週/年のベースで発信し、かつ丸3年間分のコンテンツがあるとします。 • 1日の投稿について、それぞれ異なるカテゴリが指定 (5種類) されているとします。 • すべてのブログ記事は公開されているものとします。 • ウェブページは5件あるとします。 • ブログのテーマは、クラシックブログとします。 この条件を1つのブログで構成している場合、インデックスならびに各種アーカイブの件数は、以下 のようになります。 • インデックス: 6件 • ブログ記事アーカイブ: 3750件 • カテゴリアーカイブ: 5件 • 日付 (月別) アーカイブ: 36件 • ウェブページアーカイブ: 5件 前述のように、再構築の際には、ファイルの内容について更新の有無を確認します。この条件で「す べてを再構築」した場合、約3800回も繰り返し処理が発生することがわかります。 加えて、注意しなければいけない点は、カテゴリアーカイブや日付アーカイブの処理です。 カテゴリアーカイブは、指定されたブログ内で公開済みのすべてのブログ記事を対象に、カテゴリ・ サブカテゴリの数だけファイルを生成します。実質的には、すべてのブログ記事を確認するといって も過言ではありません。この結果、特定のカテゴリが指定されているブログ記事が多かったり、カテ ゴリの数が多いと、生成に時間がかかってしまいます。 日付アーカイブは、指定されたブログ内で公開済みのすべてのブログ記事を対象に、ブログ記事の数 だけ生成処理を繰り返します。繰り返し処理では、日付アーカイブがすでに作成されている場合は、 次の処理に遷移しますが、ブログ記事の数だけ繰り返し処理を実行するため、ブログ記事が多いと、 生成に時間がかかってしまいます。 ! © 2010 Six Apart, Ltd. All rights reserved.! 2 これらより、再構築は、避けることができない以下の特性があるといえます。 • 再構築は、データベースやファイルシステムへのアクセスが多い。 • 1つのブログにブログ記事が増えるに従い、カテゴリアーカイブや日付アーカイブの作成負荷が 高まり、処理時間がかかってしまう。 これらを踏まえた上で、パフォーマンス問題が発生しないようにするには、以下の視点で最適化をは かっていきます。 • 1つのブログ内のファイル数が増えすぎないように、サイトをデザインする。 • 再構築の設定を見直す。 • テンプレートタグの計算処理を最適にする。 • データベースからの取得をより高速にする。 • ファイルの書き込みをより高速にする。 1-1. ファイル数が増えすぎないようにサイトをデザイン 企業のウェブサイトをMovable Typeで構築する場合、ナビゲーションや構成要素が異なることあ り、複数のウェブサイトやブログに分割して構築しています。たとえば、前述のニュースサイトでは、 サイトURLがhttp://www.example.com/news/となるブログにまとめるのが一般的です。 前述のニュースサイトを、以下のように設定を変更してみましょう。 • サイトURLがhttp://www.eample.com/news/となる、ウェブサイトを作成します。 • 当該ウェブサイトの下に、年単位でブログ(例: http://www.example.com/news/2010/)を作成し ます。 • 年単位で作成したブログのメインページ(index.html)では、当該ブログのすべての公開記事の一 覧を出力します。 • ウェブサイトのメインページ(index.html)に、最新の年のブログを対象公開記事の一覧(最近の公 開記事5件等)を出力します。 この方法では、各ブログのデザインを共通のテーマで管理できるため、年単位でかつカテゴリ別にブ ログを分割できます。また、カテゴリアーカイブや日付アーカイブを作成しないように設定できま す。 アクセス頻度が少なく、再構築の負荷が高いカテゴリアーカイブや日付アーカイブの作成と、ブログ 内のファイル数も抑えることで、再構築の負荷を軽減しかつ拡張性ならびにメンテナンス性の高いサ イトになります。 ! © 2010 Six Apart, Ltd. All rights reserved.! 3 1-2. 再構築の設定を見直す テンプレートを使用してファイルを出力する方法(再構築オプション)には以下のものがあります。 名称 解説 スタティック 再構築実行時にファイルを作成します。 公開キュー経由 再構築実行時にはファイルは作成せずに、公開キュー という処理待ち行列に登録します。スケジュールタス クが起動した際に、登録された公開キューの内容にあ わせてファイルを作成します。 ダイナミック 再構築実行時にはファイルは作成せずに、当該ファイ ル(URL)にアクセスがあったときに、ファイルを作成 します。 手動 [保存と再構築]ボタンをクリックした際に作成しま す。通常の再構築実行時には作成しません。 初期の設定では、すべてが[スタティック]出力の設定になっています。この設定を、以下のように変更 することで、再構築時の負荷を軽減できます。 • スタイルシートやJavaScript、RSDの各インデックステンプレートは、更新頻度は低いため、[手 動]オプションを選択します。 • 前述のブログの分割ができない環境では、日付アーカイブやカテゴリアーカイブについて、[公開 キュー経由]もしくは、[ダイナミック]を選択します。 また、必要以上に、アーカイブを作成しないことも重要です。 ダイナミックパブリッシングの活用 通常、ウェブサーバーは存在しないURLへのアクセスがあった場合、404エラーを出力します。ダイナ ミックパブリッシングは、この404エラーが発生するタイミングに、当該ページを生成する技術です。 ダイナミックパブリッシングを利用する場合、以下の環境が必要となります。 • PHP 5.x 以上が導入されていること。 • ウェブサーバーにApacheを利用している場合、.htaccessが利用可能(AllowOverrideについてall を設定可能なこと。 • ウェブサーバーに、Movable Typeがインストールされており、かつデータが格納されている データベースに直接アクセスが可能なこと。 ダイナミックパブリッシングの設定方法は、以下のURLを参照してください。 http://www.movabletype.jp/documentation/supporting_dynamic_publishing.html ! © 2010 Six Apart, Ltd. All rights reserved.! 4 公開キューの活用 ダイナミックパブリッシングには、前述の環境が必要であったり、アクセスのたびにページを作成す ることから発生するレスポンスの遅延といった制約事項があります。 反面、公開キューは、ファイルの出力のタイミングが、再構築ボタンのクリック時と異なる点を除 き、出力した内容はスタティックのそれと変わりません。また、公開キューの実行は、指定日公開と 同様にスケジュールタスクで制御できるだけでなく、別のサーバーで処理することもできます。 これらより、公開キューを活用することは、再構築の負荷を分散するという目的で注目されていま す。 公開キューは、TheSchwartzというキューイングシステムを利用し、「あとで処理する」「まとめて 処理する」といった非同期型の処理で公開します。TheSchwartzは、Movable Typeをインストール した際に、あわせてインストールされます。公開キューは、次の2つの要素に大別できます。 キュー 再構築ジョブ(処理)。タスク管理システムでいうタス クであり、作業の対象を定義します。キューは、 Movable Typeのデータベースに保存されます。 ワーカー 再構築ジョブを実行するプロセス。後述するタイミン グに、データベースに保存されたキューを所得し、再 構築を実施します。 また、ワーカープロセスが、データベースにアクセスしてキューを取得するタイミングには、以下の ものがあります。 1. スケジュールタスクが実行されたタイミング 2. デーモンモードで一定の時間間隔で実行 されたタイミング スケジュールタスクによるワーカープロセスの実行 スケジュールタスクとは、一定の時間間隔で実行される処理のことをいいます。Moable Typeの代表 的なスケジュールタスクには以下のものがあげられます。 • ブログ記事の指定日公開 • 期限が過ぎたログインセッション情報の整理 スケジュールタスクは、toolsディレクトリ内のrun-periodic-tasksスクリプトを、OSの定期実行機能 であるcron(Linux)やタスク・スケジューラ(Windows)を経由で実行することで処理されます。スケ ジュールタスクの実行方法の詳細は、以下のURLを参照してください。 http://www.movabletype.jp/documentation/schedule_task_framework.html run-periodic-tasksを実行すると、ワーカープロセス以外のタスク(例:指定日公開)を実施した後に、 ワーカプロセスを処理します。 例: 5分間隔でcronを実行させる場合 # crontab -‐e */5 * * * * cd /var/www/cgi-‐bin/mt; ./tools/run-‐periodic-‐tasks 1>/dev/null 2>&1 ! © 2010 Six Apart, Ltd. All rights reserved.! 5 デーモンモードによるワーカープロセスの実行 run-periodic-tasksは、デーモンモードでも動作することができます。デーモンモードで実行すると、 以下の特長から、コメントが多いサイトや、ページ数の多いサイトにおいて、再構築の負荷を分散で きます。 • 複数のデーモンを同一のサーバーで実行できます。 • mt.cgiが動作するサーバーとは別のサーバーで実行できます。 デーモンモードで実行するには、run-periodic-tasksに以下のオプションを指定します。 --daemon デーモンモードで動作する際に指定します。 --sleep=<秒> デーモンの休止時間です。指定した時間間隔でワー カープロセスを実行します。指定しなかった場合は、 5秒となります。 --load=<数> 1回の実行で処理するキューの数を指定します。指定 しなかった場合は、10件となります。 --verbose ワーカープロセスを実行した際に、処理した内容をコ ンソールに表示します。 --randomly 複数のデーモンを動作させる際に、衝突を低減するた めに指定します。複数のデーモンを動作させない場合 は、指定しません。 --scoreboard=<dir> 開発者向けのオプションです。通常は指定しません。 --leak 開発者向けのオプションです。Devel::Leak::Objectモ ジュールがインストールされている必要があります。 例: 10秒間隔で実行させる場合 # /var/www/cgi-‐bin/mt # ./tools/run-‐periodic-‐tasks -‐-‐verbose -‐-‐daemon -‐-‐sleep=10 & Working on MT::Worker::SummaryWatcher ... TheSchwartz::work_once got job of class 'MT::Worker::Publish', priority 2 Working on MT::Worker::Publish ... Publishing /var/www/htdocs/blog/2010/05/index.html, priority 2 Publishing /var/www/htdocs/blog/2010/04/index.html, priority 2 -‐-‐ 完了 (2ファイル -‐ 0.96秒) TheSchwartz::work_once found no jobs ! © 2010 Six Apart, Ltd. All rights reserved.! 6 1-3. テンプレートタグの計算処理の最適化 前述のように再構築処理の中で、更新の有無を確認するために、ファイルの内容とテンプレートタグ の計算結果を比較します。この比較処理の最適化には、以下のようにテンプレートをデザインしてい きます。 • 計算をより速くするようにテンプレートデザインを見直す • サーバーサイドインクルードの活用で比較する内容をより小さくする • キャッシュの活用で再計算を早くする テンプレートタグの計算時間の計測 計算をより速くするデザインにするためには、どれくらい時間がかかっているかを計測する必要があ ります。Movable Typeには計測のためのソフトウェアを標準で提供しています。それが、toolsディ レクトリ内にあるmt-tmpl-testです。 mt-tmpl-testは、Linuxのターミナルなどの標準出力に、テンプレートタグの計算結果を出力します。 また、どのテンプレートタグが何回実行されたのか、SQLの発行回数や経過時間等も出力できます。 mt-tmpl-testを実行するには、Text::SimpleTableというperlモジュールをインストールする必要があ ります。また、以下のパラメータを組み合わせて実行します。 ! --blog=<id> ブログのID(数値)またはブログ名を指定します。 --template=<id> テンプレートのID(数値)またはテンプレート名を指定 します。 --category=<id> カテゴリのID(数値)またはカテゴリ名を指定します。 --entry=<id> ブログ記事のID(数値)またはブログ記事のタイトルを 指定します。 --author=<id> ユーザーのID(数値)またはユーザー名を指定します。 --archive=<type> 作成するアーカイブ種別を指定します。 --profile テンプレートタグの実行回数や、SQLの発行回数や経 過時間等の各種プロファイル情報を表示します。 --debug=<mode> 環境変数DebugModeと同様に、デバッグモードを指 定します。 --stdout 実行時間のみを表示する場合に指定します。 © 2010 Six Apart, Ltd. All rights reserved.! 7 例: ブログID:2 テンプレートID:80 ブログ記事(エントリー)ID:6 の場合 # /var/www/cgi-‐bin/mt # ./tools/mt-‐tmpl-‐test -‐-‐blog=2 -‐-‐template=80 -‐-‐entry=6 -‐-‐profile <-‐-‐ 計算結果を出力 -‐-‐> Template Tag Utilization: .-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐+-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐+-‐-‐-‐-‐-‐-‐-‐-‐+-‐-‐-‐-‐-‐-‐-‐-‐-‐+-‐-‐-‐-‐-‐-‐-‐-‐+-‐-‐-‐-‐-‐-‐-‐-‐+-‐-‐-‐-‐-‐-‐-‐. | Time | Tag | Calls | Avg | SQL | Hits | Miss | +-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐+-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐+-‐-‐-‐-‐-‐-‐-‐-‐+-‐-‐-‐-‐-‐-‐-‐-‐-‐+-‐-‐-‐-‐-‐-‐-‐-‐+-‐-‐-‐-‐-‐-‐-‐-‐+-‐-‐-‐-‐-‐-‐-‐+ | 0.121 | include | 22 | 0.005 | 19 | 10 | 9 | | 0.042 | link | 6 | 0.007 | 11 | 12 | 5 | | 0.040 | widgetset | 2 | 0.020 | 14 | 14 | 12 | | 0.023 | entryprevious | 1 | 0.023 | 2 | 1 | 1 | | 0.022 | entrytrackbackdata | 4 | 0.005 | 5 | 11 | 4 | | 0.019 | entrypermalink | 4 | 0.005 | 3 | 16 | 2 | | 0.017 | pages | 4 | 0.004 | 2 | 0 | 0 | | 0.017 | ifarchivetypeenabled | 6 | 0.003 | 9 | 6 | 3 | | 0.016 | archivetypelabel | 1 | 0.016 | 0 | 0 | 0 | | 0.015 | entrycategories | 4 | 0.004 | 2 | 4 | 1 | | 0.011 | categoryarchivelink | 9 | 0.001 | 1 | 28 | 0 | | 0.010 | * encode_html | 5 | 0.002 | 0 | 0 | 0 | | .... | '-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐+-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐+-‐-‐-‐-‐-‐-‐-‐-‐+-‐-‐-‐-‐-‐-‐-‐-‐-‐+-‐-‐-‐-‐-‐-‐-‐-‐+-‐-‐-‐-‐-‐-‐-‐-‐+-‐-‐-‐-‐-‐-‐-‐' Total Queries: 90 Total Build Time: 0.490541 .-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐+-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐. | Query | Number | +-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐+-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐+ | RAMCACHE_GET ? | 138 | | RAMCACHE_ADD ? | 41 | | SELECT template_id, template_blog_id, template_build_dynamic, t-‐ | 14 | | emplate_build_interval, template_build_type, template_created_b-‐ | | | y, template_created_on, template_identifier, template_linked_fi-‐ | | | le, template_linked_file_mtime, template_linked_file_size, temp-‐ | | | late_modified_by, template_modified_on, template_name, template-‐ | | | _outfile, template_rebuild_me, template_text, template_type, te-‐ | | | mplate_current_revision FROM mt_template WHERE (template_id IN -‐ | | | (?)) | | | .... | '-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐+-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐' これは、ある環境におけるクラシックブログのブログ記事アーカイブの出力の結果で、以下の傾向が わかります。 • Total Build Timeの値が約0.49秒と出力されている。 • mt:includeが22回実行されているが、平均処理時間はさほど大きくない。 • mt:widgetsetや、mt:entryprevious、mt:archivetypelabelの処理時間がかかっている。 • RAMCACHE_GETやRAMCACHE_ADDがqueryの中で多く使われている。 このように、mt-tmpl-testを実行すると、何気なく使っているテンプレートタグの計算時間や処理の 重さがわかります。たとえば、複数使われるファンクションタグを変数にしたり、mt:widgetsetでな くてもよい要素を、mt:includeで置き換えることで、計算処理の時間を短縮できます。 ! © 2010 Six Apart, Ltd. All rights reserved.! 8 サーバーサイドインクルードの活用 サーバーサイドインクルードは、HTMLファイル内の組み込みコマンドを、ブラウザからのリクエス トの際に実行し、その結果を組み込みコマンドの場所に適用してからブラウザに出力する技術です。 本技術を活用することによって、フッダー部分のように共通の要素を一つのファイルに整理し、それ をすべてのページで表示するといったことができます。 Movable Typeでは、更新の確認のために、テンプレートタグの計算結果と実際のファイルの内容を 比較します。サーバーサイドインクルードを活用し、計算結果をより小さくすることで、再構築の負 荷の軽減を見込めます。 従来のバージョンでは、共通の要素をインデックステンプレートにまとめ、組み込みコマンドを他の テンプレートの適用するという方法が使われていました。これは現在でも有効な方法ですが、テンプ レートモジュールを設定することで、より簡単にサーバーサイドインクルードを利用できます。 Movable Type 5で対応しているサーバーサイドインクルードの技術には以下のものがあります。 • ApacheのSSI • PHPのインクルード • ASPのインクルード • JSPのインクルード テンプレートモジュールの計算結果を、サーバーサイドインクルードインクルードとして利用するに は、以下を設定してください。 1. ウェブサーバーについて、サーバーサイドインクルードが利用できるように設定してください。 2. 適用したいウェブサイトもしくはブログに対して、サーバーサイドインクルードを利用する設定 をします。 3. 適用したいテンプレートモジュールについて、サーバーサイドインクルードの指定をします。 「ApacheのSSI」を採用した場合、拡張子が.shtmlのファイルがサーバーサイドインクルードの対象 となります。明示的にせず、拡張子.htmlのファイルでもサーバーサイドインクルードの対象とする場 合は、以下の設定が必要となる場合があります。 AddType text/x-‐server-‐parsed-‐html .shtml .html Options Includes ウェブサイトやブログに対して、サーバーサイドインクルードを利用できるようにするには、[設定][全般]を開いていただき、モジュール設定の「サーバーサイドインクルード」の項のリストから選択 し、設定を保存してください。 また、適用したいテンプレートモジュールに対しては、テンプレートモジュールの変種画面で、 「サーバーサイドインクルード」の項のチェックボックスをチェックし、設定を保存してください。 たとえば、以下のテンプレートモジュールを、PHPのInclude形式で出力するように設定します。 <mt:Entries limit="3" sort_by="created_on" sort_order="descend"> <mt:If name="__first__" ><ul></mt:If> <li><mt:EntryTitle escape="html" /> <mt:If name="__last__" ></ul></mt:If> </mt:Entries> ! © 2010 Six Apart, Ltd. All rights reserved.! 9 このモジュールをmt:Includeで読み込むように設定すると、以下のように出力されます。 例: mt:Includeタグ <mt:Include module="demo-‐ssi" ssi="1" /> 例: 出力結果 <?php include("/var/www/htdocs/site01/blog01/includes_c/demo-‐ssi.html") ?> このように、サーバーサイドインクルードの設定をすることで、計算結果をより小さくなり、再構築 の負荷の軽減を見込めます。サーバーサイドインクルードの設定の詳細は、以下のURLを参照願いま す。 http://www.movabletype.jp/documentation/server-side-includes.html サーバーサイドインクルードの利用上の注意 サーバーサイドインクルードを利用する上で、最も意識しなければいけないことは、インクルード ファイルをテンプレートモジュールから作成するタイミングにあります。 前述のように再構築の際に、テンプレートタグの計算結果から更新の有無を確認します。確認の結 果、ファイルを更新する場合は、インクルードファイル自身も更新される点に注意してください。イ ンクルードファイルを更新しないようにするには、後述の「キャッシュ」機能も一緒に利用してくだ さい。 また、サーバーサイドインクルードを活用すると、 組み込みコマンドの有無の確認により、PHPの利 用と同様にサーバーの負荷が増える点にも注意してください。 ! © 2010 Six Apart, Ltd. All rights reserved.! 10 テンプレートモジュールのキャッシュ機能 キャッシュ機能は、テンプレートタグの計算結果を、一定期間キャッシュに格納しておき、テンプ レートタグの計算時間を短縮するものです。キャッシュに格納する期間の指定には以下のものがあり ます。 • 指定した有効期間(日、時、分)まで有効とする。 • ブログ記事やコメントなどの各種オブジェクトが新規に作成されたり、更新されたタイミングま で有効とする。 キャッシュ機能を利用するメリットは、条件にもよりますが、半分程度まで計算時間を削減できる点 にあります。様々な場所で表示されるアーカイブの一覧や最新のブログ記事の一覧などは、キャッ シュ機能を活用した方がよいかもしれません。 また、通常キャッシュは、Movable Typeのデータベース内に一種のセッション情報として格納され ますが、より高速なmemcachedに格納することもできるため、一層の高速化を期待できます。 テンプレートモジュールの計算結果を、キャッシュとして利用するには、以下を設定してください。 1. 適用したいウェブサイトもしくはブログに対して、キャッシュ機能を利用する設定をします。 2. 適用したいテンプレートモジュールについて、キャッシュの条件を指定します。 mt:Includeでキャッシュを有効にするには、以下のように記述します。ttlは、キャッシュの有効期間 を秒単位で指定します。また、keyは、キャッシュを取得するための一意的な名前になります。 例: 有効期間: 60分 (初期値)を指定 <mt:Include module="demo-‐cache" cache="1" /> 例: 有効期間: 24時間を指定 <mt:Include module="demo-‐cache" cache=”1” ttl="86400" /> 例: 有効期間: 24時間、KEYを指定 <mt:Include module="demo-‐cache" cache="1" ttl=”86400” key=”demo” /> なお、キャッシュ機能の設定の詳細は、以下のURLを参照願います。 http://www.movabletype.jp/documentation/module-caching.html ! © 2010 Six Apart, Ltd. All rights reserved.! 11 1-4. データベース (MySQL) のチューニングによる高速化 今までは、Movable Type自身の設定のみで、再構築の最適化をはかってきました。次にデータベー スの設定を見直し、最適化をはかっていくこととしましょう。 Movable Typeでは、利用状況にもよりますが、データベースからの読み込みが圧倒的に多いアプリ ケーションです。すなわち、読み込みのレスポンスをどれだけ早くするかが、パフォーマンスの最適 化につながります。 mysqltuner.plを利用したチューニング 実際にチューニングをする際に、どのように変数をチューニングしてよいか、わからない点も多いか と思います。比較的簡単にチューニングを支援するツールがmysqltuner.plです。mysqltuner.plは、 Perl ベースのソフトウェアで、MySQLの状態から変更した方が望ましい変数を報告するものです。 mysqltuner.plは以下のURLからダウンロードできます。 http://blog.mysqltuner.com/ Movable Typeをインストールしたサーバー機に当該プログラムをアップロードした後に、SSH等で ログインして実行します。実行した結果、Recommedationの項に書かれている変数を修正します。修 正した後は、MySQLを再起動することを忘れずに実行してください。 なお、mysqltuner.plは、あくまでもツールの1つであるため、定期的な確認が必要です。 ! © 2010 Six Apart, Ltd. All rights reserved.! 12 >> MySQLTuner 1.1.1 -‐ Major Hayden <[email protected]> >> Bug reports, feature requests, and downloads at http://mysqltuner.com/ >> Run with '-‐-‐help' for additional options and output filtering [!!] Successfully authenticated with no password -‐ SECURITY RISK! -‐-‐-‐-‐-‐-‐-‐-‐ General Statistics -‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐ [-‐-‐] Skipped version check for MySQLTuner script [OK] Currently running supported MySQL version 5.0.82sp1-‐log [OK] Operating on 32-‐bit architecture with less than 2GB RAM -‐-‐-‐-‐-‐-‐-‐-‐ Storage Engine Statistics -‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐ [-‐-‐] Status: -‐Archive -‐BDB -‐Federated +InnoDB -‐ISAM -‐NDBCluster [!!] InnoDB is enabled but isn't being used [OK] Total fragmented tables: 0 -‐-‐-‐-‐-‐-‐-‐-‐ Security Recommendations -‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐ ERROR 1142 (42000) at line 1: SELECT command denied to user ''@'localhost' for table 'user' [OK] All database users have passwords assigned -‐-‐-‐-‐-‐-‐-‐-‐ Performance Metrics -‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐ [-‐-‐] Up for: 166d 17h 37m 3s (127M q [8.840 qps], 2M conn, TX: 3B, RX: 2B) [-‐-‐] Reads / Writes: 98% / 2% [-‐-‐] Total buffers: 314.0M global + 10.2M per thread (128 max threads) [OK] Maximum possible memory usage: 1.6G (79% of installed RAM) [OK] Slow queries: 0% (206/127M) [OK] Highest usage of available connections: 57% (74/128) [!!] Cannot calculate MyISAM index size -‐ re-‐run script as root user [OK] Query cache efficiency: 57.7% (66M cached / 116M selects) [!!] Query cache prunes per day: 174834 [!!] Sorts requiring temporary tables: 52% (807K temp sorts / 1M sorts) [OK] Temporary tables created on disk: 0% (16K on disk / 3M total) [OK] Thread cache hit rate: 98% (41K created / 2M connections) [!!] Table cache hit rate: 13% (128 open / 924 opened) [OK] Open file limit used: 4% (45/1K) [OK] Table locks acquired immediately: 99% (51M immediate / 51M locks) -‐-‐-‐-‐-‐-‐-‐-‐ Recommendations -‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐ General recommendations: Add skip-‐innodb to MySQL configuration to disable InnoDB Enable the slow query log to troubleshoot bad queries Increase table_cache gradually to avoid file descriptor limits Variables to adjust: query_cache_size (> 16M) sort_buffer_size (> 4M) read_rnd_buffer_size (> 4M) table_cache (> 128) MyISAMとInnoDB MySQLは、複数のストレージエンジン(データの保存形式)に対応しており、その代表的なものに MyISAMとInnoDBがあります。MyISAMはトランザクション機能は利用できませんが、InnoDBより 高速に処理するといわれています。 実際に、Movable Typeで両方のストレージエンジンで比較したところ、InnoDBの方が若干早いとい う結果がでています。 ! © 2010 Six Apart, Ltd. All rights reserved.! 13 2. レスポンスを高めるシステムの設計 Movable Typeのシステムを構成する各要素について、最適化の話をすすめてきました。これからは サイト全体のレスポンスを高めていくための設計ならびに設定について解説します。 2-1. システムの構成要素 通常、Movable Typeは1台のサーバーに収容して利用していますが、機能的には以下の要素に整理で きます。 フロントエンド ウェブサーバー ファイルサーバー コメント サーバー 管理サーバー 公開キュー サーバー データベース サーバー 名称 ! 解説 フロントエンド・ウェブサーバー サイトの訪問者がアクセスするウェブサーバーです。 Movable Typeが生成したコンテンツを配信します。 ファイルサーバー Movable Typeが生成したコンテンツが出力される先 になります。フロントエンド・ウェブサーバーがアク セスするコンテンツは、ファイルサーバー上にありま す。 コメントサーバー フロントエンド・ウェブサーバーと連携して動作する サーバーで、コメントやトラックバック、検索等を処 理します。また、コミュニティ機能のフロントエンド として動作します。 管理サーバー Movable Typeがインストールされたサーバーで、ブ ログ記事の投稿や、各種管理を実行します。 また、生成したコンテンツはファイルサーバーに対し て出力します。 データベースサーバー Movable Typeのデータが格納されたサーバーです。 コメントサーバーや管理サーバーがアクセスします。 公開キューサーバー 公開キューを処理するサーバーです。 © 2010 Six Apart, Ltd. All rights reserved.! 14 2-2. サーバーの分割によるレスポンスのアップ 前述の各要素について、異なるハードウェアに分割することで、レスポンスのアップが見込めます。 最初はフロントエンドと管理サーバー 最初は、フロントエンド・ウェブサーバーと管理サーバーを別のサーバーに分割します。再構築中の 負荷によるレスポンスの低下を、フロントエンド・ウェブサーバーにかけないという効果が得られま す。 また、管理サーバーをステージング環境として出力し、rsync、robocopy 等でフロントエンド・ウェ ブサーバーに配信することもできます。この結果、複数のフロントエンド・ウェブサーバーをロード バランサーで配置するということもできるため、大量のウェブアクセスがあるサイトには向いていま す。 データベースサーバーの分割について データベースサーバーの分割は、管理サーバーの負荷が無視できなくなるほど、大量の再構築が発生 するまで考える必要はありません。これには以下の理由があるためです。 • 再構築のとき以外、データベースへのアクセスが重くなることは少なく、通常はほとんどCPUパ ワーを使わない。 • ネットワーク経由の接続の方が、ローカル接続より遅延が発生する。 ! © 2010 Six Apart, Ltd. All rights reserved.! 15 2-3. ウェブキャッシングによるレスポンスのアップ 画像やスタイルシート、JavaScriptは更新の頻度が低いため、ウェブサーバーの設定をチューニング することで、レスポンスをあげることができます。 ExpiresActive on <FilesMatch "\.(css|js)$"> ExpiresDefault "access plus 24 hours" </FilesMatch> <FilesMatch "\.(gif|jpe?g|png)$"> ExpiresDefault "access plus 24 hours" </FilesMatch> 前述の内容を、Apacheウェブサーバーに設定すると、HTTPヘッダーExpiresに有効期限(本例ではア クセスしてから24時間)が設定されます。この有効期限の間は、同じファイルにアクセスした場合304 ステータスコードがもどってくるため、よりレスポンスが早くなります。 例: 最初のアクセス (Status-‐Line) HTTP/1.1 200 OK Date Tue, 01 Jun 2010 09:32:26 GMT Server Apache/2.2.15 (Unix) mod_ssl/2.2.15 OpenSSL/0.9.8e-‐fips-‐rhel5 DAV/2 PHP/ 5.3.0 Last-‐Modified Mon, 15 Mar 2010 01:53:14 GMT Etag "3813f-‐55-‐481cd24e35680" Accept-‐Ranges bytes Content-‐Length 85 Cache-‐Control max-‐age=86400 Expires Wed, 02 Jun 2010 09:32:26 GMT Connection close Content-‐Type image/gif 例: 2回目のアクセス (Status-‐Line) HTTP/1.1 304 Not Modified Date Tue, 01 Jun 2010 09:34:16 GMT Server Apache/2.2.15 (Unix) mod_ssl/2.2.15 OpenSSL/0.9.8e-‐fips-‐rhel5 DAV/2 PHP/ 5.3.0 Connection close Etag "3813f-‐55-‐481cd24e35680" Expires Wed, 02 Jun 2010 09:34:16 GMT Cache-‐Control max-‐age=86400 また、フロントエンド・ウェブサーバーの前段にキャッシュサーバーを配置することでも向上しま す。 ! © 2010 Six Apart, Ltd. All rights reserved.! 16 2-4. FastCGIによるCGIスクリプトのレスポンスのアップ mt.cgiをはじめにMovable Typeのプログラムは、CGIスクリプトの形態を持っています。 これらのプログラムは、アクセスした度に起動しますが、起動時に環境設定ファイルmt-config.cgiの 読み込みや、データベースとの接続等を都度実行します。この結果、アクセス頻度が多い場合は起動 処理が都度実行されるために、レスポンスが遅れたりします。 FastCGIは、CGIとして呼び出された際にApacheとは別プロセスとして起動し、処理が終了した後で も一定の期間処理を終了することなく、次のCGIへのアクセスを待ちます。アクセスがあった時に同 じプロセスを使い回す事で、起動処理のオーバーヘッドが無くなり、レスポンスが上がります。 このように、FastCGIは管理画面やコミュニティサイトへのアクセスが多いサイトでは有効な技術で す。FastCGIの設定方法は、以下のURLを参照願います。 http://www.movabletype.jp/documentation/developer/server/fastcgi.html 2-5. memcachedを利用したデータベースアクセスのレスポンスのアップ 一般的なサイトでは、 導入をするメリットはありませんが、 前述したように、テンプレートの キャッシュ機能やデータベースアクセスのレスポンスの向上を実現するための技術としてmemcached があります。 memcachedは、データベースへのアクセス頻度が多い大規模サイトでの利用を推奨します。 ! © 2010 Six Apart, Ltd. All rights reserved.! 17 参考資料 MySQLのチューニングやシステム構成を検討する上で、以下の書籍は参考になります。 • エンジニアのためのMySQL運用管理大全 (技術評論社) • 実践ハイパフォーマンスMySQL 第2版 (オライリー) • [24時間365日] サーバ/インフラを支える技術 (技術評論社) ! © 2010 Six Apart, Ltd. All rights reserved.! 18