如何在Web应用程序中将数百万(1000万)字节数组加载到内存中?

时间:2013-12-19 15:11:38

标签: c# asp.net-mvc

我有一个Web应用程序,要求是我们需要将数百万个字节数组加载到内存中,以便将这些数据提供给一个将参数作为IEnumerable的个人sdk方法。问题是将如此大量的文件转换为字节数组(每个文件转换为byte [])。大约有1000万个这样的文件。这些需要大量的时间和内存才能加载。所以如何完成这项任务。任何建议都将不胜感激。

3 个答案:

答案 0 :(得分:7)

这可能不是一个好主意。

最好将数据保存在文件中,在需要时将文件加载到内存中,并保留最近使用的n个文件的缓存。这样你就可以管理你消耗的内存量,你的服务器不会因为你正在做的事情而陷入困境。

你没有提到文件的大小,BTW,但文件系统现在非常快,并且与该缓存结合,性能可能是可以接受的。在尝试任何有趣的内存之前,我会测试这个场景。

答案 1 :(得分:4)

每个2 KB的1000万个文件是20千兆字节的数据。即使它是在单个文件中,也需要大约三分钟的时间来加载典型的每秒100兆字节的磁盘传输速度。但是因为你要打开1000万个单独的文件,所以需要更长的时间。

如果这1000万个文件在一个目录中,则需要更长的时间。当单个目录中有这么多文件时,NTFS的性能不佳。

如果文件在一个目录中,我建议将它们拆分。你最好在一个目录中拥有少于10,000个文件(最好少于1,000个)的文件。创建一个目录层次结构来保存文件。

这仍然让你不得不打开1000万个单独的文件。如果数据不经常更改,则应创建包含文件名和关联数据的单个二进制文件。每次其中一个组成文件发生更改时,您都必须重新创建该文件,但如果其中一个文件发生更改,则必须重新启动应用程序。

但总而言之,我真的不明白为什么要将所有这些数据加载到内存中。如果您的Web应用程序要将此管道传输到某个请求应用程序,则数据传输时间最多与从文件读取数据的速度相同。因此,您最好从文件中读取数据并将其流式传输到请求的应用程序。

如果您的应用程序要求内存为20 GB,以便您可以将其发送到请求应用程序,那么您的应用程序设计可能会出现严重问题。

还有一件事:我记得,IIS不时回收流程。如果您的Web应用程序长时间处于空闲状态,那么IIS可能会很好地从内存中清除它。因此,下次有人向您的应用程序发出请求时,它将不得不重新加载数据。如果您希望数据真正持久,您可能需要一个Windows服务来加载数据并将其保存在内存中。 Web应用程序可以在需要时查询服务以获取数据。

答案 2 :(得分:1)

可预见的问题:

  • 性能:大量文件的顺序序列化可能非常耗时。
  • RAM:有效负载总大小可能会请求大量内存。

可能的解决方案:

  • 分发序列化任务。生成工作线程,为每个线程设置processor affinity,以便均匀分配工作负载。您的磁盘/存储库I / O可能是瓶颈。
  • 实施分页。不要试图在内存中加载所有内容。按需序列化块。只要您的序列化速度快于所需的物理网络带宽,就不会出现“缓冲区欠载”情况 - 在这种情况下,等待服务器应答的空信道。这样,您的进程甚至可能比在开始传输之前尝试进行完全序列化更快地开始回复。
  • 尽可能少地缓存,尽可能少。不要重做昂贵的工作。

那说......

......我完全赞同Roy Dictus和其他人 - 对我来说似乎是一个非常糟糕的模特。