【问题标题】:Disk backed dictionary/cache for c#c# 的磁盘支持字典/缓存
【发布时间】:2010-09-29 08:00:53
【问题描述】:

我正在寻找一种用于缓存大量数据的解决方案。

相关问题,但针对不同的语言:

用不同的术语结束问题:

我不需要(或不想为此支付任何费用)持久性、事务、线程安全等,并且想要使用不比 List 或 Dictionary 复杂多少的东西。

如果我必须编写代码,我会将所有内容保存为临时目录中的文件:

string Get(int i)
{
   File.ReadAllText(Path.Combine(root,i.ToString());
}

在我的情况下,索引将是 int(它们应该是连续的或足够接近),数据将是 string,所以我可以同时处理 POD 并且宁愿超-light 并做到这一点。

用法是我有一个 3k 文件序列(如文件 #1 到 #3000),总计 650MB,需要为序列中的每个步骤做一个差异。我希望总数大致相同或更多,并且我不想将所有这些都保留在内存中(我无法做到的情况下可能会出现更大的情况)。


许多人针对我的问题提出了不同的解决方案。然而,似乎没有一个针对我的小利基。我正在查看磁盘支持缓存的原因是因为我预计我当前的使用将占用我可用地址空间的 1/3 到 1/2。我担心更大的箱子会完全耗尽空间。我不担心踩踏、持久性或复制。我正在寻找的是使用最少代码、最少占用空间、最少内存开销和最低复杂性的最小解决方案。

我开始认为我过于乐观了。

【问题讨论】:

  • 为什么不是文件系统?这就是为...设计的......
  • 如果有人不能指出我已经写好的更好的东西,我会的。
  • 基于磁盘的缓存不是破坏了缓存机制的全部目的吗?
  • 取决于数据的来源。如果它要记住昂贵的计算值或通过缓慢的 Internet 链接传来的数据,那可能就更合理了。
  • 我刚刚遇到了类似的问题...仍在寻找解决方案

标签: c# caching disk-based


【解决方案1】:

您真正想要的是 B 树。 这是数据库使用的主要数据结构。 它旨在使您能够根据需要有效地将数据结构的部分交换到磁盘和从磁盘交换。

我不知道有任何广泛使用的、高质量的 C# 独立 B-Tree 实现。

但是,获得一个简单的方法是使用 Sql Compact 数据库。 Sql Compact 引擎将在进程内运行,因此您不需要运行单独的服务。它会给你一个 b-tree,但没有所有的头痛。您可以只使用 SQL 来访问数据。

【讨论】:

  • 我不喜欢开销。查看我的编辑,但我可以通过一次内存数组查找和每次加载读取一次磁盘来摆脱困境,因此 B-Tree 太过分了......在我的情况下。
  • 使用进程内数据库的一个优点是它可以让您独立访问路径。当您需要更改存储的数据或访问数据所需的密钥时,您无需重新编写大部分应用程序
  • 然而,如果你真的觉得你需要对数据做的事情就是那么简单,那么我认为你可以从头开始使用 Dictionary(of int, string),其中字符串是一个文件名,在大约 2-3 小时的工作中......
【解决方案2】:

免责声明 - 我将向您介绍我参与的产品。

我还在做网站方面的工作,所以没有很多信息,但Serial Killer 很适合这个。我有使用 .Net 序列化的示例(可以提供示例),因此为 .Net 可序列化对象编写持久映射缓存将是微不足道的。

够无耻的自我宣传——如果有兴趣,请使用网站上的联系链接。

【讨论】:

  • +1 用于相关内容,但我正在寻找更多超轻量级解决方案(理想的情况是键和值都是 POD 并存储为二进制数据块)
  • SerialKiller 实在是太轻了——我不想让你因为这个原因而放弃它!该接口基本上是从密钥(系统生成)到二进制流的映射。
  • 我正在寻找的天真、可能有问题和可扩展性的版本(跳过驱逐政策的东西)可以在大约 30 LOC 内完成。如果您能在其中获得一半的功能列表,我会印象深刻。
  • “轻量级”我更多地指的是运行时开销,它们非常低。我还没有计算 LOC,但 DLL 总共不到 500kb,考虑到能力,非常精简。
  • 我不同意。克服文件系统中的碎片问题和缓存策略会极大地影响执行时间,因此性能可能与 LOC 成反比!
【解决方案3】:

这和我的问题很相似

Looking for a simple standalone persistant dictionary implementation in C#

我认为不存在完全符合您想要的库,也许是时候在 github 上创建一个新项目了。

【讨论】:

  • 添加了链接。换个方式加个链接怎么样?
  • OTOH 动机不同。您正在寻找持久性,我想将内容存储在磁盘上而不是内存中。大量重叠,但不完全相同。
  • 别担心,我从我的帖子中添加了一个链接
【解决方案4】:

这是 .net 的 B-Tree 实现:http://bplusdotnet.sourceforge.net/

【讨论】:

  • 一个有趣的项目,但仍然比我想要的要重很多。
【解决方案5】:

您可以将MS application block 与基于磁盘的缓存解决方案一起使用

【讨论】:

    【解决方案6】:

    也试试看 NCache here

    我不隶属于这家公司。我刚刚下载并测试了他们的免费快递版本。

    【讨论】:

      【解决方案7】:

      我已将 EhCache Java 应用程序部分弹出到 .NET 尚未实现分布式缓存,但在单个节点上,所有原始单元测试都通过了。完全开源:

      http://sourceforge.net/projects/thecache/

      如果你需要,我可以创建一个二进制文件(现在只有源代码可用)

      【讨论】:

      • 看起来像一个整洁的项目。 OTOH,这对我来说似乎有点矫枉过正。
      【解决方案8】:

      我会采用嵌入式数据库路由(SQLite、Firebird),但这里有一些其他选项:

      【讨论】:

        【解决方案9】:

        我推荐 MS 的企业库中的缓存应用程序块。这也是推荐的,但链接指向企业库的数据访问部分的文章。

        这里是缓存应用程序块的链接:

        http://msdn.microsoft.com/en-us/library/cc309502.aspx

        具体来说,您需要创建一个新的后备存储(如果没有持久存储到磁盘的后备存储):

        http://msdn.microsoft.com/en-us/library/cc309121.aspx

        【讨论】:

          【解决方案10】:

          鉴于您最近对该问题进行了编辑,我建议您实施问题中提到的解决方案,因为您不太可能在库中找到如此幼稚的解决方案供您重复使用。

          【讨论】:

            猜你喜欢
            • 2016-02-26
            • 2015-03-27
            • 2020-07-21
            • 1970-01-01
            • 1970-01-01
            • 2019-06-19
            • 1970-01-01
            • 2015-10-01
            • 2015-05-22
            相关资源
            最近更新 更多