背景:File upload
我的场景:我需要上传大量的文件到Azure blob,可能有10,000到100,000个文件。每个文件大小为10KB-50KB。
我在上面的讨论中使用了解决方案,我看到文件正在快速上传,然而,我有如此多的文件,以至于我发现我的应用程序导致非常高的CPU使用率,总是100%…更糟糕的是,下一步我需要运行数百个进程,我的意思是我需要运行数百个进程,每个进程需要上传10,000个或更多文件。到目前为止,我已经测试过它,毫不夸张地说,我看到了许多奇怪的问题,比如异常“连接已关闭”等。
你们有没有办法减少任务的CPU使用率...
发布于 2012-10-13 04:24:27
在这里,我看到的问题是,你旋转了太多的线程,以至于你只需要管理所有排队的线程,即使从技术上讲,它们并不试图同时运行所有线程,也会使机器资源超载。它们将占用RAM,在没有RAM的情况下,将使用交换空间-这将使机器在一片不光彩的火焰中停机。
我会使用一个队列(天蓝色队列,msmq,Systems.Collections.Queue)来排队所有的对象,使用有限数量的线程,这些线程将使用你的后台链接中描述的异步方法来处理文件,然后线程完成对队列中下一项的检查,并处理该项。我的建议是使用非内存队列-我将在下面解释。主要的好处是节省了内存,这样你的软件就不会因为队列太大而崩溃或变慢。
Parallel.ForEach等非常节省时间,但当您处理大量项目时,可能会真正破坏机器的性能-如果机器宕机,您将无法恢复,除非您在某个地方设置了检查点。使用持久队列不仅允许您正确管理机器资源,还允许您正确管理进程中的位置。
然后,您可以通过使用持久队列(如MSMQ )或Azure queues (如果在云中,则为Azure queues)将其扩展到多台计算机。如果您使用检查azure队列有多大的服务,您甚至可以不时地启动实例,以减少负载,然后终止额外的实例。
这是我要实现的场景:
检测到新文件/批处理时使用标准ThreadPool大小-每次在队列(如果内存队列)中插入新项目时,提交到队列都会触发事件。让进程检查队列(如果是持久队列)如果队列中有新项目,首先检查ThreadPool中是否有空间如果没有则忽略(使用窥视方法,这样就不会删除项目)-如果有空间进程线程(在ThreadPool下运行)应该执行,则向ThreadPool添加工作线程,然后检查队列中是否有其他项目-如果没有,线程会死,这很好
使用这种方法,你可以在一台机器上运行,也可以在50,000台机器上运行--只要你在一台以上的机器上使用持久队列,就不会有任何问题。当然,如果你正在使用Azure队列,请确保你做了适当的重复项测试工作,因为你可能会被交给另一台机器的排队项。
这是一种简单的方法,可伸缩,如果使用持久队列(甚至是文件系统),则可以从故障中恢复。但是,它不会通过强制机器管理具有1个million+项的ThreadPool来滥用资源,从而使机器过载。
希望这能有所帮助
发布于 2012-10-13 04:31:53
简单地说,使用线程池实现,假设有20个线程(因为这可能大约是您的网络带宽可以同时处理的),每次上传需要2-3秒,大约需要4-5个小时,这是可以接受的。请确保您没有在上传之间共享存储或容器实例,这可能会导致“连接已关闭”错误。
发布于 2013-03-12 16:00:22
我是一名Microsoft技术布道师,我已经开发了一个样本和免费工具(不支持/不保证)来帮助这些场景。
二进制文件和源代码可以在这里找到:https://blobtransferutility.codeplex.com/
Blob传输实用程序是一种GUI工具,可将数千个小/大文件上传到Windows Azure Blob存储,或从Windows Azure Blob存储下载数千个小/大文件。
功能:
upload/download
第一个和第三个特性是您问题的答案。
您可以从示例代码中了解我是如何做到这一点的,或者您可以简单地运行该工具并执行您需要做的事情。
https://stackoverflow.com/questions/12855626
复制相似问题