使用 Azure 处理大量数据



我们有一个应用程序,随着时间的推移,它为我们的用户存储了大量的数据(这里谈论数百TB或更多)。由于新的欧盟指令,如果用户决定停止使用我们的服务,他们的所有数据必须在接下来的 80 天内可供导出,之后必须完全根除。数据存储在 Azure 存储块 blob 中,元数据存储在 sql 数据库中。

遗憾的是,数据不能按原样导出(它是专有格式),因此需要对其进行处理并将其转换为PDF以进行导出。一个文件的大小约为 240KB,因此想象一下上述 TB 值的 PDF 数量。

我们尝试使用函数将工作拆分为微小的 50 个值块,但它在某个时候变得混乱并产生了巨大的成本,失控了。

所以我们正在寻找的是这个:

  • 可以从 Web 触发器/队列/数据库条目按需运行
  • 是按使用量付费,因为这会在随机时间发生,并且(所以我们希望)很少发生。
  • 能够以最低的成本相当有效地处理大量数据
  • 易于维护和跟踪。函数作业只是火和祈祷 - 完全混乱 - 由于它们的数量和并行处理。

有谁知道符合我们要求的服务?

以下是 .NET、python 或 node.js 的入门链接: https://learn.microsoft.com/en-us/azure/batch/batch-dotnet-get-started

批量的概念非常简单,尽管根据我的经验,第一次需要一些摆弄才能让它工作。我将尽我所能解释它涉及的内容。欢迎任何建议或意见。

以下概念很重要:

  1. 游泳池。这是预配以执行工作的所有节点(即虚拟机)的抽象。这些可以运行Linux,Windows Server或Azure拥有的任何其他产品。可以通过 API 预配池。
  2. 乔布斯。这是一个抽象,您可以在其中放置需要执行的"任务"。每个任务都是可执行文件的命令行执行,可能带有一些参数。

您的任务由池中的可用节点逐个选取,并执行任务指定的命令。节点上可用的是可执行文件和分配给任务的文件,其中包含一些标识数据,例如,任务应处理哪些用户。

因此,假设您需要为 100 个用户执行处理。每个单独的处理作业都是您创建的某些可执行文件的执行,例如 ProcessUserData.exe。 例如,假设您的可执行文件除了 userId 之外,还包含一个参数,指定是否应该在 test 或 prod 中执行此操作,例如 ProcessUserData.exe"包含要处理的用户 ID 的文件的路径" --环境测试。 我们假设您的可执行文件不需要除用户 ID 和执行处理的环境之外的其他输入。

  • 将所有应用程序文件上传到 Blob(在下文中名为"应用程序 Blob")。这包括您的主可执行文件以及任何依赖项。预配后,所有内容最终都会显示在池中每个节点(虚拟机)上的文件夹中。该文件夹通过池中每个节点上创建的环境变量进行标识,以便您可以轻松找到它。 见 https://learn.microsoft.com/en-us/azure/batch/batch-compute-node-environment-variables
  • 在此示例中,您将创建 10 个输入文件,每个文件包含 10 个应处理的用户 ID(总共 100 个用户 ID)。每个命令行任务对应一个文件。每个文件可以包含 1 个用户 ID 或 10 个用户 ID,这完全取决于您希望主可执行文件如何解析此文件并处理输入。将这些内容上传到"输入"Blob 容器。 这些也将在每个节点上的环境变量标识的目录中,因此也很容易在每个节点上的命令行活动中构造路径。

上传到输入容器后,您将收到每个输入文件的引用(资源文件)。一个输入文件应与一个"任务"相关联,并且每个任务在作业执行时传递到可用节点。

如何做到这一点的细节在入门链接中很清楚,我试图专注于概念,所以我不会详细介绍。

现在,您可以创建要执行的任务 (CloudTask),指定它应在命令行上运行的内容,并将它们添加到作业中。在这里,您引用每个任务应作为输入的输入文件。 一个例子(假设Windows cmd):

cmd /c %AZ_BATCH_NODE_SHARED_DIR%ProcessUserdata.exe %AZ_BATCH_TASK_DIR%userIds1.txt --environment test

在这里,userIds1.txt 是上传输入文件时返回的第一个资源文件。下一个命令将指定 userIds2.txt 等。

创建包含命令的 CloudTask 对象列表后,将它们添加到作业中,例如在 C# 中。

await batchClient.JobOperations.AddTaskAsync(jobId, tasks);

现在您等待作业完成。

现在发生的情况是,Azure 批处理会查看池中的节点,当任务列表中有更多任务时,它会将任务分配给可用(空闲)节点。

完成后(可以通过 API 轮询),可以删除池、作业,并仅为使用的计算付费。

最后一点:您的任务可能取决于外部包,即默认情况下未安装在您选择的操作系统上的执行环境,因此有几种可能的方法可以解决此问题: 1. 上传一个应用程序包,该包将在每个节点进入池时分发到每个节点(同样,有一个环境变量指向它)。这可以通过 Azure 门户完成。 2. 使用命令行工具来获取您需要的内容,例如在 Ubuntu 上安装apt-get。

希望这能让您大致了解什么是批处理。在我看来,最好的入门方法是做一些非常简单的事情,即在单个节点上的单个任务中打印环境变量。

您可以在执行过程中再次通过门户检查每个节点的标准输出和标准输出。

显然还有更多的东西,但这是一个基本指南。您可以创建链接任务和许多其他漂亮的东西,但如果需要,您可以阅读它。

假设很多人正在寻找满足这些要求的解决方案,新版本的ADLA(Azure Data Lake Analytics)现在支持Parquet格式。这将与 U-SQL 一起受支持。现在,只需不到 100 行代码,您就可以将这些小文件读入大文件,并且使用较少的资源(顶点)将数据压缩到 Parquet 文件。例如,您可以将 3TB 数据存储到 10000 个镶木地板文件中。阅读这些文件也非常简单,根据要求,您可以立即创建csv文件。这肯定会为您节省太多的成本和时间。

最新更新