C#架构建议:在结构中缓存数据的方法?
我想就C#中可行的架构问你的专家建议。
我有一个C#服务,它响应LAN上本地用户的请求,从互联网上获取数据包,并收集数据以生成结构中的数据数组。 每个数据请求大约需要2秒,并返回4000个字节。 每天可能会有成千上万的请求。
为了加快速度并减少带宽,我需要缓存数据处理的结果,以便第二次和后续访问立即提供给LAN上的任何其他用户(可能有> 50个用户)。
约束:
- 基础数据永远不会改变,即我不必担心“脏”数据(太棒了!)。
- 我想要缓存的数据是一个相当复杂的结构,包含DateTime,double等嵌套数组。数据来自互联网提供的数据,使用大量数学。
- 无论缓存多少数据(即缓存必须限制大小),我都不能使用超过100MB的内存。
- 我无法通过数字索引索引缓存中的数据,我必须使用日期(“YYYY-MM-DD”)和唯一ID字符串(“XXXXXXXX”)的组合对其进行索引。
- 它必须很快,即它必须从RAM中提供大部分响应。
- 缓存中的数据必须每24小时持久保存到磁盘。
以下是我的选择:
- 使用私有变量(即私有列表或字典)缓存服务器类中的数据,然后偶尔将其序列化为磁盘;
- 使用数据库;
我对你的专家意见感兴趣。
到目前为止,最简单的解决方案是使用Dictionary
。
关于您的要求:
-
通过使用后台线程执行高速缓存扫描10分钟或小时左右,可以最轻松地管理高速缓存的生命周期。 使用
ComplexDataStructure
,您可以在创建缓存时存储DateTime
,并在其生命周期到期后从字典中删除密钥。 -
因为您存储的是实际的数据结构,所以复杂性不是问题;
-
限制尺寸可能很困难。 sizeof()等效于引用类型? 可以帮助您计算对象结构的大小。 此操作不是
ComplexDataStructure
,但您可以使用ComplexDataStructure
存储结果。 然后,与用于1的线程相同的线程可以在空间不足时删除条目。 一个更简单的解决方案可能是使用GC.GetTotalMemory()
并确定您的进程的总内存使用量是否超出特定限制。 然后,只需删除一个缓存项,在第二次运行时,当你看到你仍在使用太多内存时,删除第二个; -
只需使用一个字符串;
-
使用
Dictionary<,>
可能是禁食的方式; -
再次,使用1.中的线程并实现这样的逻辑。
确保正确处理锁定策略。 这里最大的问题是,当不同的线程已经处理数据时,您不希望进行运算。 解决方案可能是以下策略:
-
锁定字典;
-
validation缓存项是否存在;
-
当缓存项不存在时:
-
创建一个空缓存项;
-
将其添加到字典中;
-
锁定缓存项;
-
释放字典上的锁;
-
做数据处理;
-
将已压缩的数据添加到缓存项;
-
释放缓存项上的锁;
-
-
缓存项已存在时;
-
当缓存项实际上确实有嘎吱嘎吱的数据时,返回;
-
当缓存项没有压缩数据时,锁定缓存项;
-
在锁内部,会出现嘎吱嘎吱的数据(因为锁会强迫您在另一个线程上等待)。
-
还有其他问题需要解决,但我认为这里介绍了基础知识。
也许是像Index4Objects这样的东西?
( http://www.codeplex.com/i4o)http://staxmanade.blogspot.com/2008/12/i4o-indexspecification-for.html
此外,也许可以阅读对另一个问题i4o与PLINQ的回答。
怎么样:使用IIS提供的内部方法?
我想我找到了完美的解决方案:PostSharp + Kellerman .NET日志库。 PostSharp需要略微的学习曲线(大约15分钟),但是一旦启动并运行,您可以使用[Cachable]属性注释您的方法,系统将自动为您缓存此方法的结果。 它可以作为您可能获得的清洁解决方案。