【问题标题】:Building a scalable server构建可扩展的服务器
【发布时间】:2023-04-24 22:28:01
【问题描述】:

所以我正在开发一个服务器应用程序,它必须存储数十万(在某些情况下多达几百万)的类,将它们序列化到 SQL 数据库,然后多次加载它们,看起来将这么多类对象存储到列表中会引发内存不足异常吗?我想。

这就带来了问题

  • 如何在仍然处理我所有的大约数百万个课程的同时避免此类错误?
  • 拥有这么多数据还会带来其他问题吗?
  • 我还能做些什么来确保我的服务器完全可扩展并最终能够处理和管理尽可能多的数据?

这个问题的重点是,我需要这么多类都在内存中运行,因为我需要不断更新它们,这比我想序列化到 SQL 数据库要花费更长的时间。现在,目前,我使用的内存比我最终需要的还要少!

【问题讨论】:

  • 你能添加你正在使用的数据结构吗?通过一些智能优化,很有可能将您的数据消耗减少一半(完全猜测)。
  • 你的设计,有问题。
  • @Will - 除了明显的内存不足异常,这取决于。如果他正在构建一个旨在为所有这些数据提供内存的服务,那么一般方法可能不会有那么大的问题。

标签: c# .net scalability out-of-memory


【解决方案1】:

您可能指的是对象,而不是类;-)

一个可扩展的处理架构通常包括以下内容:

在任何时间点,内存中只有有限数量的对象(可能是一个,可能是十个,可能是一百个,但如果它必须是“我需要多少”,那么您必须重新考虑你的设计)。这可确保您永远不会耗尽内存,因为最大内存使用量是固定的。

所有对象都存储在数据库中。当您需要一个不在内存中的对象时,请从数据库中加载它。除非它是前面提到的对象短列表的一部分,否则不要保留它。

要利用您的短列表未使用的内存,请在您的代码和数据库之间插入一个缓存层,这样如果您最终多次获取相同的对象,这样做的成本将会降低。缓存策略意味着您的软件只会在有可用内存的情况下以内存换取速度。

尝试使用读取一些内容、写回一些内容然后重新开始的小事务来工作。如果在处理过程中发生崩溃或中断,这有助于您的软件从其离开的地方恢复。数据库应该足以从它离开的地方重新开始。

通过使用独立的事务,可以让多个工作进程(在同一台计算机上或在计算网格上)在同一个数据库上工作。如果可以的话,实现一个基于事务工作者的模型对性能很有好处,并且可以更容易地让更多的计算机解决问题。

【讨论】:

    【解决方案2】:

    首先,显而易见:确保您有足够的 RAM。分析您的代码以找出(大约)您将同时在内存中拥有多少个对象,然后使用内存分析器。请参阅此相关问题:How much memory does a C#/.NET object use?

    其次,如果您真的需要数百万个对象,重新考虑您的设计可能是有意义的。在许多情况下,像大型多维数组这样简单的东西可能比复杂的 .net 类树更有效(并且在内存方面更可预测)。这个建议是否适用于你的情况,我不能用手头的数据说。

    第三,如果不需要将所有这些数据同时保存在内存中,那么就不要这样做。 SQL 数据库现在非常快(并且使用智能缓存机制),因此在列表中只包含您当前需要的对象(而不是将所有内容加载到内存中)可能是有意义的。此外,搜索一个 SQL 数据库索引甚至可能比遍历一个巨大的内存列表更快。

    【讨论】:

    • 其实可能需要。我有类似的应用程序...但是 64 位。获取数百万个对象的动态更新……所有对象都处于活动状态。 IO 将更改写入数据库,但我必须将活动副本保留在内存中。我扫描多重来源,其中一个有大约 160 万个项目,每秒处理大约 400.000 次更新。
    【解决方案3】:

    可能值得缓存一些经常读入 Memcached 之类的数据库数据。 http://en.wikipedia.org/wiki/Memcached

    【讨论】:

      最近更新 更多