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


30

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

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

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

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

私の目標は、キャッシュをクリアしてもサイトがひどくならないようにすることです。たとえば、admin_menuの個々のキャッシュクリア機能(「CSS and JS」、「Menu」、「Theme registry」など)を使用すると、「Page and else」オプションを押すまでスムーズに進みます。それは、ビューのキャッシュがリセットされるとき(キャッシュする必要があるビューの数を含む非常にCPUとデータベースに負荷がかかる操作)、およびフィールド情報キャッシュがリセットされるときです(このサイトでもCPUとデータベースに負荷がかかります)。

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

  • ブラシや他のシェルスクリプトを使用して、「すべてのキャッシュを一度に爆発させ、クリーンな再構築を期待する」よりも賢い方法でキャッシュをクリアすることは可能ですか?
  • キャッシュのクリア中にhttpリクエストをブロックして、Apacheが大量のキャッシュスタンプリクエストで詰まらないようにできますか?
  • Drupal /通常のhttpdリクエスト以外でキャッシュをクリアできる場合、おそらくキャッシュクリア操作に高いPHP memory_limitを設定し、ユニバーサルmemory_limitを元に戻すことができます(個々のhttpdスレッドがキャッシュをクリアする必要がある場合は、現在256MBに設定されています) ...)。

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

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


2
興味深い質問。キャッシュを無効にした場合、サイトのパフォーマンスは適切ですか?IOW、Apache / PHP / MySQLを最適化して、キャッシュなしでも実行できるようにしましたか?明らかに、システムを見たことはありませんが、apc.stat = 0を設定し、APCに十分なメモリがあることを確認すると、ディスク使用量を削減できます。mysqltuner.plを使用すると、MySQLがボトルネックであるかどうかもわかります。次に、キャッシュをオンにして微調整できます(DBの使用量が増加するため、MySQLパラメーターを調整する必要がある場合があります)。
mpdonadio

Redis(memcacheに類似)を使用して、ビューキャッシュテーブルをメモリに保持します。これにより、ロード時間が大幅に改善されました。安定したリリースで「ディスプレイごとのビューキャッシュ」機能を使用することを楽しみにしており、それは非常に理にかなっています。
-uwe

@MPD-キャッシュを無効にすると、サイト全体がすぐに停止します。通常は100〜500人の認証済みユーザーであり、サイトの一部のセクションはかなり重いです。私にとって最大の問題はキャッシュ読み取りではありません(そのためにMemcached、Redis、およびAPCユーザーキャッシュを試しました)。
geerlingguy

理想的には、新しいキャッシュの再構築中に古いキャッシュデータを使用する必要があります。これは正しいです?
mikeytown2

@ mikeytown2-正しい-それが理想です。
geerlingguy

回答:


9

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

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

キャッシュの優雅なモジュールも見てください-まだ試していませんが、面白そうです。


私はすでにdrush cc [type]特定のキャッシュクリアに使用しています(キャッシュアクションに似ています)が、キャッシュをより適切にクリアする方法を見つけ、他のhttpdスレッドがApacheサーバーを強制終了しないようにすることに興味があります。
-geerlingguy

1
drush ccはすべてのビューキャッシュをクリアするようです。キャッシュアクションを使用すると、特定のビューまたは表示をクリアできます。ビューの開発バージョンにはおそらくバグがあるでしょう。そうでなければ、キャッシュを再構築するのに1、2分はかかりません。ビュー7.x-3.5を使用しても同じ問題がありますか?また、見とるdrupal.org/project/cache_gracefulを -まだ試していないが、面白そうだ
ウヴェ・

Views devは、キャッシュ読み取りパフォーマンスを支援するために、ビュー表示を独自のキャッシュ行に分割します。これは、ビューがキャッシュの構築におそらく5倍の時間を費やすことを意味します(ただし、キャッシュを読み取る際のメモリ使用量の削減に役立ちます!)。
geerlingguy

Cache Gracefulに関する情報を元の回答に追加していただけますか?その特定のモジュールが少し役立つので、私はそれを受け入れます(しかし、私のために問題を完全に解決するわけではありません)。本当に問題を解決するために、より少ないフィールドとエンティティタイプを使用するために、サイトを少し再設計する必要があると思います。
geerlingguy

OK。cache_gracefulでのあなたの経験について聞いてみたいです。どの部分が修正されなかったのですか?
-uwe

2

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

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

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

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


私はmemcachedとAPCの両方をさまざまな方法で使用しましたが、これらはキャッシュの読み取りを大幅に支援しますが、主な問題は実際の再構築です。(非常に遅い/長い)再構築プロセス中にWebサーバーがキャッシュにスタンプを付けている間、データベースはほとんど何もしていません。
-geerlingguy

APCとMemcachedは異なるものを作成します。Memcachedを正しく構成すると役立つと思います。ところで、あなたのサイトが主に匿名ユーザーによって訪問されている場合-Varnishを使用できます。この場合、Varnishは独自のキャッシュシステムを使用し、Apacheは匿名リクエストに対して実行されません。
ユージンフィデリン

サイトの認証トラフィックはほぼ100%です。それ以外の場合は、ワニスの使用を検討します。この時点でCache Gracefulモジュールを検討するかもしれません。
geerlingguy

0

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

すべてのキャッシュ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リクエスト以外でキャッシュをクリアできる場合は、おそらくmemory_limitキャッシュクリア操作に高いPHP を設定し、ユニバーサルをバックオフ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ます。


-1

潜在的に金銭的なコストがかかりますが、Varnishのようなキャッシュサーバーのセットアップを使用できます。利点は、ユーザーが賢くなくても、実稼働サーバーでキャッシュがクリアされている間、ワニスがサイトを提供することです。

欠点:実稼働サーバーのダウンタイムの秒/分とVCLタイムアウト設定に応じて、その間にVarnishが更新され、Varnish 503エラー画面が表示されます。

しかし、このアプローチとRedisまたはMemcacheが役立つ場合があります。


この質問は、内部Drupalキャッシュにのみ関係します。Drupalのキャッシュの再構築には永遠に時間がかかり、Drupalの外側または前のキャッシュの追加レイヤーは、実際のキャッシュデータの再構築にはあまり役立ちません(Webサーバーがキャッシュをしばらく保持する必要があるトラフィックをオフロードする以外に)再構築されます)。
geerlingguy

その場合、Zend OpCacheがうまく機能することがわかりました。:-)
mulderjoe
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.