【问题标题】:Azure Functions updating a Table Storage entity, concurrency problemAzure Functions 更新表存储实体,并发问题
【发布时间】:2020-01-29 13:05:49
【问题描述】:

首先,这可能最终成为一个菜鸟问题,但仍然......我正在努力为这个概念找到一个好的解决方案,而谷歌对我来说并不奏效。

我正在使用 Azure Functions 创建导入。将 BLOB 上传到 BLOB 存储容器时触发函数。该函数读取文件,并将每个导入条目传递到验证队列中。当验证失败时,实体将被传递到失败队列。验证成功后,实体将在成功队列中排队。

另一个函数读取成功队列并开始将实体写入表存储。当该进程失败时,实体将被排入失败队列。

处理和存储失败队列中的实体,以便用户知道出了什么问题,并存储原始导入数据,以便用户修复错误。

在我看来,这是实现带函数的导入过程的最佳方式。这是很多功能,我知道...但它们都有一个单一的职责(例如读取文件、验证等)。

现在我的问题是,当实体存储成功或失败实体存储成功时,我还会向状态队列发送一条消息,告知某个实体的导入是否成功。另一个 Azure 函数处理该状态队列并使用最新状态更新表存储中的单个条目。导入状态如下所示:

CorrelationId <-- The import identifier
StartedAt (date time)
TotalEntries (int)
Succeeded (int)
Failed (int)
CompletedAt (date time)

显然,对于队列中的每条消息,Succeeded 或 Failed int 都会增加一个。此外,当队列大小增加时,AZ Functions 实例的数量也会增加,并且更多的函数开始同时更新表存储条目,从而导致错误。我可以选择使用 ETag,这会导致一些队列条目失败(而且速度很慢!!),或者我可以将 ETag 设置为“*”,这会使过程更快,但我只是错过了数据。您应该如何处理/解决这种情况?

非常感谢!

【问题讨论】:

  • 这个状态表需要实时更新还是可以批量更新?
  • 我真的很喜欢实时,因为我想向用户提供过程的反馈(使用 SignalR 推送更新)

标签: c# azure azure-functions azure-table-storage


【解决方案1】:

Azure 表存储不是处理此类场景的最佳选择。您应该在 SQL 数据库或 Cosmos DB 上创建您的物化视图,以便更好地处理并发/事务。

作为另一种选择,您可以使用事件中心/流分析为您提供实时统计信息。

【讨论】:

    【解决方案2】:

    不是真正回答您的问题,而是将其视为一些“深思熟虑”:)。

    您可以做的是创建一个表(我们称之为StatusTracker),您将在其中存储每个操作的状态。这将是一个简单的表,其中PartitionKey 作为日期/时间的刻度(或反向刻度)表示(您可以将其设置为分钟粒度,以便将一分钟的数据存储在单个分区中),RowKey 是唯一的操作的 id,然后是状态属性,告诉您操作是失败还是成功。您可以使用此表向用户提供近乎实时的反馈。由于您总是在此表中插入记录,因此不会遇到并发问题。

    然后你可以编写另一个函数(哦,不!......不是另一个函数:)),它将被定时器触发(例如每 5 分钟运行一次)。它将做的是查询第一个表(StatusTracker),汇总数据并更新您的状态表。由于此表仅由单个函数更新,因此您也不会遇到并发问题。

    【讨论】:

    • 我想到了这个,这确实不是我问题的答案。大多数导入(在我的情况下)最多需要 30 到 60 秒。在这种情况下,必须将计时器触发器设置为 5 或 10 秒才能提供“真实”的反馈。但对于没有运行导入进程的 99.999 % 的时间来说还不够......
    猜你喜欢
    • 2014-05-14
    • 2013-06-05
    • 2017-10-29
    • 2016-09-19
    • 1970-01-01
    • 2011-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多