【问题标题】:Keeping persistent data in memory将持久数据保存在内存中
【发布时间】:2011-04-13 01:53:48
【问题描述】:

我即将用 C# 开发一个 Windows 服务。该服务需要跟踪系统中的事件,并不时将一些数据写入文件。这些正在进行的事件形成了某种状态,因此我会将状态保存在内存中,并在事件到达时对其进行更新。我不想让事情变得过于复杂,所以我不希望状态在磁盘上持久存在,但我想知道我是否可以以某种方式使其在内存中持久存在,这样如果服务崩溃(并且自动重启Windows)它可以从它离开的地方继续前进(可能会丢失一些事件,没什么大不了的)。

我正在考虑创建一个“共享”内存区域,从而让 Windows 管理它,并仅在服务中使用它 - 但我不确定该对象在服务终止后是否会持续存在。

有什么想法吗?

编辑:我不是在寻找一个矫枉过正的解决方案。数据有点重要,所以我想让它在内存中等待,直到服务重新启动,但数据并不是重要。如果我可以轻松地保存数据,而无需处理文件、外部 3rd 方进程等,这将是一个不错的功能。我理想的解决方案是一个简单的内置功能(在 .NET 或 Windows 中),它将为我提供一些内存持久性,以便从崩溃事件中恢复。

【问题讨论】:

    标签: c# .net windows persistence shared-memory


    【解决方案1】:

    您可以使用来自Microsoft Enterprise Library 的持久缓存块。

    它是可配置的,您可以使用许多后备存储,例如数据库和隔离存储。

    【讨论】:

      【解决方案2】:

      我知道您说过您不想通过将内容持久化到磁盘来使事情变得过于复杂,但是将内容持久化到共享内存或此处列出的任何解决方案肯定会变得更加复杂。这么多应用程序使用数据库或文件存储的原因是因为它是最简单的解决方案。

      我建议您将所有状态保存在单个对象或对象层次结构中,将此对象序列化为 XML 并将其写入文件。真的没有比这更简单的了。

      【讨论】:

      • 我猜你是对的。我的想法是——这不是一个非常重要的数据,我可以忍受丢失它。如果我可以在我的代码中调整一些东西,让它在我的服务宕机和备份时持久化,而不需要做更多的改变,我会喜欢的。
      • 是的,我不认为你真的有这个选择。您可以定期将其写入磁盘,但不能在服务关闭之前将其持久化 - 例如,如果您的服务器崩溃,则为时已晚
      【解决方案3】:

      您可以使用 Memcached 或 Redis(它也将数据保存在磁盘上,但会自动处理)。

      http://code.google.com/p/redis/

      你也可以看看这个问题:

      Memcached with Windows and .NET

      【讨论】:

      • Memcached 和 Redis 确实很有趣,但我觉得它们会有点矫枉过正。我只需要存储一些对象,其中包含几个字符串和整数。我可以通过磁盘交互来做到这一点,但出于显而易见的原因,我更喜欢内存交互。我一直在寻找 .NET 或 Windows 中的内置功能。
      • 好吧,你可以试一试,然后确定你的感觉是否正确......无论如何,jmservera 使用 Persistenc Caching Block 的建议对你来说可能是一个不错的选择。
      【解决方案4】:

      我不明白为什么坚持到磁盘会更难。

      使用db4o,您可以持久化您已经在使用的实例。

      【讨论】:

      • 持久化到磁盘并不难。我的数据非常简单,我可以轻松地将其序列化到文件中或从文件中序列化,我只是想尽可能避免弄乱磁盘。数据不是那么重要;如果我可以使用它,但在服务不幸重新启动时在短时间内保持内存安全(更安全......),那就太好了。
      • 处理预期的故障情况,避免不必要地使用自动重启,并在极端情况下忽略它,它仍然会崩溃/因为你已经说过,如果盒子重新启动,你不关心丢失数据。
      • 嗯,这是最好的希望 :-) 显然我不会像我不在乎服务是否存在那样进行编码。我会尽我最大的努力保持它,但仍然......但我确实需要权衡持久化数据的成本。
      • 很抱歉,您谈论它的方式有些奇怪。你要么关心数据,要么不关心。如果您关心数据,请坚持下去!盒子会意外关机,你可以指望它。我建议您更新问题并提供有关您的方案的更多信息。
      • 我的推理是这样的——当且仅当它不会在开发时间或运行时产生太多工作时,我才愿意保留数据。否则我不会这样做,我会接受它作为合理的系统限制。我会在问题中说得更清楚。
      【解决方案5】:

      如何使用隔离存储并以这种方式将对象持久化到内存中?

      【讨论】:

      【解决方案6】:

      例如,即使您将数据保存在其他联网电脑的共享内存中,您如何“保证”联网电脑不会挂起/重启/暂停/等?在这种情况下,您的服务无论如何都会丢失持久数据。

      我建议,你很可能最终会将数据存储在同一个磁盘上。

      请注意,由于内存 (RAM) 的易失性,您无法在系统重新启动之前重新加载之前存在的数据;除非您使用某种机制在磁盘上存储/重新加载,否则不会。

      --编辑--

      那么,使用MSMQ 怎么样?因此,您可以将所有内容推送到队列中,即使您的服务重新启动,它也会查找队列中的项目并继续前进。

      【讨论】:

      • 如果同一台 PC 重新启动,我不再需要持久数据。我只想介绍我的服务崩溃并自动重启的极端情况。
      猜你喜欢
      • 2021-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多