我有一个生成一些输出的服务器,如下所示: http://192.168.0.1/getJPG= [ID]
我必须通过ID 1到20M。
我看到大部分延迟都在存储文件中,目前我将每个请求结果存储为文件夹中的单独文件。形式为:[ID] .jpg
服务器响应很快,生成器服务器真的很快,但我无法快速处理收到的数据。
存储数据以供以后处理的最佳方法是什么?
我可以做所有类型的存储,比如在DB中,比如在SINGLE文件中,以及稍后解析大文件等。
我可以用.NET,PHP,C ++等编码。编程语言没有限制。请指教。
由于
答案 0 :(得分:2)
因此,您从服务器下载了2000万个文件,并且将它们保存到磁盘的速度是一个瓶颈?如果您通过Internet访问服务器,那很奇怪。也许你是通过本地网络下载的,或者“服务器”甚至可以在本地运行。
要保存2000万个文件,我确信它们不会全部适合RAM,因此缓冲内存中的数据无济于事。如果将数据写入磁盘的最大速度确实是一个瓶颈,那么使用MS SQL或任何其他数据库都不会改变任何内容。关于数据库没有任何“魔力” - 它受到磁盘性能的限制,就像任何其他程序一样。
听起来你最好的选择是使用多个磁盘。并行下载多个文件,并在收到每个文件时,以循环方式将其写入不同的磁盘。你拥有的磁盘越多越好。使用多个线程或非阻塞I / O,因此下载和磁盘写入都会同时发生。
答案 1 :(得分:1)
为了有效地做到这一点,我会多线程你的应用程序(c ++)。
应用程序的主线程将生成这些Web请求并将它们推送到std :: list的后面。这是你的所有主要应用程序线程都会做的。
Spawn(并保持运行,不要反复生成)一个pthread(我首选的线程方法,甚至在windows上......)并将其设置为在while循环中检查相同的std :: list。在循环中,确保检查列表的大小,如果有要处理的事项,请从列表中弹出前项(这些可以在不同的线程中完成,而不需要互斥锁...大多数时候。 ..)并将其写入磁盘。
这将允许您在内存中排队响应,同时将文件异步保存到磁盘。如果您的服务器确实像您说的那样快,那么您可能会耗尽内存。然后,如果要处理的项目数超过某个阈值,我会实现一些“等待”,但这只会比连续执行要好一些。
“提高”速度的真正方法是拥有许多工作线程(每个都有自己的std :: list和'smart'推送到列表中的项目最少或者一个std :: list共享一个互斥)处理文件。如果你有一台带有多个硬盘的多核机器,这将大大提高将这些文件保存到磁盘的速度。
另一种解决方案是将文件保存卸载到许多不同的计算机上(如果当前计算机上的磁盘数量限制了写入)。通过使用消息传递系统(如ZMQ / 0MQ),您可以非常轻松地将文件保存到不同的系统(以PULL方式设置),可以访问更多硬盘驱动器,而不仅仅是当前使用的硬盘驱动器。一台机器。使用ZMQ使循环风格的消息变得微不足道,因为内置扇出架构并且实际上只需几分钟即可实现。
另一个解决方案是创建一个ramdisk(在linux上本地很容易完成,对于windows ...我使用了this)。这将允许您将文件的写入与您想要的任意数量的编写器并行化而没有问题。然后,您需要确保在重新启动之前将这些文件复制到实际存储位置,否则您将丢失文件。但在运行期间,您可以毫无问题地实时存储文件。
答案 2 :(得分:1)
顺序访问磁盘可能会有所帮助。这是一个简单的技巧:将所有传入的文件流式传输到未压缩的ZIP文件(有用于此的库)。这使得所有IO顺序并且只有一个文件。您还可以在10000张图像之后拆分新的ZIP文件,以保持单个ZIP的小。
您可以稍后通过流式传输ZIP文件来读取所有文件。那里的开销很小,因为它没有压缩。
答案 3 :(得分:1)
听起来您正在尝试编写一个尽可能快地下载尽可能多的内容的应用程序。您应该知道,当您这样做时,人们可能会注意到这会吸收大量带宽和其他资源。
由于这是Windows / NTFS,因此您需要记住一些事项: - 一个文件夹中的文件不能超过2k。 - 尽可能使用异步/缓冲写入。 - 尽可能多地传播可用于获得最佳I / O性能的磁盘。
未提及的一件事有点重要的是文件大小。由于看起来你正在获取JPEG,我假设平均文件大小约为50k。
我最近做了类似这样的事情,使用.Net 4.0循环播放了大约1KB的文本文件,并且能够在本地网络上使100mbit网络控制器饱和。我使用TaskFactory生成HttpWebRequest线程以将数据下载到内存流。我把它们缓存在内存中,所以我没有把它们写到磁盘上。我建议的基本方法是类似的 - 旋转每个发出请求的线程,获取响应流,并将其写入磁盘。最难的部分是生成顺序文件夹和文件名。您希望尽快执行此操作,使其保持线程安全,并在内存中进行簿记,以避免因不必要的目录内容调用而占用磁盘。
我不担心尝试对你的写作进行排序。有足够的OS / NTFS层可以为您尝试这样做。你应该立刻让你的管道饱和。