Azure功能和缓存

Sil*_*ohn 14 c# caching azure azure-functions

我们计划开发一个Azure函数,其输入触发器是服务总线消息,输出将是blob存储.服务总线消息将包含图像URL,该功能将图像调整为预定义的分辨率,并上传到azure blob存储.

应该调整图像大小的分辨率存储在数据库中,Azure函数需要调用数据库以了解应该在输入消息中用于图像的分辨率.分辨率实际上是基于输入消息源配置的主数据.

进行数据库调用将是一项昂贵的调用,因为每次调用都必须进入数据库.有没有办法缓存数据并在不调用数据库的情况下使用它.喜欢内存缓存?

Mik*_*kov 20

您可以自由使用在其他.NET应用程序中使用的常用方法:

  • 您可以将其缓存在内存中.最简单的方法是声明一个静态字典并将数据库值放入其中(如果需要,使用并发字典).缓存的值将重用于在同一实例上运行的所有后续Function执行.如果实例空闲5分钟,或者App扩展到额外的实例,则必须再次读取数据库;

  • 您可以使用功能代码中的SDK来使用分布式缓存,例如Redis.可能会更好一些,因为你保持函数的无状态特性,但可能会花费更多.表存储是Redis的可行替代方案,但API有限.

Azure函数本身没有"缓存"功能,可以在没有任何额外代码的情况下使用.

  • 不,每次执行后都不会删除功能.如果请求的速度快于每几个(默认为5分钟)分钟,则会重复使用实例. (8认同)
  • 如果函数托管在消费计划中,那么在内存中缓存不是毫无意义吗?函数不会被删除(在每次执行之后??)并且可能会在不同的 VM 中启动,从而使内存缓存不是一种可行的方法? (3认同)
  • @robs 然后,如果您仍然需要缓存(它仍然有意义吗?),您唯一的选择是进程外缓存 (3认同)
  • 或设置一个计时器来触发一个实际上只是称为“ Ping”的功能。您的整个应用程序都是卸载的单元,因此调用“ Ping”将使其保持活动状态。从技术上讲,我不知道这与他们的服务条款相符。 (2认同)
  • 实际上距离消耗计划上的最后一个空闲实例被杀死还有 20 分钟。它不适用于固定或保费计划。 (2认同)

小智 7

Redis 是内存缓存,并且您可以使用自定义输出绑定来保持函数干净:

[FunctionName("SetPoco")]
public static async Task<IActionResult> SetPoco(
    [HttpTrigger("POST", Route = "poco/{key}")] HttpRequest request,
    [Redis(Key = "{key}")] IAsyncCollector<CustomObject> collector)
{
    string requestBody;
    using (var reader = new StreamReader(request.Body))
    {
        requestBody = reader.ReadToEnd();
        var value = JsonConvert.DeserializeObject<CustomObject>(requestBody);
        await collector.AddAsync(value);
    }
    return new OkObjectResult(requestBody);
}
Run Code Online (Sandbox Code Playgroud)

项目链接: https: //github.com/daulet/Indigo.Functions#redis

但是,如果内存中的缓存是指函数的内存中,我强烈建议否则,因为函数是无状态的,并且您将无法在运行函数的多个主机之间共享该内存。Azure Functions 最佳实践中也不建议这样做

  • 我可以理解为什么您在这种特定情况下建议反对状态(像这样的主设置是状态,可以保存在设置中而不是数据库中),但恕我直言,一般来说,缓存被认为是性能优化而不是状态。该函数仍然是无状态和幂等的,它只是避免每个传入的请求都访问数据库。 (4认同)

use*_*268 5

您可以使用Azure缓存服务(https://azure.microsoft.com/en-us/services/cache/)来缓存数据。基本上,在您的Azure函数中,而不是一直调用数据库,请调用Azure缓存并使用它是否未过期,是否已过期或未设置,然后调用数据库以获取值并使用适当的过期逻辑填充缓存(超时后固定时间或其他自定义逻辑)。

  • 不过它并不便宜:/ (3认同)

小智 5

您可以使用Durable Functions并通过活动或子业务流程进行数据库调用,返回值实质上是为您缓存的,然后将在每次函数重播时返回而不会再次进行基础调用。