web-dev-qa-db-ja.com

大規模サイト向けのメモリ節約キャッシュクリア戦略?

私のDrupal 7サイトには、数千のフィールド、多数のコンテンツタイプ、25を超えるビュー、および数百(間もなく数千になる)のプロファイルタイプがあります。このため、私はエンティティフィールド情報(http://drupal.org/node/1040790)をより適切にキャッシュするコアパッチと、すべてのビューデータを含む1つの巨大なビューキャッシュ行ではなく、表示によってビューをより適切にキャッシュする-devバージョンのビューを使用します。初期化)。

これにより、サイトのほとんどのページが160MB +ではなく20-30MBのRAMを使用してロードされました(10MB +だったフィールドとビューのcache_ *テーブル行をプルアップする代わりに)、パッチが役立ちます。 cache_ *データをより効率的に保持します)。

ただし、キャッシュの再構築に非常に長い時間がかかるという問題があります。通常は1〜2分以上です。そして、この間、Drupalはページをロードしません(読み取りを試みているキャッシュがまだ構築されていないため、他のリクエストは待機する必要があります)。

トラフィックの少ないサイクルでは、これは大した問題ではありません。 100人程度のユーザーは、ページが読み込まれるまで1分間待つ必要があります。しかし、トラフィックの多いサイクルの間、ApacheサーバーはCPU負荷が40以上になり、異常に動き始めます。すべてのワーカースレッドが待機し、メモリを使い果たしてスワップが発生するため、メモリがすぐにいっぱいになります。それは一種の死のスパイラルです。 httpdを再起動すると問題が解消されますが、正常に戻るには5〜10分かかります。

私の目標は、キャッシュをクリアしてサイトをひどく壊さないようにすることです。 1つは、admin_menuの個別のキャッシュクリア機能(「CSSとJS」、「メニュー」、「テーマレジストリ」など)を使用する場合、「ページとその他」オプションを押すまで、問題はスムーズに進みます。これは、ビューのキャッシュがリセットされるとき(キャッシュする必要のあるビューの数を伴う非常にCPUとデータベースを多用する操作)、およびフィールド情報キャッシュがリセットされるとき(このサイトではCPUとデータベースを多用する)です。

だから...私の質問/アイデア:

  • Drushやその他のシェルスクリプトを使用して、「一度にすべてのキャッシュをブラストしてクリーンな再構築を期待する」よりもインテリジェントな方法でキャッシュをクリアすることは可能ですか?
  • キャッシュがクリアされている間にhttpリクエストをブロックして、Apacheが多数のキャッシュスタンプリクエストで詰まらないようにすることはできますか?
  • Drupal /通常のhttpdリクエストの外でキャッシュをクリアできる場合、おそらくキャッシュクリアオペレーションのためにより高いPHP memory_limitを設定し、普遍的なmemory_limitをバックオフすることができます(現在256MBに設定されています。個々のhttpdスレッドがキャッシュをクリアする必要がある場合...).

基本的に:DrupalでUIのボタンをクリックするかdrush cc allを使用する以外に、すべてのキャッシュをクリアするインテリジェントで優雅な方法はありますか?

[明確にするために編集:私が抱えている主な問題は、キャッシュの再構築で、(a)しばらく時間がかかり、(b )再構築が完了するまで、他のすべての要求をブロックします。トラフィックの多い時間帯に再構築が致命的にならないようにする方法を見つけたいと思います。]

29
geerlingguy

UIのボタンをクリックするか、drush cc allを使用する以外に、Drupalですべてのキャッシュをクリアするインテリジェントで優雅な方法はありますか?

キャッシュアクション モジュールがそれを行います。ルールによる。たとえば、タイプ「x」のノードが追加または更新されたときに特定のビューをクリアするルールを設定できます。詳細は docs をご覧ください。

cache graceful モジュールも見てください。まだ試していないが、興味深いようです。

9
uwe

主な問題は、キャッシュデータを格納するためにMySQLを使用していることです。高負荷のサイトの場合、これは非常に非効率的なソリューションです。

代わりに Memcache を使用することをお勧めします。これにより、キャッシュシステムのパフォーマンスが劇的に向上し、2つの大きなメリットが得られます。

  1. Memcacheは、MySQLよりも読み取りおよび書き込み操作がはるかに高速です。すべてのキャッシュ操作(および完全なキャッシュの再構築)はより高速に動作します。
  2. キャッシュデータがDBに保存されなくなったため-キャッシュをクリアしても他のMySQLクエリはブロックされません。

以下は Memcache構成 の例ですDrupal 7。

2
Eugene Fidelin

Drushやその他のシェルスクリプトを使用して、「一度にすべてのキャッシュをブラストしてクリーンな再構築を期待する」よりもインテリジェントな方法でキャッシュをクリアすることは可能ですか?

すべてのキャッシュをブラストしたくない場合は、drush cc type_of_cacheを使用して特定のキャッシュをクリアするか、独自のキャッシュを定義します。

または、すべてのキャッシュのようなテーブルを手動でクリアします。

echo "SHOW TABLES LIKE 'cache%'" | $(drush sql-connect) | tail -n +2 | xargs -L1 -I% echo "DELETE FROM %;" | $(drush sql-connect) -v 

Memcached(Bash構文)を使用している場合は、以下を試してください。

pgrep memcached && echo flush_all > /dev/tcp/127.0.0.1/11211

キャッシュがクリアされている間にhttpリクエストをブロックして、Apacheが多数のキャッシュスタンプリクエストで詰まらないようにすることはできますか?

メンテナンスモード(drush -y vset maintenance_mode 1)を有効にして、サイトへのアクセスを禁止します。または、別の場所にリダイレクトするようにフロントエンドを構成します(例:Varnish、Apacheでリダイレクト、または.htaccessを変更)。

Drupal /通常のhttpdリクエストの外部でキャッシュをクリアできる場合、おそらくキャッシュクリア操作のために、より高いPHP memory_limitを設定し、ユニバーサルmemory_limitをバックオフすることができます。 (現在、個々のhttpdスレッドがキャッシュをクリアする必要がある場合に備えて、256MBに設定しています...)。

キャッシュをクリアしてもメモリは増えませんが、クリア後にキャッシュを再構築すると、さらに多くの時間がかかります。 cronを実行するか、任意のページを開くことで、いつでもキャッシュをウォームアップできます。

time php -n -d memory_limit=-1 time $(which drush) cc registry
PHP_OPTIONS='-d memory_limit="2G"' drush cron
php -d memory_limit=1G ./scripts/drupal.sh http://localhost/

-nを指定してphp.ini処理を無視すると、キャッシュのクリアプロセスをさらに高速化できます。

0
kenorb