2009-04-16 10 views
3

私は、Class::DBIを継承するかなり複雑なORMモジュールのセットを持っています。データが非常に頻繁に変更されるので、私は物事をスピードアップするために、これの上にキャッシング/メモレイヤーを使用することを検討しています。モジュール:Class::DBI::Cacheableを見つけましたが、RTの評価や評価はありません。このクラスや他のClass :: DBIキャッシング・スキームを使用した人から聞いていただければ幸いです。Class :: DBIのメカニズムをキャッシュする方法はありますか?

ありがとうございます。

答えて

3

私はあまりにも自分のORMをロールバックしていると言いたいことは何度もあります!すべてのフェッチが単一のAPI(またはそのサブクラス)を介して行われる場合、キャッシング/メモ化は非常に簡単です。

ユニークキーに基づいたフェッチでは、キーの連結に基づいてキャッシュすることができます。単純なアプローチは次のようになります。代わりにハッシュの

my %_cache; 

sub get_object_from_db { 
    my ($self, $table, %table_lookup_key) = @_; 

    # concatenate a unique key for this object 
    my $cache_key = join('|', map { "$_|$table_lookup_key{$_}" } 
         sort keys %table_lookup_key 

    return $_cache{$cache_key} 
     if exists $_cache{$cache_key}; 

    # otherwise get the object from the db and cache it in the hash 
    # before returning 
} 

は、あなたがあなたのキャッシュ内の時間とメモリの制限を実装するためにCPANにモジュールのキャッシュ::スイートを使用することができます。

キャッシュに入れようとしているのであれば、キャッシュ内のオブジェクトを期限切れにする方法について考えるとよいでしょう。たとえば、すべての更新もORMを経由する場合は、update()ORMメソッドのキャッシュエントリをクリア(または更新)できます。

念入りに考えると、毎回同じオブジェクトが返されていますが、これは意味があります。たとえば、あるコードがオブジェクトを取得して値を更新するがその変更をdbにコミットしない場合、そのオブジェクトを取得する他のすべてのコードはその変更を認識します。これは一連の操作を一緒にストリング化している場合に非常に便利です。オブジェクトをすべて更新してから最後にコミットできますが、意図したとおりではありません。私は通常、データベースから新鮮なときにオブジェクトにフラグを設定し、オブジェクトが更新されていればセッターメソッドでそのフラグを無効にします。新しいオブジェクトが本当に必要な場合は、常にそのフラグをチェックできます。

0

私はの前にmemcachedを使用しましたが、Class :: DBI(ORMは私に汚れを感じさせます)では使用しませんでした。

2

私たちは自分自身をロールバックしましたが、プロファイリングが必要な特別なケースに限定しました(例えば、大きなジョイン)。私たちのアプリケーションでは通常、DBアクセスの上にカスタム抽象レイヤー(自家製ORMに似ています)を使用しているため、ここでキャッシュを実装しました。我々は満足していて、多くの努力を払っていない、良い結果を達成しました。もちろん、私たちはCPAN ORMを使用していなかったので、CPANキャッシングモジュールを使用することについての選択肢はありませんでした。

厳密にはケースバイケースでオプトインでした。 CPANソリューションを使用するかどうかにかかわらず、プロファイリングが助けを必要としていることを示す場合には制限し、キャッシングが微妙な方法でアプリケーションを損なわないようにオプトインしていることを確認することをお勧めしますあなたがそれを期待していないときにアクティブになって。

関連する問題