20

大量のトラフィックを伴う新しいプロジェクトで、Symfony2 アプリを構築してキャッシュを活用し、将来的により積極的になる準備をする方法を考えています。あなたの意見を知りたいです。

ユーザーがページに場所のリストをリクエストしたとします。このページには次のものがあります。

- list
   - common data (title, author, description)
   - user data (the user likes the list + other data)
- first 20 places
   - common data (title, photo of each place)
   - user data (the rates of the user for those places)

HTML は次のようになります。

<html>...
<body>
  <header>
  ...
  <!-- Embed the top user menu -->
  <esi:include src="http://example.com/profile/menu" />
  ...
  </header>

  <content>
  ...
  common data of the list
  ...
  <!-- Embed the common data of the first 20 places, the same for everyone -->
  <esi:include src="http://example.com/lists/17/places" />
  ...
  <!-- Embed the user data of the list (used in JS) -->
  <esi:include src="http://example.com/lists/17/user" />
  ...
  <!-- Embed the user data of the list of places (used in JS) -->
  <esi:include src="http://example.com/lists/17/places/user" />
  ...
  </content>
</body>       
</html>

HTML はゲートウェイ (Symfony または Varnish) にキャッシュされます。ほとんどの場合、場所のリストもゲートウェイにキャッシュされます。ユーザーデータリクエストは、呼び出されてキャッシュされないものになります (少なくとも最初はそうではありません)。

質問:

  1. この構造をどう思いますか?
  2. ユーザーが匿名の場合、ユーザー データの esi-includes を作成しないようにすることはできますか? また、anonユーザーのCookieを持っている場合は? どのように?
  3. ユーザーメニューの esi-include は理にかなっていますか?
  4. それとも、ESI を忘れて、常にコントローラーを経由する必要がありますか (たとえば、共通データのレンダリングされたビューをキャッシュします)?
  5. サーバーで待機する代わりに、ユーザー データを AJAX 呼び出しにするよう要求する 2 つの ESI 要求を移動する必要がありますか?
  6. 迅速に行う必要がある場合、これはスケーリングするための良いアプローチですか? 何が一番いいでしょうか?

どうもありがとう!

4

1 に答える 1

5

1 つのサイトでページ全体のキャッシュに Varnish を使用しており、Symfony2 を数年間使用していますが、どの運用環境でも Varnish + Symfony2 + ESI を使用していないことに注意してください。

  1. 基本的な考え方はOKだと思います。メニューが多くのページで同じで、場所のリストも多くのページで同じである場合、Varnish または Symfony のリバース キャッシュによって共通のコンテンツがキャッシュされます。通常、Varnish はメモリ内にキャッシュを保持するため、コンテンツをより速く取得でき、リクエストごとにレンダリングと DB クエリ コードを呼び出す必要はありません。

    難しいのは、ユーザーがログインしている場合にこれらの ESI リクエストをキャッシュすることです。私が知っているように、デフォルトの Varnish 構成では、Cookie を含むリクエストは決してキャッシュされません。Cookie を ESI リクエストに渡す傾向がある場合、それらの ESI レスポンスはユーザー間で共有されません。

    URL からいくつかのルールを作成してみることができますが、デフォルトの Symfony twig ヘルパーを使用すると、生成される URL は /_internal/... になるため、パブリックとプライベートの区別が難しい場合があります。

    Cache-Control: publicが渡された場合、常にすべての Cookie を無視するように構成することもできます。これは Symfony ではデフォルトで行われます:

    if ($this->isPrivateRequest($request) && !$response->headers->hasCacheControlDirective('public')) {
        $response->setPrivate(true);
    }
    

    コードからわかるpublicように、ディレクティブがある場合、応答が非公開になることはありません。

    Varnish がこのディレクティブをどのように処理するかはわかりません。私が理解しているように、デフォルトでは Cookie を持つリクエストはキャッシュされません。したがって、これを実現するには構成を微調整する必要があると思います。

  2. メインページもキャッシュする場合、インクルードをスキップする方法がわかりません。

    登録ユーザーには (検索ボットではなく) JS が必要であると想定しているため、Javascript を使用してユーザー データの読み込みを変更することをお勧めします。

    Javascriptコードは、ユーザーがCookiesession-idなどを持っているかどうかを調べ、この場合にのみデータを取得するように要求できます。_loggedinJavascript コードがセッション ID を取得しないようにするなど、他の Cookie を設定することをお勧めします。

    ログインしていないユーザーも、Cookie に などのデータを保持できます_likedPost:1,2,132。Javascript はこの Cookie を取得して、追加のリクエストを行わなくても HTML の修正を行うことができます。

    これらの Cookie で行ったように、JS のみの Cookie をアプリケーション Cookie から分離しました。_\wこれは、JS Cookie の場合のように、いくつかのパターンで行いました。次に、Varnish の構成を微調整して、Cookie ヘッダーを分割し、これらの JS のみの Cookie を削除しました。その後、他の Cookie が残っていない場合、応答は全員に共有されます。アプリケーション (Symfony) はこれらの Cookie を取得しません。

  3. どのページも同じならいいと思います。

  4. Varnish はキャッシュをメモリに保持できるため、ESI は優れていると思います。そのため、ハードディスクに対してコンテンツのクエリを実行することさえできない可能性があります。コントローラーのキャッシュもメモリ内にある可能性があるため、Varnish はすべてのルーティング、PHP コード、サービスの初期化などで Symfony フレームワークよりも高速にキャッシュを探すと思います。

  5. 場合によりますが、より良いアプローチになる可能性があると思います。キャッシュの寿命は異なることに注意してください。たとえば、場所のリストが 2 時間キャッシュされている場合、この時間の最後に場所が変更されている可能性があります。新しいアイテムがリストに新しく追加されたり、欠落していたり​​することがあります。ユーザーへのリストはまだ古いもの (キャッシュ) ですが、新しいリストに関するユーザーのデータを提供します。一部のデータは不要で、一部は欠落しています。

    たとえば、いくつかの HTML 属性を検索してから、data-list-item-idこれらの項目に関するデータを照会する ajax 要求を作成するなど、javascript によってロードされた場所を取得する方が良い方法かもしれません。この場合、ユーザー データは現在キャッシュされているリストと同期され、両方のリストに対して 2 つではなく 1 つの ajax リクエストを行うことができます。

  6. キャッシュの無効化 (PURGE リクエスト) が使用されていない場合、すべての HTTP キャッシュ スキームは確かにスケーリングに適しています。アプリケーションを複数のサーバーにスケーリングし、Varnish を構成してそれらをランダムに呼び出すか、何らかのルールで呼び出すか、それらの 1 つをフェールセーフとして使用することができます。それでも帯域幅が大きすぎる場合は、キャッシュのタイムアウトやその他の構成をいつでも変更できます。

于 2012-12-11T22:39:08.597 に答える