Performance 使用并行编程存储数据

Performance 使用并行编程存储数据,performance,memory-management,out-of-memory,task-parallel-library,parallel.foreach,Performance,Memory Management,Out Of Memory,Task Parallel Library,Parallel.foreach,要求如下: Dim opts As New ParallelOptions opts.MaxDegreeOfParallelism = System.Environment.ProcessorCount Parallel.ForEach(dealList, opts, Sub(deal) If Len(deal) > 0 Then

要求如下:

Dim opts As New ParallelOptions
opts.MaxDegreeOfParallelism = System.Environment.ProcessorCount
Parallel.ForEach(dealList, opts, Sub(deal)
                                                 If Len(deal) > 0 Then
                                                     Dim dealPass As String = ""
                                                     Try
                                                         If dealPassDict.ContainsKey(deal.ToUpper) Then
                                                             dealPass = dealPassDict(deal.ToUpper)
                                                         End If
                                                         Dim p As New Process()
                                                         p.StartInfo.FileName = "E:\IGB_New\CMBS Intex Data Deal v2.0.exe"
                                                         p.StartInfo.Arguments = deal & "|" & keycode & "|" & dealPass & "|" & clArgs(1) & "|"
                                                         p.StartInfo.UseShellExecute = False
                                                         p.StartInfo.CreateNoWindow = True
                                                         p.Start()
                                                         p.WaitForExit()
                                                     Catch ex As Exception
                                                         exceptions.Enqueue(ex)                                                             
                                                     End Try
                                                 End If
                                             End Sub)
我们有一个第三方客户机,我们需要从那里获取数据并存储在数据库中(最终)

<客户端>通过DLL的函数(DLL是由C++代码构建),我们需要调用这些函数,并得到相应的结果。
Declare Function wcmo_deal Lib "E:\IGB\System\Intex\vcmowrap\vcmowr64.dll" (
    ByRef WCMOarg_Handle As String,
    ByRef WCMOarg_User As String,
    ByRef WCMOarg_Options As String,
    ByRef WCMOarg_Deal As String,
    ByRef WCMOarg_DataOut As String,
    ByRef WCMOarg_ErrOut As String) _
     As Long

wcmo_deal(wcmo_deal_WCMOarg_Handle, WCMOarg_User, WCMOarg_Options, WCMOarg_Deal, WCMOarg_DataOut, WCMOarg_ErrOut)
这里WCMOarg_DataOut是我们获得的数据,需要存储

与上述方法类似,我们还有10个方法(总共11个方法)用于提取数据,并且数据(每个字符串约为500 KB到1 MB)使用以下方法存储在文件中:

File.WriteAllText(logPath & sDealName & ".txt", sDealName & " - " & WCMOarg_ErrOut & vbCrLf)
现在,这些方法调用将针对每个交易运行。因此,对于单个交易,我们在11个不同的文件夹中获得输出,文本文件与从客户端接收的数据一起存储

总共有5000笔交易,我们需要调用这些方法,数据存储在文件中

此功能的实现方式是使用具有主子关系的并行编程,如下所示:

Dim opts As New ParallelOptions
opts.MaxDegreeOfParallelism = System.Environment.ProcessorCount
Parallel.ForEach(dealList, opts, Sub(deal)
                                                 If Len(deal) > 0 Then
                                                     Dim dealPass As String = ""
                                                     Try
                                                         If dealPassDict.ContainsKey(deal.ToUpper) Then
                                                             dealPass = dealPassDict(deal.ToUpper)
                                                         End If
                                                         Dim p As New Process()
                                                         p.StartInfo.FileName = "E:\IGB_New\CMBS Intex Data Deal v2.0.exe"
                                                         p.StartInfo.Arguments = deal & "|" & keycode & "|" & dealPass & "|" & clArgs(1) & "|"
                                                         p.StartInfo.UseShellExecute = False
                                                         p.StartInfo.CreateNoWindow = True
                                                         p.Start()
                                                         p.WaitForExit()
                                                     Catch ex As Exception
                                                         exceptions.Enqueue(ex)                                                             
                                                     End Try
                                                 End If
                                             End Sub)
其中CMBS Intex Data Deal v2.0.exe是子代码,当deallist包含5000笔交易时,该子代码将执行5000次

CMBS Intex Data Deal v2.0.exe代码包含调用DLL并将数据存储在上述文件中的代码

面临的问题:

  • 代码运行时将主代码和子代码放在一个地方,但在3000次交易后,我们出现了内存不足异常。[对于32 GB RAM,处理器计数=16]
  • 上面的代码(主-子代码)也占用了大量内存,它在一小时内可以正常运行多达4800个事务(在4800个事务左右时,内存使用率逐渐达到100%),而对于剩余的200个事务,则需要将近1个小时(总共2个小时)。[对于32 GB RAM,处理器计数=16] 尝试主控子对象的原因是假定GC将负责子对象中所有对象的内存处理
  • 数据存储在文本文件中后,运行一个perl脚本并将数据加载到数据库中

    尝试的方法:

    我没有将数据保存在文本文件中然后存储到数据库中,而是尝试将数据直接存储到DB中,而不将它们放入文件中(假设I/O操作消耗大量内存),但这也不起作用,因为DB每次都崩溃/挂起

    注:

  • 与DLL相关的所有句柄都已正确关闭
  • 调用DLL的方法会消耗大量内存,但由于我们无法控制,因此无法减少内存
  • 使用并行方法的原因是,如果我们使用顺序方法,那么获取和加载数据将需要很多小时,并且随着数据不断变化,我们需要每天运行两次,因此需要更新来自客户端的最新数据
  • 也存在CPU最大化问题,但已通过保持MaxDegreeOfParallelism=System.Environment.ProcessorCount解决
  • 问题:

    是否有办法减少流程完成所需的时间。 目前,它需要2小时才能完成,但这可能是因为它达到4800笔交易时没有剩余内存,并且没有任何内存,它无法进一步处理。
    有没有一种方法可以通过尝试不同的执行方式来减少内存消耗,或者如果在同一代码中进行更改,会有一些东西可以使其工作?

    并行性很可能完全没有用处。您受到IO的约束,而不是CPU的约束。IO是瓶颈,并行化甚至可能使它变得更糟。您可以使用一个实例进行实验,然后将所有输出复制到实际存储器中