在.Net中设计没有长寿命对象的服务器应用程序?

时间:2012-10-15 07:09:16

标签: .net caching

我有一个使用.Net 4.0的游戏服务器项目。我正在使用MemoryCache类并缓存许多可以​​由多个用户同时修改的对象,以实现快速i / o和同步。最近在游戏发布后,我发现我的设计存在问题。因为这些缓存对象是长寿命对象,所以它们都转到GC gen 2,并且很难被释放,因此gen 2堆非常大(5天后大约8 GB)并且需要太长时间才能完成GC。

经过几天的谷歌搜索,我想也许这是不使用长寿命对象来避免大二代堆的最佳方式。但我不知道该怎么办。这些对象是从db加载的,由用户请求修改,并保存回db,它们太复杂,无法序列化为byte []以保存在memcached中,即使它们可以序列化,(从memcached中读取 - > modify - &gt ;回写)也不是线程安全的操作。

有什么建议吗?

3 个答案:

答案 0 :(得分:0)

这个服务器有必要在内存中本地缓存所有内容吗?如果从服务器连接到数据库,我可以理解为什么会遇到这样的问题以及为什么要将它们缓存在内存中。但是,有许多缓存框架可以跨多个应用程序实例工作,例如Memcached。

当然,它不会像在内存中那样快,但实际上是否存在检索对象的性能问题,或者您是否只是先发现存在速度问题并进行预优化?好像你有,那么你可能会发现,如果你横向扩展你的应用程序并停止在内存中缓存并将责任推到另一个系统,你可能会让每个服务器实例稍微慢一些,但它会更容易和更快地扩展。

答案 1 :(得分:0)

我可以想到一些建议

  • 首先尝试使用Server GC这会将堆分成多个堆(每个处理器一个)并行收集,以提高多个处理器计算机的吞吐量。这可能有助于彻底解决您的问题。
  • 如果这没有帮助,并且你的第2代堆仍然需要很长时间才能收集,那么你应该考虑使用某种外部缓存框架(如Memcached)。如果不了解更多细节,这可能是我的首选方法。
  • 或者,您可以考虑使用object pool并重新使用现有对象,而不是分配和取消分配新对象。

我能想到的唯一其他解决方案是像redirecting to another server server when a full GC is about to happen这样的事情(完整GC即将发生的通知是.Net 3.5 SP1特性)但是这可能比上面的第二个更复杂选项。

答案 2 :(得分:0)

为什么不为缓存对象配置生命周期?可能没有必要存储那么多未使用N小时/天的对象。

如果没有帮助,则需要更改缓存机制。此外,当您需要存储如此大量的对象和如此长的时间,那么您需要多个服务器。您可以使用内部托管或云,对于它们两者,都有称为分布式缓存的缓存机制。在.NET的前提下,它可以是使用Windows Azure的云中的AppFabric Cache - 也非常类似于AppFabric。

所以,当生命时间没有帮助时,我建议你使用云中的分布式缓存(Windows Azure,亚马逊AWS)或内部部署(AppFabric)