7

私はウェブサイトを開発しています。現在、私はcheapo共有ホスティングを利用しています。しかし、少年は夢を見ることができます。私は、自分のサイトのユーザー数が増えたらどうなるかをすでに考えています。

サイトでのゲームの進行状況がログに記録されるため、訪問者は時折データベースへの書き込みを必要とします。

$_SESSION進行状況やその他の情報を変数に書き込むことで、クエリを最小限に抑えることを考えました。そして、セッションが破棄されたとき (ログアウト、ブラウザの終了、またはタイムアウト) にのみ、内容を$_SESSIONデータベースに書き込みたいと考えています。

質問:

  1. それは可能ですか?セッションがタイムアウトまたはブラウザの終了によって破棄されたときに関数を実行する方法はありますか?

  2. それは理にかなっていますか?共有サーバーでは数百の同時 SQL クエリが問題になるの$_SESSIONでしょうか。これを緩和するためにバッファとして使用するという考えがあります。

4

4 に答える 4

6

タイムアウトまたはブラウザのクローズによってセッションが破壊されたときに関数を実行する方法はありますか?

はい、しかしそれはあなたが想像するようには機能しないかもしれません。を使用して独自のカスタムセッションハンドラーを定義できます。定義のsession_set_save_handler一部は、destroyおよびgcコールバック関数を提供することです。これらの2つは、セッションが明示的に破棄されたときと、セッションが期限切れになったために破棄されたときに呼び出されるため、要求どおりに実行されます。

ただし、タイムアウトによるセッションの期限切れは、時計仕掛けの精度では発生しません。期限切れのセッションが実際に「ガベージコレクション」されるまでには、かなりの時間がかかる場合があります。さらに、ガベージコレクションは確率的にトリガーされるため、理論的には、期限切れのセッションがガベージコレクションされない可能性があります。

それは官能的ですか?共有サーバーでは数百の同時SQLクエリが問題になり、これを軽減するために$_SESSIONをバッファーとして使用するというアイデアがあります。

私は実際にはいくつかの理由でこれをしませんでした:

  • 時期尚早の最適化(測定する前に、それが「より良い」と単に想定しないでください)。
  • セッションがガベージコレクションされることはありません。これが起こらなくても、いつ収集されるかを制御することはできません。これは問題になる可能性があります。
  • プレーヤーの進行状況を含め、セッションに含まれるすべてのもの(サーバーの再起動など)が失われる可能性があります。プレイヤーは進歩を失うのが好きではありません。
  • 同じユーザーの同時セッションは不可能です(「保存されたデータ」が優先され、データベースに保持されたままになりますか?)。

代替案はどうですか?

ええと、私たちはel cheapo共有ホスティングについて話しているので、あなたは間違いなくサーバーを制御するつもりはないので、PHP拡張機能(memcachedなど)を含むものはすべて条件付きです。データベース側のキャッシュも飛ぶことはありません。さらに、サーバーの負荷は制御外の変数の影響を受けるため、キャパシティプランニングを実際に行うことはできません。

いずれにせよ、データベース自体が最適に構造化されていることと、データベースへの負荷を最小限に抑える方法でコードが記述されていることを確認することから始めます(エディターに入力するだけでパフォーマンスが向上します)。

その後、読み取り専用キャッシュを導入できます。通常、表示する必要があるものの、変更するつもりのないものがたくさんあります。「ほとんどない」データの場合、必要なときにいつでも無効にするセッションキャッシュは、簡単で非常に効果的な改善になる可能性があります(無効化に関して誤検知が発生する可能性もありますが、その数が多すぎない限り、物事の壮大な計画)。

最後に、1回のリクエストで同じデータをデータベースから2回プルする必要がある場合は、リクエストごとのキャッシュを(変数で)追加できます。

于 2012-04-17T13:58:44.680 に答える
5

セッションが破棄されたときにデータを書き込むことはお勧めできません。セッションデータは、ホスティング事業者によって構成されたガベージコレクターを介して破棄される可能性があるため、ユーザーのCookieが古くなるまで、セッションが実際にいつ閉じられるかはわかりません。

つまり...memcacheのような共有メモリ(RAM)キャッシュシステム(ホスティング事業者が提供している場合)またはディスクベースのキャッシュシステムのいずれかを使用することをお勧めします。

ちなみに、クエリが最適化されている、列が正しくインデックス付けされているなどの場合、共有ホスティングは「同時に」大量のクエリを受け取る可能性があります。

于 2012-04-17T13:57:59.330 に答える
2

それは理にかなっていますか?共有サーバーでは数百の同時 SQL クエリが問題になるのでしょうか?これを軽減するために $_SESSION をバッファとして使用するという考えです。

いいえ。何よりもまず、セッションに何が起こるかわかりません (ログアウトは明らかで、タイムアウトはほとんど検出されません)。そのため、とにかく信頼できるキャッシュ メカニズムではありません。あまり頻繁に変更されないいくつかのリクエストの期間にわたって複数回クエリを実行する結果がある場合は、それらのクエリの結果をAPCや memcached などの専用のキャッシュ メカニズムに保存します。

ウェブホストがこれらのキャッシュ システムを提供していないことは理解していますが、サイトを最適化するためにさまざまなことを実行できる可能性があります。手始めに、私の最も複雑なソフトウェア製品 (かなり複雑です)、平均して 1 ページあたり約 6 回データベースにクエリを実行します。結果が再利用可能な場合は、キャッシュを使用する傾向があるため、クエリの数が減ります。

それに加えて、適切なクエリを作成することがより重要です。デザインとクエリの質は、量よりも重要です。スキーマ、インデックス、およびクエリが適切であれば、最適化されていない 1 つのクエリよりも 10 個のクエリの方が高速です。セッションでのキャッシュなどの「回避策」で問題を克服しようとするのではなく、効率的なクエリを作成する方法を調査し、インデックス作成について読むことに時間を費やします。

頑張ってください。あなたのサイトが大成功を収めて、実際に上記のアドバイスが必要になることを願っています ;)

于 2012-04-17T14:04:11.963 に答える
1

実際には、重複した読み取りを回避するためのバッファーとして$ _SESSIONを使用できますが、書き込みを遅らせることはありません(これははるかに複雑で、dbで処理する必要があります)。

$_SESSIONに保存した単純なハッシュを使用できます

$cache = array();
$_SESSION['cache'] = $cache;

その後、クエリを実行する必要がある場合

if(isset($_SESSION['cache'][$id]){
    //you have a cache it
    $question = $_SESSION['cache'][$id];
}else{
    //no cache, retrieve your $question  and save it in the cache
    $_SESSION['cache'][$id] = $question ;
}
于 2012-04-17T14:01:16.270 に答える