智能应用 - U-SQL 大数据应用程序的扩展性

传统上,在大数据处理期间,对大数据的数据量、速度和多样性的处理主要集中在提供能处理海量数据的可缩放平台、添加近乎实时的处理功能,以及提供处理各种格式(从 CSV 到 JSON,再到自定义二进制格式)输入数据的相应功能上。经常事后才想到的一种多样性是与自定义数据处理相关的多样性,不仅体现在格式方面,还体现在能否轻松地使用自定义算法扩展分析,同时保留查询语言的声明性。

一些新式大数据处理和查询语言正着手解决此问题。特别是 U-SQL,一种从头到脚专为以下用途而设计的语言:将 SQL 语言的声明性与灵活使用现有代码库和开发新的自定义算法相结合。

使用 U-SQL,你不仅可以添加自己的自定义 C# 函数,还可以通过一个框架添加自己的用户定义运算符 (UDO),如你自己的提取程序、输出程序和行集运算符(如处理程序、应用方、化简程序和自定义合并程序)。此框架由以下两部分组成:

.NET 接口,为你提供生成这些运算符的协定,以便你可以专注于代码编写,将横向扩展留给 U-SQL 来执行。请注意,不必在 .NET 中实现实际的业务逻辑代码,我将在后面予以介绍。
U-SQL 表达式(如 EXTRACT 和 REDUCE),调用自定义运算符,并对数据大规模执行这些运算符。
在本文中,我将接着上一篇文章介绍如何利用 U-SQL 扩展性机制处理各种不同的数据(从 JSON 到图像数据)。此外,我还将介绍如何添加你自己的运算符。

在 U-SQL 中管理自定义代码

在开始引入一些示例之前,我们最好先了解一下 U-SQL 是如何使用自定义代码的。

如上所述,U-SQL 沿用 C# 及其标量表达式语言,适用于 U-SQL 谓词和 select 子句表达式等场景。为了让你的自定义代码对 U-SQL 编译器可见,必须将代码打包到必须由 U-SQL 脚本引用的 .NET 程序集中。必须先使用 CREATE ASSEMBLY 语句事先在 U-SQL 元数据服务中注册此程序集,然后才能引用它。

注册和引用 U-SQL 程序集:我建议使用用于 Visual Studio 的 Azure Data Lake 工具 (aka.ms/adltoolsvs),以便轻松生成和注册与 U-SQL 兼容的程序集。如果你在“类库(对于 U-SQL 应用程序)”项目(见图 1)中编写自定义代码,可以编写代码并生成项目,然后右键单击一下即可直接注册已生成的程序集 DLL 文件(见图 2)。

类库(对于 U-SQL 应用程序)项目

图 1:类库(对于 U-SQL 应用程序)项目

注册 U-SQL 程序集

图2
然后,只需在 U-SQL 脚本中使用 REFERENCE ASSEMBLY 语句,以便可在 U-SQL 脚本中使用公共类和方法即可,如图 3 所示。

3:从自定义程序集引用用户定义函数
REFERENCE ASSEMBLY master.TweetAnalysis;
USING tweet_fns = TweetAnalysis.Udfs;
@t =
  EXTRACT date string,
          time string,
          author string,
          tweet string
  FROM "/Samples/Data/Tweets/Tweets.csv"
  USING Extractors.Csv();
// Get the mentions from the tweet string
@m =
  SELECT origin
       , tweet_fns.get_mentions(tweet) AS mentions
       , author AS mentioned_by
FROM @t;
...

将现有代码与 U-SQL 程序集结合使用:你经常想要使用现有代码库或非 .NET 代码。若要使用非 .NET 代码(如本机库或完全不同的语言运行时,如 Python 或 JavaScript),必须为非 .NET 代码包装 C# 互操作性层(从 U-SQL 调用此层,然后调用非 .NET 代码),同时封送处理组件之间的数据,并实现 UDO 接口协定。在这种情况下,需要将非 .NET 代码项目(如本机 .dll 或其他运行时的文件)添加为其他文件。可在用于注册程序集的“其他文件”选项中执行此操作。当 .NET 程序集在脚本中获得引用时,这些文件会自动部署到每个节点,并可用于 .NET 程序集在相应节点的本地工作目录。

若要使用现有 .NET 库,你需要在自己的程序集上将现有代码库注册为托管依赖项。或者,如果你重复使用可直接用于 U-SQL 的库,请直接在 U-SQL 数据库中进行注册。无论属于上述哪种情况,脚本均必须引用所需的全部 .NET 程序集。

在本文的剩余部分中,我将在介绍一些最好使用扩展性模型的自定义代码应用场景中,介绍几个与这些注册选项相关的示例。这些应用场景包括:使用自定义化简程序合并重叠的范围、处理 JSON 文档、图像数据和空间数据。我将挨个介绍。

使用自定义化简程序合并重叠的范围

假设你有一个日志文件,用于跟踪用户何时与你的服务交互。此外,还假设用户能够以多种方式(例如,在多台设备或多个浏览器窗口中执行必应搜索)与你的服务交互。在准备日志文件以供日后分析的 U-SQL 作业中,你想要合并重叠的范围。

例如,如果输入日志文件如图 4 所示,则你需要针对每个用户合并重叠的范围(如图 5 所示)。

图 4:包含重叠的时间范围的日志文件

开始时间 结束时间 用户名
5:00 AM 6:00 AM ABC
5:00 AM 6:00 AM XYZ
8:00 AM 9:00 AM ABC
8:00 AM 10:00 AM ABC
10:00 AM 2:00 PM ABC
7:00 AM 11:00 AM ABC
9:00 AM 11:00 AM ABC
11:00 AM 11:30 AM ABC
11:40 PM 11:59 PM FOO
11:50 PM 0:40 AM FOO
图 5:合并重叠的时间范围后的日志文件
开始时间 结束时间 用户名
5:00 AM 6:00 AM ABC
5:00 AM 6:00 AM XYZ
7:00 AM 2:00 PM ABC
11:40 PM 0:40 AM FOO

如果你研究一下此问题,首先会注意到你想要通过定义用户定义聚合等内容来合并重叠的时间间隔。不过,如果你研究一下输入数据,则会注意到由于数据未经排序,你要么需要维持所有可能的时间间隔的状态,然后将非连续时间间隔合并为桥接时间间隔,要么需要针对每个用户名对时间间隔进行重新排序,以简化时间间隔的合并。

虽然有序聚合更易于横向扩展,但 U-SQL 不提供有序的用户定义聚合程序 (UDAGG)。此外,UDAGG 通常会每组生成一行,而在此示例中,如果为非连续范围,我可以每组生成多行。

幸运的是,U-SQL 提供了一种称为化简程序 (bit.ly/2evGsDA) 的可缩放 UDO,可根据使用自定义代码设置的分组键聚合行集。

我们要先编写 U-SQL 逻辑,其中 ReduceSample.Range­Reducer 是 RangeReducer 程序集中的用户定义化简程序(化简程序 UDO),日志数据位于文件 /Samples/Blogs/MRys/Ranges/ranges.txt (bit.ly/2eseZyw) 中,并使用“-”作为列分隔符。代码如下:

REFERENCE ASSEMBLY RangeReducer;
@in = EXTRACT start DateTime, end DateTime, user string
FROM "/Samples/Blogs/MRys/Ranges/ranges.txt"
USING Extractors.Text(delimiter:'-');
@r =  REDUCE @in PRESORT start ON user
      PRODUCE start DateTime, end DateTime, user string
      READONLY user
      USING new ReduceSample.RangeReducer();
OUTPUT @r
TO "/temp/result.csv"
USING Outputters.Csv();

REDUCE 表达式将行集 @in 视作输入,根据用户列对其进行分区,根据起始列中的值对分区进行预排序,然后应用 RangeReducer,从而在输出中生成相同的行集架构。由于化简程序仅调整起止范围,因此它其实并未调整用户列,因此将用户列标记为 READONLY。这样一来,化简程序框架便有权自动为该列传递数据,进而允许 U-SQL 查询处理程序出于一些目的主动优化只读列,如为了先于化简程序在只读列上叠加谓词。

编写化简程序的方法是实现 Microsoft.Analytics.Interfaces.IReducer 实例。在此示例中,由于不必提供任何参数,因此只需覆盖抽象的 Reduce 方法。可以将代码复制到适用于 U-SQL 的 C# 库中,然后将它注册为程序集 RangeReducer,如上所述。图 6 展示了 RangeReducer 的实现。(请注意,由于空间有限,已改变一些代码示例中的常规代码缩进做法。)

6:RangeReducer 的 C# 实现
using Microsoft.Analytics.Interfaces;
using Microsoft.Analytics.Types.Sql;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ReduceSample
{
  public class RangeReducer : IReducer
  {
    public override IEnumerable<IRo
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值