Azure Data Lake 中的增量负载

Incremental load in Azure Data Lake

我有一个很大的 blob 存储,里面装满了日志文件,这些日志文件根据它们的标识符在多个级别组织:存储库、分支、构建编号、构建步骤编号。

这些是 JSON 个包含对象数组的文件,每个对象都有一个 timestamp 和一个 entry 值。我已经实现了一个自定义提取器(扩展 IExtractor),它采用输入流并生成许多纯文本行。

初始负载

现在我正在尝试将所有这些数据加载到 ADL 商店。我创建了一个类似于此的查询:

@entries =
  EXTRACT
    repo string,
    branch string,
    build int,
    step int,
    Line int,
    Entry string
  FROM @"wasb://my.blob.core.windows.net/{repo}/{branch}/{build}/{step}.json"
  USING new MyJSONExtractor();

当我 运行 这个提取查询时,我得到一个编译器错误 - 它超过了 25 分钟编译时间的限制。我的猜测是:文件太多。所以我在 INSERT INTO 查询中添加了一个 WHERE 子句:

INSERT INTO Entries
(Repo, Branch, Build, Step, Line, Entry)
SELECT * FROM @entries
WHERE (repo == "myRepo") AND (branch == "master");

还是不行 - 编译器超时。

(它确实有效,但是,当我处理单个构建时,将 {step} 保留为唯一的通配符,并对其余名称进行硬编码。)

问题:有没有一种方法可以在多个作业中执行类似的加载 - 但无需明确(手动)"partition"输入文件?

增量加载

让我们暂时假设我成功加载了这些文件。但是,几天后我将需要执行更新 - 我应该如何指定文件列表?我有一个 SQL 服务器数据库,其中保存了所有元数据,我可以提取确切的日志文件路径 - 但 U-SQL 的 EXTRACT 查询迫使我提供一个静态字符串指定输入数据。

一个简单的方案是为每个日期定义一个顶级目录并逐日处理它们。但是系统的设计方式使这即使不是不可能也非常困难。

问题:有没有办法根据创建时间来识别文件?或者也许有一种方法可以将对 SQL 服务器数据库的查询与提取查询相结合?

关于您的第一个问题:听起来您的 FileSet 模式正在生成大量输入文件。要解决这个问题,您可能需要尝试 U-SQL 预览功能部分中记录的 FileSets v2 预览: https://github.com/Azure/AzureDataLake/blob/master/docs/Release_Notes/2017/2017_04_24/USQL_Release_Notes_2017_04_24.md

Input File Set scales orders of magnitudes better (opt-in statement is now provided)

Previously, U-SQL's file set pattern on EXTRACT expressions ran into compile time time-outs around 800 to 5000 files.

U-SQL's file set pattern now scales to many more files and generates more efficient plans.

For example, a U-SQL script querying over 2500 files in our telemetry system previously took over 10 minutes to compile now compiles in 1 minute and the script now executes in 9 minutes instead of over 35 minutes using a lot less AUs. We also have compiled scripts that access 30'000 files.

The preview feature can be turned on by adding the following statement to your script:

SET @@FeaturePreviews = "FileSetV2Dot5:on";

如果您想根据文件路径的分区生成多个提取语句,则必须使用一些生成一个或多个 U-SQL 脚本的外部代码来实现。

你的第二个问题我没有很好的答案,所以我会让同事回答。希望第一部分可以让你暂时畅通无阻。

回答你的第二个问题:

您可以使用联合查询从 SQL 服务器数据库中读取数据,然后在与您从文件集创建的虚拟列的连接中使用该信息。这样做的问题是,这些值仅在执行时已知,而在编译时未知,因此您不会减少访问的文件。

或者,您可以编写一个 SQL 查询来获取您需要的数据,然后参数化您的 U-SQL 脚本,这样您就可以将该信息传递到 U-SQL 脚本。

至于 select 基于文件创建时间的能力:这是我们待办事项列表中的一项功能。我建议对以下功能请求投赞成票并添加评论:https://feedback.azure.com/forums/327234-data-lake/suggestions/10948392-support-functionality-to-handle-file-properties-fr 并添加您希望通过文件集查询它们的评论。