U-SQL 从 SQL 并行读取 Table
U-SQL Paralell reading from SQL Table
我有一个场景,我使用 U-SQL 从 MS SQL DB 将数据提取到 Azure Data Lake。我的 table 相当大,有超过 1600 万条记录(很快就会更多)。我只是做一个 SELECT a, b, c FROM dbo.myTable;
然而,我意识到只有一个顶点用于读取 table。
我的问题是,在读取 SQL table 时是否有任何方法可以利用并行性?
我认为 U-SQL 还不支持外部数据源的并行性(尽管很高兴得到更正)。如果您觉得这是一个重要的缺失功能,您可以在此处创建请求并投票:
https://feedback.azure.com/forums/327234-data-lake
作为解决方法,您可以根据数据源中可用的列手动并行化查询。例如按日期
// External query working
USE DATABASE yourADLADB;
// Create the external query for year 2016
@results2016 =
SELECT *
FROM EXTERNAL yourSQLDBDataSource EXECUTE
@"SELECT * FROM dbo.yourBigTable WITH (NOLOCK) WHERE yourDateCol Between '1 Jan 2016 and 31 Dec 2016'";
// Create the external query for year 2017
@results2017 =
SELECT *
FROM EXTERNAL yourSQLDBDataSource EXECUTE
@"SELECT * FROM dbo.yourBigTable WITH (NOLOCK) WHERE yourDateCol Between '1 Jan 2017 and 31 Dec 2017";
// Output 2016 results
OUTPUT @results2016
TO "/output/bigTable/results2016.csv"
USING Outputters.Csv();
// Output 2017 results
OUTPUT @results2017
TO "/output/bigTable/results2017.csv"
USING Outputters.Csv();
现在,我通过将文件分成多个部分创建了一个不同的问题。但是,您可以使用文件集读取这些内容,这些文件集也将并行化,例如:
@input =
EXTRACT
... // your column list
FROM "/output/bigTable/results{year}.csv"
USING Extractors.Csv();
鉴于 ADLA 和 U-SQL 让您能够在数据所在的位置查询数据,我想问您为什么选择将如此大的文件移动到您的数据湖中。你能进一步解释一下吗?
对外部数据源的查询不会在 U-SQL 中自动并行化。 (这是我们未来考虑的事情)
wBob 的回答确实提供了一种实现相同效果的选项 - 尽管它当然需要您使用多个 U-SQL 语句手动分区和查询数据。
请注意,如果并行写入发生在源中,则在非事务环境中进行并行读取可能会导致重复或丢失数据。因此需要小心谨慎,用户需要了解权衡。
这里的另一个可能的解决方案是创建一个 HDInsight 集群,该集群由与您的 ADLA 帐户相同的 ADLS 存储支持。
然后您可以使用 Apache Sqoop 将数据从 SQL 服务器并行复制到 ADLS 中的一个目录,然后使用 U-SQL.
我有一个场景,我使用 U-SQL 从 MS SQL DB 将数据提取到 Azure Data Lake。我的 table 相当大,有超过 1600 万条记录(很快就会更多)。我只是做一个 SELECT a, b, c FROM dbo.myTable;
然而,我意识到只有一个顶点用于读取 table。
我的问题是,在读取 SQL table 时是否有任何方法可以利用并行性?
我认为 U-SQL 还不支持外部数据源的并行性(尽管很高兴得到更正)。如果您觉得这是一个重要的缺失功能,您可以在此处创建请求并投票:
https://feedback.azure.com/forums/327234-data-lake
作为解决方法,您可以根据数据源中可用的列手动并行化查询。例如按日期
// External query working
USE DATABASE yourADLADB;
// Create the external query for year 2016
@results2016 =
SELECT *
FROM EXTERNAL yourSQLDBDataSource EXECUTE
@"SELECT * FROM dbo.yourBigTable WITH (NOLOCK) WHERE yourDateCol Between '1 Jan 2016 and 31 Dec 2016'";
// Create the external query for year 2017
@results2017 =
SELECT *
FROM EXTERNAL yourSQLDBDataSource EXECUTE
@"SELECT * FROM dbo.yourBigTable WITH (NOLOCK) WHERE yourDateCol Between '1 Jan 2017 and 31 Dec 2017";
// Output 2016 results
OUTPUT @results2016
TO "/output/bigTable/results2016.csv"
USING Outputters.Csv();
// Output 2017 results
OUTPUT @results2017
TO "/output/bigTable/results2017.csv"
USING Outputters.Csv();
现在,我通过将文件分成多个部分创建了一个不同的问题。但是,您可以使用文件集读取这些内容,这些文件集也将并行化,例如:
@input =
EXTRACT
... // your column list
FROM "/output/bigTable/results{year}.csv"
USING Extractors.Csv();
鉴于 ADLA 和 U-SQL 让您能够在数据所在的位置查询数据,我想问您为什么选择将如此大的文件移动到您的数据湖中。你能进一步解释一下吗?
对外部数据源的查询不会在 U-SQL 中自动并行化。 (这是我们未来考虑的事情)
wBob 的回答确实提供了一种实现相同效果的选项 - 尽管它当然需要您使用多个 U-SQL 语句手动分区和查询数据。
请注意,如果并行写入发生在源中,则在非事务环境中进行并行读取可能会导致重复或丢失数据。因此需要小心谨慎,用户需要了解权衡。
这里的另一个可能的解决方案是创建一个 HDInsight 集群,该集群由与您的 ADLA 帐户相同的 ADLS 存储支持。
然后您可以使用 Apache Sqoop 将数据从 SQL 服务器并行复制到 ADLS 中的一个目录,然后使用 U-SQL.