Azure functions 为ETL过程使用Azure持久功能

Azure functions 为ETL过程使用Azure持久功能,azure-functions,azure-durable-functions,Azure Functions,Azure Durable Functions,我有以下情况: 我必须执行一个函数来检索N条(N条介于0和无限之间)记录。我必须调用一个映射函数来将记录转换为其他内容并将其向前移动(通过http、服务总线、cosmos db等) 由于10分钟的限制,我无法使用常规Azure函数,因此我正在寻找持久函数是否可以解决我的问题 我的想法如下: 1-当持久功能触发时,它将从数据库流式传输记录。 2-对于每个记录,它调用映射函数。 3-映射后,它通过服务总线将记录发送到消息 作为概念证明,我做了下面的例子。我模拟在持久函数中接收1000条消息,但它的行

我有以下情况:

我必须执行一个函数来检索N条(N条介于0和无限之间)记录。我必须调用一个映射函数来将记录转换为其他内容并将其向前移动(通过http、服务总线、cosmos db等)

由于10分钟的限制,我无法使用常规Azure函数,因此我正在寻找持久函数是否可以解决我的问题

我的想法如下:
1-当持久功能触发时,它将从数据库流式传输记录。
2-对于每个记录,它调用映射函数。
3-映射后,它通过服务总线将记录发送到消息

作为概念证明,我做了下面的例子。我模拟在持久函数中接收1000条消息,但它的行为非常不可靠。如果我发送1000条消息,函数会崩溃或者需要很长时间才能完成,我希望这段代码几乎能立即完成

#r "Microsoft.Azure.WebJobs.Extensions.DurableTask"

public static async Task<List<string>> Run(DurableOrchestrationContext context, TraceWriter log)
{
    var outputs = new List<string>();

    var tasks = new List<Task<string>>();
    for(int i = 0; i < 1000; i++)
    {
        log.Info(i.ToString());
        tasks.Add(context.CallActivityAsync<string>("Hello", i.ToString()));
    }

    outputs.AddRange(await Task.WhenAll(tasks.ToArray()));

    return outputs;
}
#r“Microsoft.Azure.WebJobs.Extensions.DurableTask”
公共静态异步任务运行(DurableOrchestrationContext,TraceWriter日志)
{
变量输出=新列表();
var tasks=新列表();
对于(int i=0;i<1000;i++)
{
log.Info(i.ToString());
Add(context.CallActivityAsync(“Hello”,i.ToString());
}
outputs.AddRange(wait Task.WhenAll(tasks.ToArray());
返回输出;
}
我的问题是:持久功能是否适合这种情况? 我是否应该研究一些非服务函数方法来从数据库中提取数据


是否有一种从持久函数中调用另一个Azure函数的方法?

在开始之前,你必须考虑持久函数是如何工作的。要了解流程,请查看以下示例:

#r "Microsoft.Azure.WebJobs.Extensions.DurableTask"

public static async Task Run(DurableOrchestrationContext context, TraceWriter log)
{
    await context.CallActivityAsync<string>("Hello1");
    await context.CallActivityAsync<string>("Hello2");
}

这与其说是一个真实的例子,不如说是一个想法,但你应该能够抓住要点。另一个问题是持久功能是否真的是此类操作的最佳解决方案-我相信有更好的服务,例如Azure Data Factory。

此外,您可以在这里详细介绍一步一步的示例

[FunctionName("Orchestration_Client")]
public static async Task<string> Orchestration_Client(
    [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "start")] HttpRequestMessage input,
    [OrchestrationClient] DurableOrchestrationClient starter)
{
    return await starter.StartNewAsync("Orchestration", await input.Content.ReadAsStringAsync());
}

[FunctionName("Orchestration")]
public static async Task Orchestration_Start([OrchestrationTrigger] DurableOrchestrationContext context)
{
    var payload = context.GetInput<string>();
    await context.CallActivityAsync(nameof(Activity), payload);
}

[FunctionName("Activity")]
public static string Activity(
    [ActivityTrigger] DurableActivityContext context,
    [Table(TableName, Connection = "TableStorageConnectionName")] IAsyncCollector<FooEntity> foo)
{
    // Get data from request
    var payload = context.GetInput<string>();

    // Fetch data from database
    using(var conn = new SqlConnection())
    ...

    // Transform it
    foreach(var record in databaseResult) 
    {
        // Do some work and push data
        await foo.AddAsync(new FooEntity() { // Properties });
    }

    // Result
    return $"Processed {count} records!!";
}