12

基本的には、クエリ結果をキャッシュするためだけに memcache を使用します。

無効化は、実装方法が原因で悪夢です。それ以来、メーリング リストを読んで memcache に関するいくつかのテクニックを学びました。知っている人は次の段落を飛ばしてください。

知らない人や興味がある人のために説明すると、鍵にシーケンス番号を追加し、そのシーケンス番号を memcache に保存するという方法があります。次に、「取得」を行う前に、現在のシーケンス番号を取得し、その周りにキーを作成します。次に、グループ全体を無効にするには、そのシーケンス番号をインクリメントします。

とにかく、私は現在、これを実装するためにモデルを修正しています。

私の質問は..

私たちはこのパターンについて知りませんでした。また、私たちが知らないパターンが他にもあると確信しています。memcache やベスト プラクティスなどを実装するためのデザイン パターンをウェブ上で検索しましたが、見つけることができませんでした。

誰かが私にこのようなことを指摘したり、単に例を書いたりできますか? 新しいリファクタリングで初心者の間違いを犯さないようにしたいと思います。

4

5 に答える 5

15

オブジェクト キャッシングで覚えておくべき 1 つのポイントは、オブジェクト/複雑な構造のキャッシュであるということです。多くの人が、単純で効率的なクエリのためにキャッシュをヒットするという間違いを犯します。これは、データベースがはるかに高速に結果を取得できる場合に、キャッシュ チェック/ミスのオーバーヘッドを引き起こします。

このアドバイスは、教えられて以来、私が心に留めているものです。つまり、オーバーヘッドが認識されたメリットを相殺する場合です。ここで特定の質問に答えていないことはわかっていますが、一般的なヒントとして指摘する価値があると思いました.

于 2008-11-27T01:55:38.133 に答える
6

ロブが言っていることは良いアドバイスです。私の経験から、タグを識別して無効化するには、一意の識別とタグベースの識別の 2 つの一般的な方法があります。これらは通常、次のような完全なソリューションを形成するために組み合わされます。

  1. キャッシュ レコードには、一意の識別子 (通常はキャッシュするデータに依存します) と任意の数のタグが割り当てられます。
  2. キャッシュ レコードは、一意の識別子によって呼び出されます。
  3. キャッシュ レコードは、一意の識別子 (一度に 1 つ)、またはタグ付けされた任意のタグによって無効化できます (複数のレコードを同時に無効化する可能性があります)。

これは実装が比較的簡単で、一般的に非常にうまく機能します。特定のソリューションを必要とするいくつかのエッジケースがおそらく存在しますが、それ以上のシステムが必要なシステムにはまだ出会っていません。

于 2008-11-27T02:06:20.203 に答える
3

私はZend Cacheコンポーネントを使用します (フレームワーク全体を使用する必要はなく、必要に応じて Zend キャッシュのものだけを使用します)。キャッシングの一部を抽象化します (「タグ」によるキャッシュのグループ化をサポートしていますが、その機能は memcache バックエンドではサポートされていません。「タグ」の独自のサポートを比較的簡単に展開しました)。したがって、キャッシュにアクセスする関数に使用するパターン (通常は私のモデル) は次のとおりです。

public function getBySlug($ignoreCache = true)
{
    if($ignoreCache || !$result = $this->cache->load('someKeyBasedOnQuery'))
    {
        $select = $this->select()
                ->where('slug = ?', $slug);
        $result = $this->fetchRow($select);

        try
        {
            $this->cache->save($result,'someKeyBasedOnQuery');
        }
        catch(Zend_Exception $error)
        {
          //log exception
        }
    }
    else
    {
        $this->registry->logger->info('someKeyBasedOnQuery came from cache');
    }
    return $result;

}

クエリのハッシュに基づいてキャッシュ キーを使用するということは、別の開発者が私のモデルをバイパスしたり、別の場所で同じことを行う別の関数を使用したりした場合でも、キャッシュから引き出されることを意味します。通常、私はキャッシュにいくつかの生成タグを付けます (テーブルの名前は 1 つで、もう 1 つは関数の名前です)。したがって、デフォルトでは、キャッシュされたアイテムをテーブルのタグで挿入、削除、および更新すると、コードは無効になります。全体として、キャッシングは基本コードではかなり自動化されており、開発者は、私たちが行っているプロジェクトでキャッシングが「正常に機能する」という安心感を得ることができます。(また、タグ付けを利用することの大きな副作用は、モデル関数またはテーブルごとにキャッシュをクリアするオプションを備えた、きめ細かなキャッシュのクリア/管理を提供するページがあることです)。

于 2008-11-27T04:16:01.300 に答える
1

データベース ( PostgreSQL ) からのクエリ結果も memcache に保存し、テーブルでトリガーを使用してキャッシュを無効にしています。確かに知っている)。利点は、データベース自体 (トリガー) が変更 (更新、挿入、削除) でのデータの無効化を処理できることです。そのすべてを「アプリケーション」に書き込む必要はありません。

于 2008-11-27T17:50:55.100 に答える