当前位置: 首页 > 知识库问答 >
问题:

语言工作者如何使用Python在Azure Functions中工作?

越风史
2023-03-14

我正在使用Azure函数进行一个ETL项目,在该项目中,我从blob存储中提取数据,在Python和pandas中转换数据,并使用pandas将数据加载到_sql()。我试图通过使用异步IO和语言工作者来提高这个过程的效率。

我有点困惑,因为我的印象是asyncio使用一个线程工作,但Azure Functions文档说如果你改变配置,你可以使用多个语言工作者,甚至一个不使用async关键字的方法也在一个线程池中运行。

这是否意味着如果我不使用async关键字,我的方法将使用语言工作者并发运行?我必须使用asyncio来利用语言工作者吗?

此外,该文档还指出,Azure函数可以扩展到200个实例。如果只允许最多10名语言工作者,我如何扩展到这么多实例?

编辑:谢谢阿纳托利。澄清一下,如果我有一个定时器触发器,代码如下:

import azure.functions as func
from . import client_one_etl
from . import client_two_etl

def main(mytimer: func.TimerRequest) -> None:
    client_one_etl.main()
    client_two_etl.main()

如果我增加了语言工作者的数量,这是否意味着< code > client _ one _ ETL . main()和< code > client _ two _ ETL . main()即使不使用< code>asyncio也会自动在单独的线程中运行?如果< code > client _ two _ ETL . main()需要< code > client _ one _ ETL . main()在执行前完成,我将需要使用< code>async await来防止它们并发运行?

对于单独的实例,如果client_one_etl.main()client_two_etl.main()不相互依赖,这是否意味着我可以将它们作为单独的. py脚本在一个Azure Function应用程序中执行,并在它们自己的VM中运行?是否可以运行多个定时器触发器(在各自的VM中为一个Azure Function调用多个__init__. py脚本)?如果我在host.json文件中增加FunctionTimeout,则所有脚本都需要在10分钟内完成?

共有1个答案

詹夕
2023-03-14

FUNCTIONS_WORKER_PROCESS_COUNT限制了每个Functions主机实例的最大工作进程数。如果将其设置为10,每个主机实例最多可以同时运行10个Python函数。每个工作进程仍将在单个线程上执行Python代码,但现在您最多可以同时运行其中的10个。您不需要使用asyncio来实现这一点。(话虽如此,使用asyncio来提高可扩展性和资源利用率是有正当理由的,但您不必这样做来利用多个Python工作进程。)

200限制适用于每个函数应用程序的函数主机实例数。您可以将这些实例视为单独的虚拟机。FUNCTIONS_WORKER_PROCESS_COUNT限制分别应用于每个线程,这使并发线程总数达到2000。

更新(回答其他问题):

一旦在某个工作进程上启动函数调用,它将在此工作进程上运行,直到完成。在该调用中,代码执行不会被分发到其他工作进程或函数主机实例,也不会以任何其他方式为您自动并行化。在您的示例中,<code>client_two_etl。main()将在<code>client_one_etl之后启动。main()退出,它将在同一个工作进程上启动,因此无论配置的限制如何,您都不会观察到任何并发性(除非您在<code>client_*_etl.main()中执行了一些特殊操作)。

当多个调用几乎同时发生时,这些调用可能会自动分配给多个辅助角色,这就是上面提到的限制适用的地方。从开始到结束,每个调用仍然只在一个辅助角色上运行。在您的示例中,如果您设法在同一时间两次调用此函数,每个调用都可以获得自己的辅助角色,它们可以并发运行,但每个调用都将按顺序执行client_one_etl.main()client_two_etl.main()

还请注意,因为您在单个函数上使用计时器触发器,所以根本不会遇到任何并发:根据设计,计时器触发器在上一次调用完成之前不会启动新的调用。如果需要并发,可以使用不同的触发器类型(例如,您可以将队列消息放在计时器上,然后由队列触发的函数可以自动扩展到多个工作线程),或者使用多个计时器触发器和多个函数,如您所建议的那样。

如果您实际上想要同时运行独立的< code > client _ one _ ETL . main()和< code > client _ two _ ETL . main(),最自然的做法是从不同的函数调用它们,每个函数都在单独的< code>__init__中实现。py具有自己的触发器,在相同或不同的功能应用程序中。

主机中的函数超时。json应用于每个函数调用。因此,如果应用程序中有多个函数,则每次调用都应在指定的限制内完成。这并不意味着所有这些都应该在这个限制内完成(如果我正确理解您的问题)。

更新2(回答更多问题):

@JohnT请注意,我不是在谈论Function应用程序或___init___. py脚本的数量。函数(由___init___. py描述)是一个定义需要做什么的程序。您可以为每个应用程序创建超过10个函数,但不要这样做来增加并发——这无济于事。相反,将函数添加到分离逻辑独立和连贯的程序中。函数调用是一个主动执行程序的过程,这就是我所说的限制适用的地方。您需要非常清楚函数和函数调用之间的区别。

现在,为了调用一个函数,您需要一个专用于此调用的工作进程,直到此调用完成。接下来,为了运行一个工作进程,您需要一台将托管此进程的机器。这就是Functions主机实例(不是Functions主机实例的非常准确的定义,但对于本讨论的目的来说已经足够好了)。在消耗计划上运行时,您的应用可以横向扩展到200个Functions主机实例,默认情况下它们中的每一个都会启动单个工作进程(因为FUNCTIONS_WORKER_PROCESS_COUNT=1),因此您最多可以同时运行200个函数调用。增加FUNCTIONS_WORKER_PROCESS_COUNT将允许每个Functions主机实例创建多个工作进程,因此每个Functions主机实例最多可以处理FUNCTIONS_WORKER_PROCESS_COUNT个函数调用,从而使潜在总数达到2000个。

但请注意,“可以横向扩展”并不一定意味着“将横向扩展”。有关详细信息,请参阅Azure Functions扩展和托管以及Azure Functions限制。

 类似资料:
  • 问题内容: 我想知道rstrip和lstrip如何在python中工作。说,如果我有一个字符串 剥离单词如何工作? 理想情况下,输出应该是“ thist”(对于第一种情况)和“ that”(对于第二种情况)对吗? 还是像正则表达式一样,匹配每个字符,以及最后看到的哪一个字符都会删除(对于第三种情况)? 注意:我不是在寻找替换,我只是想知道从字符串中删除子字符串时,strip的工作方式。 问题答案:

  • 问题内容: 我对Python引用感到困惑。考虑以下示例: 我的任务: 编辑列表中的每个元素 类似地: 在python中,所有内容都按引用进行操作,那么何时创建新对象?我们总是需要和从模块,使对象副本? 请说清楚。 问题答案: 在Python中,变量不是容纳事物​​的盒子,它是指向对象的名称。在您的代码中: ->将名称绑定到字典 ->将名称绑定到列表 ->将名称绑定到另一个列表 您的第三行不是在改变

  • 假设我有用不同语言编写的工人(Java

  • 我刚刚开始学习python,通过《像计算机科学家一样思考》这本书,我陷入了一些语言语法。 当我使用一些输入(比如7)运行此程序时,会收到如下错误消息: 为什么if语句不能正常工作?即使输入值小于20,它仍会进入第一个if语句

  • 问题内容: 我是Python的新手…并且来自Java的背景,如果可以说明这一点的话。 我正在尝试了解Python中的多态性。也许问题在于我期望将我已经知道的概念投影到Python中。但是我整理了以下测试代码: 从我习惯的多态性(例如java的多态性)来看,我希望这两个语句都能显示为true,因为dog的实例 既是 动物又 是 狗。但是我的输出是: 我想念什么? 问题答案: Python中的运算符检

  • 问题内容: 我已经阅读了python文档中的示例,但仍然无法弄清楚此方法的含义。有人可以帮忙吗?这是python文档中的两个示例 和 参数和目的是什么? 问题答案: 通常,如果你尝试使用字典中当前不存在的键来获取项,则字典会抛出 。该相反只会创建你尝试访问的任何物品(当然前提是他们还不存在)。为了创建这样的“默认”项目,它调用传递给构造函数的函数对象(更确切地说,它是一个任意的“可调用”对象,其中