2017-01-23 1 views
0

セッションオブジェクトを.net framework 4.0のキャッシュメカニズムに置き換えるMVCアプリケーションを作成したいとします。MemoryCacheを使用してセッションを置換するC#MVC

アプリケーションは、データベーストラフィックとローディング時間を低く抑えるために、ある種のキャッシュに値を格納する必要があります(設定、ドロップダウン値など)。ユーザは、ユーザ名とパスワードを使用して自分自身を認証します。ここではデフォルトのFormsAuthenticationが使用されています。私の考えは、ユーザーごとに一意のMemoryCacheを作成し、アプリケーションのために一般的なMemoryCacheを作成することでした。ユーザーはキャッシュが配置され、ログアウトした場合、ユーザーMemoryCacheため

私のゲッターはこの

private MemoryCache _memCache 
{ 
    get 
    { 
     if(HttpContext.Application[User.Identity.Name] == null) 
     { 
      HttpContext.Application[User.Identity.Name] = new MemoryCache(User.Identity.Name); 
     } 

     return HttpContext.Application[User.Identity.Name] as MemoryCache; 
    } 
} 

のように見えます。

これは、アプリケーションオブジェクトはMemoryCacheを格納するために使用可能である場合に問題があるアプリケーション

private MemoryCache _appMemCache 
{ 
    get 
    { 
     if(HttpContext.Application["ApplicationMemoryCache"] == null) 
     { 
      HttpContext.Application["ApplicationMemoryCache"] = new MemoryCache("ApplicationMemoryCache"); 
     } 

     return HttpContext.Application["ApplicationMemoryCache"] as MemoryCache; 
    } 
} 

のグローバルMemoryCacheです。そして、がこれに問題なく動作していれば。

セッションを使用しない理由は、可能なタイムアウトと並列要求のブロックです。

+0

[セッション状態の使用について2回考えてください](https://brockallen.com/2012/04/07/think-twice-about-using-session-state/) - セッション状態がユーザープロファイルデータを格納する場所。しかし、私は@ChrisPrattに同意します。それを置き換えるための精巧な方法を考え出すのではなく、セッション状態の使用を排除または最小化することを目指すべきです。 – NightOwl888

答えて

1

これはいくつかの理由で悪い考えです。まず第一に、MemoryCacheは、揮発性とプロセスの両方にバインドされています。セッションデータがprocに格納されている場合でもセッションデータを保持しようとする試みがありますが、キャッシュは完全に使い捨てであるとみなされます。メモリが不足すると、すぐに破棄されます。また、これは効果的に、複数のワーカー(プロセス)へのアプリケーションの拡張能力を失わせ、それぞれがキャッシュのバージョン上にあるので、ユーザーの「セッション」が復元されたかどうかは、彼らは次の要求で彼らが着陸したプロセス。

セッションを使用するだけの理由は意味を持ちません。はい、セッションにはタイムアウトがありますが、これはprocで使用していないと仮定するといくぶん修正されています。 procであっても、App Poolのリサイクルなどが発生しない限り、セッションは一定の間隔でタイムアウトします。逆にMemoryCacheはいつでものになります。データがどれくらい長く続くか、まったく持続するかについての保証はありません。ちょうどあなたがそれを1年間固執するように設定したからといって、システム内で何が起こっているかによって5分で廃棄されないというわけではありません。

「並列要求をブロックする」とは、あなたが何を話しているのか分かりません。セッションはスレッドセーフであり、理論的には並列要求を許可する必要があります。セッションストアへの書き込みなどの非同期プロセスでは常に並行性の問題が発生しますが、同じ問題はMemoryCacheでも発生します。

皆、あなたが貯蓄について話していることは、実際にはセッションに属していないと言っています。 MemoryCacheのようなものを使用する理由は完全に無効ですが、実際にはこのタイプのものを保存するためにキャッシュを使用する必要があります。言い換えれば、キャッシュを使用して、何らかの形でセッションをキャッシュに置き換えようとしないでください。

また、前述したように、マルチプロセスシナリオではMemoryCacheに深刻な問題があります。一握り以上のユーザーに役立つアプリを構築する場合は、MemoryCacheを完全に避けて、代わりにRedisのようなものを使用する必要があります。RedisはMicrosoft Azureで使用されているため、Microsoftの優れたサポートとASP.NETへの統合は可能ですが、NoSQLソリューションを選択することもできます。

+0

asp.netは、(書き込み可能な)セッションごとに1つのスレッドを使用して、一度に1つの要求でユーザーを制限します。これは私が避けたいものです。自分のデータがセッションに属していない理由を指定することができますか(例:ドロップダウン値) – JoeJoe87577

+0

これは単に正しくありません。私はあなたがその情報を入手したかどうか分からない。あなたがそのデータのためにセッションを使用すべきでない限り、一般的にセッションをごくわずかな期間使用するべきです。データが特定のユーザーに属している場合は、後でそのユーザーからデータを取得するだけです。セッションは、リクエスト間で永続化する必要のある匿名ユーザー固有のデータにのみ使用する必要があります。ドロップダウンのようなものは、それらのボックスをチェックしません。 DBへのラウンドトリップを避けるために、*キャッシュ*したいかもしれませんが、セッションに属していません。 –

+0

@ChrisPratt - ObjectCacheを使用すると複数のプロセスにスケールアウトされないとは言えません。[分散ObjectCache](http://stackoverflow.com/questions/14646658/i-am-looking-for -a-distributed-data-object-cache-for-my-asp-net-mvc-app)を使用して、それを処理します。しかし、Out-of-Process Session StateやRedisのようなものを使うよりも余計な努力が必要ですか?おそらくそうではありません。 – NightOwl888

関連する問題