3

私は最近、PHP アプリのスケーラビリティに関する多くの記事を読んでいます。私が読んだほとんどすべての記事でキャッシングについて言及していたので、過剰な DB クエリを防ぐために、クラス プロパティに DB データをキャッシングするというアイデアを思いつきました。私はそのアイデアを共有したかったので、それについてブログに書きました. 無意味でばかげたという言葉を使う以外に、彼はそれがなぜ悪いのかを本当に説明できませんでした. PHP アプリケーションのスケーリングを支援するためのこのキャッシング方法がなぜ悪いのか、誰かここで説明してもらえますか?

メソッド:

仮説:

DB から (必要に応じて) すべてのメソッドでデータをフェッチし、クエリを次々と実行する代わりに、フェッチした DB データを格納するクラス プロパティ (変数) を用意して、重複の必要性を防ぐことをお勧めします。同じデータを返すクエリ。

わからない場合は、私のブログから抜粋した例を次に示します。


説明を少し簡単にするために、Facebook をこの例に取り入れます。ソーシャル ネットワークのユーザー クラスを再コーディングしているとしましょう。

class FBuser
{

}

このクラスに含まれる明らかなメソッドは次のとおりです。

getStatusUpdates()
getAccountInfo()
getFriendIDs()

本来、これらのメソッドは、必要なデータを取得するためにデータベース クエリを実行する必要がありました。しかし、キャッシング メソッドを使用すると、キャッシュされたデータを格納するクラス プロパティを定義し、すべての DB クエリを 1 つのメソッドで実行できます。

class FBuser
{
    private $userCache = array();

    private function getData( $dataToGet = '' )
    {

    //all of my db querying would happen here

    }

}

ただし、同じ方法で、許可されている場合はキャッシュも探します。

private function getData( $dataToGet = '' , $useCache = true )
{
   //am I allowed to use cache?
   if ( $useCache === true )
   { 
       //does the appropriate data exist in cache?
       if ( isset($this->userCache[ $dataToGet ]) )
       {
           return $this->userCache[ $dataToGet ];//return the cached data, and forget about the DB queries
       }

   }

   //if we get here, caching was disabled or the required data has not yet been cached :(
   //all of my db querying would happen here

   //store the data that's just been fetched by the queries in the cache property

}

getData( 'the data I want' , true );このようにして、DB からデータを取得したいときにいつでも呼び出すことができ、可能な場合にキャッシュされたデータを使用できます。

したがってgetAccountInfo()getStatusUpdates()またはgetFriendIDs()複数回呼び出す必要がある場合、このメソッドは複数の DB クエリが実行されるのを防ぎます = スケーリングに適しています (私はそう思います)。


4

2 に答える 2

3

なぜそれは悪い考えですか?

厳密に言えば、それ自体は悪い考えではありません。スクリプトに重複したクエリがある場合、期待どおりの動作が得られ、パフォーマンスが少し向上します。

ただし、実際には、スクリプトが非常に、まあ、異常なことを行っていない限り、典型的な PHP スクリプトの要求ごとのデータベース呼び出しの数は 15 または 20 を超えず、おそらくそのうちの 2 または 3 だけが重複トップです。データベース呼び出しがすでに比較的高速である場合、2 つまたは 3 つのデータベース呼び出しをハッキングしても、パフォーマンスの違いはごくわずかです。言うまでもなく、データベース自体には既にキャッシュ システムが配置されている場合があります。

アプリ/スクリプトによっては、リクエスト間で存在する永続キャッシュを実装することで、潜在的なパフォーマンス ジャックポットが得られます。

「やらないで」と言っているのではありません。同じリクエスト/スクリプト内で同じクエリを何百回も実行する予定がない限り、これは一般的にありそうもないことです。永続的な解決策なし。でも絶対に損はしません。

于 2012-08-28T03:49:40.570 に答える
1

あなたの先生はばかです :p

私が言いたい主なポイントは、このタイプのキャッシングは、コンテキストによっては、実際には非常に役立つということです。私が開発した Web フレームワークでこれを行います。このリファクタリングは、XDebug を使用してキャッシュグラインドを注意深く分析することによって行われました。

このように考えてみてください。DB アクセスは、PHP スクリプトが実行する (パフォーマンスの点で) 最もコストのかかる作業の 1 つです。DB 関連の呼び出しがページの合計実行時間の 50% (またはそれ以上) を占めているページを簡単に見つけることができます。データの再利用が自動的に利益をもたらすように、結果をキャッシュしてみませんか?

PHP リソースの割り当てに関して、そうしない理由はありません。カバーの下では、PHP は変更されない限り zval への参照を共有するため、スクリプトはヒープ上でより多くのメモリを必要としません。

これを疑う人には、2 つではなく 1 つの DB 呼び出しを行うページで XDebug を実行し、重要な結果が得られないことを世界に宣言するように挑戦します。これを実装するコードが非常に単純な場合、なぜ改善しないのでしょうか?

現在、より永続的な形式のキャッシングを指摘し、代わりにそれらを使用する必要があると言う人もいるかもしれません。私は、この種の反応が示唆する普遍性には同意しません。おそらく、そのデータ セットは大きすぎて、サーバーに完全にキャッシュすることはできません。たとえば、毎日 1% のユーザーしかログインしていない場合、すべての人のデータをメモリにキャッシュするつもりはありません。サーバー上のメモリの価値はありません。データが頻繁に更新される可能性があります。その場合、同期が問題/負荷になり、キャッシュの利点を上回る可能性があります。私が指摘したいのは、より永続的な形式のキャッシュが適切でない状況があるということです。

環境に優しく、すべてのサイクルが重要です:)

于 2012-08-27T22:58:41.840 に答える