2009-06-29 11 views
2

私のキャッシュを私が望むように動作させるにはいくつか問題があります。ASP.NET永続キャッシュ(「レイジーローディング」スタイル)

問題: 要求されたデータを取得するプロセスは非常に時間がかかります。標準のASP.NETキャッシュを使用している場合、一部のユーザーはデータの取得に「ヒット」します。これは受け入れられません。

溶液: データが100%電流であることは非常に重要ではありません。キャッシュされたデータを別のスレッドで更新している間に古い無効化されたデータを提供して、新しいデータを将来のリクエストで利用できるようにしたいと思います。そのユーザーがアプリケーションを再起動した後に最初のユーザーにサービスを提供できるようにするためには、データを何らかの方法で永続化する必要があると思います。

私は上記のやや優れた解決策を作りましたが、「ベストプラクティス」の方法があるのか​​、すでにこの動作をサポートしているキャッシングフレームワークがあるのでしょうか?

答えて

1

私は自分のソリューションを実際のキャッシュの複製としてメモリ内のDictionary/Hashtableで作成しました。メソッドコールがオブジェクトをキャッシュから要求し、そこには存在しなかったがメモリに存在すると、メモリ格納オブジェクトが返され、デリゲートメソッドを使用してメモリとキャッシュの両方のオブジェクトを更新する新しいスレッドを起動しました。

1
キャッシュされた項目が削除されたときにあなたが聞くことができ

とプロセス、その後、

public void RemovedCallback(String k, Object v, CacheItemRemovedReason r) 
{ 
    // Put Item Back IN Cache, (so others can use it until u have finished grabbing the new data) 

    // Spawn Thread to Go Get Up To Date Data 

    // Over right Old data with new return... 
} 
グローバルasaxで

protected void Application_Start(object sender, EventArgs e) 
{ 
    // Spawn worker thread to pre-load critical data 
} 

これがベストプラクティスである場合おお...私は見当がつかない、ちょうど私それは滑らかであると思った〜 幸運〜

+0

私はこれを考えなかった。 しかし、このソリューションを使用すると、サイトを訪問した最初のユーザーは、キャッシュを更新する際に「ヒット」します。また、データをフェッチするためにインラインデリゲートを使用しているため、RemovedCallback内でデリゲートを再実行する方法がわかりません。 – hakksor

+0

申し訳ありませんが、その部分に対処するのを忘れました。アプリケーションの開始時にGlobal.Asaxで、必要なデータに "偽の"要求を出すスレッドを生成します。この方法で既に働いているか、それはすでに最初の要求によって終了しています。 – BigBlondeViking

+0

haha​​ fist request ...(私は恐ろしいタイパーです) – BigBlondeViking

3

これを行うツールは、MicrosoftsのISA Server(少し高価かもしれない/過剰です)があります。

Enterprise Libary Cachingを使用してメモリにキャッシュできます。ユーザーがキャッシュから読み込み、キャッシュを更新する他のページを持つようにすると、これらの他のページはデータを最新の状態に保つ必要があるので定期的に呼び出されるべきです。

+2

あなたの要件があまり複雑でないなら、ELキャッシングはかなり摩擦がありません。 –

+0

しかし、私はサービス/スケジュールされた仕事に頼ることなくこれをやりたかったのです。 – hakksor

+0

サービス/スケジュールされたタスクなしでこれを行うことができますが、コンテンツを要求する最初のユーザーはEnterprise Libary Cachingの推奨のために "ヒット" –

0

ええ、アプリ起動時に最も頻繁にアクセスされるデータをキャッシュすることはできますが、引き続き最初のユーザーが「ヒットする」ということを意味します(inprocキャッシュを仮定した場合)。

0

私は、最新のデータをキャッシュし、テーブルのデータをリフレッシュするバックグラウンドジョブ(共有環境ではスレッドを使用できるWindowsサービス)を実行するために、dbのCacheTableを使用しています。

ユーザーに空白の画面を表示する可能性はほとんどありません。私はasp.netキャッシュを介して1分間キャッシュすることでこれを排除します。

悪いデザインであるかどうかわかりませんが、よく使用されているWebサイトで問題なく動作しています。

1

.NETに組み込まれたCacheおよびTimerクラスを使用すると、これを簡単に実行できます。タイマーは別のスレッドで実行されます。

そして実際には、オーバーロードされたコンストラクタでこの機能を公開するWebCacheHelperという非常に小さなラッパーライブラリを作成しました。ライブラリは、Cacheオブジェクトの周囲に強く型付けされたラッパーとしても機能します。

は、ここでこれはGetRegisteredUsersCount()RegisteredUsersCountが最初にアクセスされる瞬間をスレッド呼び出しで実行されることに遅延ロードの側面を持っている

public readonly static WebCacheHelper.Cache<int> RegisteredUsersCount = 
    new WebCacheHelper.Cache<int>(new TimeSpan(0, 5, 0),() => GetRegisteredUsersCount()); 

...あなたがこれを行うことができる方法の例です。しかしその後、バックグラウンドスレッドで5分ごとに実行されます。これは、遅い待ち時間でペナルティを科される唯一のユーザーが最初のユーザーになることを意味します。

値を取得するのは、RegisteredUsersCount.Valueと同じくらい簡単です。

関連する問題