简体   繁体   English

如何确定为什么并行运行的持久函数仍然很慢

[英]How to identify why durable functions running in parallel are still slow

We have the following function which splits a task into separate functions (Fan Out)我们有以下 function 将任务拆分为单独的函数(扇出)

[FunctionName("process-orchestration")]
public async Task ProcessOrchestrationAsync(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var runProcessEvent = context.GetInput<RunProcessDto>();

    var processStartedAt = context.CurrentUtcDateTime;

    // 1. Initialise process

    var initialiseProcessResponseDto = await context.CallActivityAsync<InitialiseProcessResponseDto>
        ("initialise-process-activity", );

    // 2. Run process segment tasks in parallel

    var tasks = new List<Task<RunProcessSegmentResponseDto>>();
    foreach (var runProcessRequestDto in initialiseProcessResponseDto.RunProcessRequestDtos)
    {
        var subTask = context.CallActivityAsync<RunProcessSegmentResponseDto>("run-process-segment-activity", runProcessRequestDto);
        tasks.Add(subTask);
    }

    await Task.WhenAll(tasks);

    // 3. Aggregate results

    var runProcessSegmentResponseDtos = new List<RunProcessSegmentResponseDto>();

    foreach (var eachTask in tasks)
    {
        var taskResult = eachTask.Result;
        runProcessSegmentResponseDtos.Add(taskResult);
    }

    var aggregateProcessResultDto = new AggregateProcessResultDto()
    {
        RunProcessRequestDto = new RunProcessRequestDto()
        {
            NoOfDays = runProcessEvent.NoOfDays,
        },
        RunProcessSegmentResponseDtos = runProcessSegmentResponseDtos
    };
    var runProcessResponseDto = await context.CallActivityAsync<RunProcessResponseDto>("aggregate-process-result-activity", aggregateProcessResultDto);

    // 4. Finalise process

    runProcessResponseDto.ProcessStartedAt = processStartedAt;
    runProcessResponseDto.ProcessFinishedAt = context.CurrentUtcDateTime;
    await context.CallActivityAsync<RunProcessResponseDto>("finalise-process-activity", runProcessResponseDto);
}

This takes a date range and splits into segments这需要一个日期范围并分成几个部分

Each segment is then processed in parallel然后并行处理每个段

After all segments are processed, the results are combined, this process is fine所有segment处理完之后,再合并结果,这个过程就可以了

However, when I look at the breakdown of the segments there are some segments that take a really long time to run, even though they dont have many days然而,当我查看分段的细分时,有些分段需要很长时间才能运行,即使它们没有很多天

Start date: 03/07/2022 
End date: 01/10/2022 
No of days: 90

Diagnostic started: 01/10/2022 10:02:48 GMT 
Diagnostic finished: 01/10/2022 11:41:51 GMT

Segment start date: 03/07/2022
Segment end date: 18/07/2022 
Segment started at: 01/10/2022 10:02:48
Segment finished at: 01/10/2022 11:41:36

Segment start date: 19/07/2022
Segment end date: 03/08/2022 
Segment started at: 01/10/2022 10:02:48
Segment finished at: 01/10/2022 11:37:26

Segment start date: 04/08/2022
Segment end date: 19/08/2022 
Segment started at: 01/10/2022 10:02:48
Segment finished at: 01/10/2022 11:35:59

Segment start date: 20/08/2022
Segment end date: 04/09/2022 
Segment started at: 01/10/2022 10:02:48
Segment finished at: 01/10/2022 11:17:13

Segment start date: 05/09/2022
Segment end date: 20/09/2022 
Segment started at: 01/10/2022 10:02:48
Segment finished at: 01/10/2022 10:19:05

Segment start date: 21/09/2022
Segment end date: 01/10/2022 
Segment started at: 01/10/2022 10:02:48
Segment finished at: 01/10/2022 10:14:03

I tried to scale the function up to be the max power premium function and the timings are no different (this was in place for the timings above)我试图将 function 扩展为最大功率溢价 function 并且时间没有什么不同(这适用于上面的时间)

I also added this to my host.json in case there are too many segments being run in parallel我还将此添加到我的 host.json 以防并行运行的段太多

"extensions": {
    "durableTask": {
      "hubName": "%HubName%"
    },
    "maxConcurrentActivityFunctions": 5,
    "maxConcurrentOrchestratorFunctions": 5
  },
  "functionTimeout": "-1"

Are there any considerations that I have missed when doing this?这样做时我是否遗漏了任何注意事项?

Cheers干杯

Paul保罗

maxConcurrentActivityFunctions and maxConcurrentOrchestratorFunctions should be inside durableTask section. maxConcurrentActivityFunctionsmaxConcurrentOrchestratorFunctions应该在durableTask部分内。

"extensions": {
  "durableTask": {
    "hubName": "%HubName%",
    "maxConcurrentActivityFunctions": 5,
    "maxConcurrentOrchestratorFunctions": 5
  },
},
"functionTimeout": "-1"

I've faced the similar issue and at the end I used App Service Plan with a fixed set of VM instances and auto-scale rules.我遇到过类似的问题,最后我使用了具有一组固定的 VM 实例和自动缩放规则的 App Service Plan。

Not very serverless but with more control over the resources that app uses.不是很无服务器,但可以更好地控制应用程序使用的资源。

Hosting plans 托管计划

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM