首页 > 解决方案 > Azure Durable Framework Function App 非常慢

问题描述

我制作了一个应用程序,它使用 azure 函数持久扇出策略通过向我们自己的内部 API 发送 http 请求来对数据库进行并行查询和更新。

我发现扇出策略比使用TPL 库并在普通的 .net Core webapp 上以这种方式进行并行处理要慢得多。它不仅慢,而且慢了大约 20 倍。130 次更新需要 10 分钟,而我为速度比较而制作的 .net core 3.1 应用程序在 0.5 分钟内完成 130 次更新,而且计划要低得多。

我知道由于持久的框架基础架构(与存储帐户等通信)存在延迟,但我看不出这种速度差异是如何正常的。每个单独的更新都发生在 ActivityTrigger 函数中,并且协调器是收集所有必要更新并将它们放入 Task.WhenAll() 调用中的一个,就像 Microsoft 文档中的示例一样。

我在这里做错了吗?这个业务场景可能与该技术不兼容吗?代码似乎工作正常,并行性工作它只是比 .net 核心应用程序慢很多。另一件要提到的是,当函数打开第二个实例时(由于它处于消耗计划中并且自然地打开第二个实例以处理重负载,或者它处于 appservice 计划中并且我手动打开一个实例)它甚至尽管 cpu 负载在两个实例中以某种方式平衡,但速度较慢。我怀疑这可能是由于两个实例之间的天蓝色队列通信导致的额外延迟,但我不完全确定。

最后一个细节是,该应用程序还有一个 TimeTrigger,它每分钟在数据库中执行一次简单的选择(甚至没有远程 CPU 密集型,但它可能会影响性能)。

我已经在高级计划、消费计划和 appservice 计划中尝试了功能应用程序,无论计划有多大,它似乎在 10 分钟内更新了 130 次。

标签: c#azureazure-functionsazure-durable-functions

解决方案


一般来说,TPL 几乎总是比 Durable Functions 快得多,因为所有协调都是在内存中完成的(假设在一台机器上做所有事情时不会完全耗尽系统资源)。所以这部分通常是预期的。这里有几点值得了解:

  • 活动函数的每个扇出都涉及一组队列事务:一条消息用于调用活动函数,一条消息用于将结果返回给协调器。当涉及多个虚拟机时,您还必须担心队列轮询延迟。
  • 默认情况下,在单核 VM 上,活动函数的每个实例并发限制为 10。如果您的活动函数不需要太多内存或 CPU,那么您需要提高此值以增加每个实例的并发性。
  • 如果您使用的是 Azure Functions Consumption 或 Premium 计划,则需要 15-30 秒才能为您的应用添加新实例。这主要是如果您的工作负载可以通过在多台机器上运行来更快地完成。消息在队列上等待的时间是横向扩展的原因(1 秒被认为太长)。

您可以在Durable Functions Performance and Scale 文档中找到更多详细信息。

我要说的最后一件事是,Durable Functions 的关键增值是在分布式环境中以可靠的方式编排工作。但是,如果您的工作负载不是长时间运行的,不需要严格的持久性/弹性,不需要横向扩展至多个 VM,并且如果您有严格的延迟要求,那么 Durable Functions 可能不是正确的工具。如果您只需要单个 VM 并且想要低延迟,那么使用内存中 TPL 的简单函数可能是更好的选择。


推荐阅读