相关文章推荐

Azure 流分析提供类似 SQL 的查询语言,用于对事件数据流执行转换和计算。 其中有许多内置函数,但在某些复杂的情况下需要更大的灵活性。 通过使用 .NET Standard 用户定义函数 (UDF),可以调用以任何 .NET Standard 语言(C#、F# 等)编写的自己的函数来扩展流分析查询语言。 UDF 可用于执行复杂的数学计算,使用 ML.NET 导入自定义 ML 模型,并对丢失的数据使用自定义插补逻辑。 流分析作业的 UDF 功能目前处于预览状态,不应在生产工作负荷中使用。

对于在 流分析群集 上运行的云作业,启用了 .NET 用户定义函数功能。 在标准多租户 SKU 上运行的作业可以在下列公共区域中利用此功能:

  • 美国中西部
  • 美国东部 2
  • 如果你希望在其他区域使用此功能,可以 请求访问

    任何 UDF 包的格式都具有路径 /UserCustomCode/CLR/* 。 动态链接库 (DLL) 和资源被复制到 /UserCustomCode/CLR/* 文件夹下,有助于将系统中的用户 DLL 与 Azure 流分析 DLL 隔离开来。 无论使用何种方法来利用这些函数,此包路径都用于所有函数。

    支持的类型和映射

    若要在 C# 中使用 Azure 流分析值,需要将值从一个环境封送到另一个环境。 针对 UDF 的所有输入参数进行封送处理。 每个 Azure 流分析类型在 C# 中都有对应的类型,如下表所示:

    Azure 流分析类型 C# 类型

    在 Visual Studio Code 中开发 UDF

    Azure 流分析的 Visual Studio Code 工具 可用于轻松编写 UDF、在本地(甚至脱机)测试作业,并将流分析作业发布到 Azure。

    可通过两种方法在 Visual Studio Code 工具中实现 .NET Standard UDF。

  • 来自本地 DLL 的 UDF
  • 来自本地项目的 UDF
  • 可在 Azure 流分析查询稍后引用的程序集中编写用户定义的函数。 这是复杂函数的推荐选项,它需要 .NET Standard 语言在其表达式语言之外的全部功能,例如过程逻辑或递归。 当需要在多个 Azure 流分析查询之间共享函数逻辑时,也可能会使用本地项目中的 UDF。 通过将 UDF 添加到本地项目,你可以本地调试和测试函数。

    引用本地项目:

  • 在本地计算机上创建新的 .NET Standard 类库。
  • 在类中编写代码。 注意必须将类定义为公共,并且必须将对象定义为静态公共
  • 在 Azure 流分析项目中添加新的 CSharp 函数配置文件,并引用 CSharp 类库项目。
  • 在“CustomCodeStorage”部分的作业配置文件 JobConfig.json 中配置程序集路径。本地测试不需要执行此步骤。
  • 本地 DLL

    此外,也可以引用包含用户定义函数的本地 DLL。

    在此示例中,CSharpUDFProject 是一个 C# 类库项目,ASAUDFDemo 是 Azure 流分析项目,它们将引用 CSharpUDFProject。

    下面的 UDF 包含一个函数,该函数将整数自身相乘以生成整数的平方。 必须将类定义为“公共”,并且必须将对象定义为“静态公共”。

    using System;
    namespace CSharpUDFProject
        public class Class1
            public static Int64 SquareFunction(Int64 a)
                return a * a;
    

    以下步骤演示如何将 C# UDF 函数添加到流分析项目。

  • 右键单击“Functions”文件夹,然后选择“添加项”。

  • 将 C# 函数“SquareFunction”添加到 Azure 流分析项目中。

  • 在 C# 函数配置中,选择“选择库项目路径”,以从下拉列表中选择你的 C# 项目,并选择“生成项目”以生成项目。 然后选择“选择类”和“选择方法”,以从下拉列表中选择相关的类和方法名称。 要在流分析查询中引用方法、类型和函数,必须将这些类定义为公共,并且必须将对象定义为静态公共

    如果要从 DLL 使用 C# UDF,请选择“选择库 DLL 路径”选择 DLL。 然后选择“选择类”和“选择方法”,以从下拉列表中选择相关的类和方法名称。

  • 在 Azure 流分析查询中调用 UDF。

     SELECT price, udf.SquareFunction(price)
     INTO Output
     FROM Input 
    
  • 将作业提交到 Azure 之前,在“CustomCodeStorage”部分的作业配置文件 JobConfig.json 中配置包路径。 在 CodeLens 中使用“从你的订阅中选择”,选择你的订阅,并从下拉列表中选择存储帐户和容器名称。 将“路径”保留为默认值。 本地测试不需要执行此步骤。

    CodeBehind

    可以在 Script.sql CodeBehind 中编写用户定义的函数。 Visual Studio 工具会自动将 CodeBehind 文件编译为程序集文件。 将作业提交到 Azure 时,程序集将打包为 zip 文件并上传到存储帐户。 可以根据流分析 Edge 作业的 UDF 教程执行操作,了解如何使用 CodeBehind 编写 C# UDF。

    在 Visual Studio 中引用本地项目:

  • 在解决方案中创建新的 .NET Standard 类库
  • 在类中编写代码。 注意必须将类定义为公共,并且必须将对象定义为静态公共
  • 生成你的项目。 工具会将 bin 文件夹中的所有项目打包为 zip 文件,并将该 zip 文件上传到存储帐户。 对于外部引用,请使用程序集引用而不是 NuGet 包。
  • 引用 Azure 流分析项目中的新类。
  • 在 Azure 流分析项目中添加一个新的函数。
  • 在作业配置文件 JobConfig.json 中配置程序集路径。 将程序集路径设置为“本地项目引用或 CodeBehind”
  • 重新生成函数项目和 Azure 流分析项目。
  • 在本示例中,UDFTest 是一个 C# 类库项目,ASAUDFDemo 是 Azure 流分析项目,它将引用 UDFTest

  • 生成 C# 项目,通过该项目,可以从 Azure 流分析查询中添加对 C# UDF 的引用。

  • 在 ASA 项目中添加对 C# 项目的引用。 右键单击“引用”节点,然后选择“添加引用”。

  • 从列表中选择 C# 项目名称。

  • 你会在“解决方案资源管理器”中看到“引用”下方列出的 UDFTest

  • 右键单击“Functions”文件夹,然后选择“新项”

  • 将 C# 函数“SquareFunction.json”添加到 Azure 流分析项目中

  • 双击“解决方案资源管理器”中的函数,以打开配置对话框

  • 在 C# 函数配置中,选择“从 ASA 项目引用中加载”,并从下拉列表中选择相关的程序集、类和方法名称。 要在流分析查询中引用方法、类型和函数,必须将这些类定义为公共,并且必须将对象定义为静态公共

    可以在所选的任何 IDE 中编写 .NET Standard UDF,并从 Azure 流分析查询中调用它们。 首先编译代码并打包所有 DLL。 包的格式具有路径 /UserCustomCode/CLR/*。 然后,将 UserCustomCode.zip 上传到 Azure存储帐户中容器的根目录。

    将程序集 zip 包上传到 Azure 存储帐户后,便可使用 Azure 流分析查询中的函数。 你只需将存储信息包含到流分析作业配置中即可。 无法使用此选项在本地测试该函数,因为 Visual Studio 工具不会下载你的包。 包路径直接解析至服务。

    若要在作业配置文件 JobConfig.json 中配置程序集路径,请执行以下操作:

    展开“用户定义的代码配置”部分,并使用以下建议值填写配置:

    用户日志记录

    使用日志记录机制,可以在作业运行时捕获自定义信息。 可以使用日志数据实时调试或评估自定义代码的正确性。

    StreamingContext 类可让你使用 StreamingDiagnostics.WriteError 函数发布诊断信息。 下面的代码显示了由 Azure 流分析公开的接口。

    public abstract class StreamingContext
        public abstract StreamingDiagnostics Diagnostics { get; }
    public abstract class StreamingDiagnostics
        public abstract void WriteError(string briefMessage, string detailedMessage);
    

    StreamingContext 作为输入参数传递到 UDF 方法,并可在 UDF 中使用以发布自定义日志信息。 在下面的示例中,MyUdfMethod 将定义一个由查询提供的“数据”输入,以及一个作为 StreamingContext 的“上下文”输入(由运行时引擎提供)。

    public static long MyUdfMethod(long data, StreamingContext context)
        // write log
        context.Diagnostics.WriteError("User Log", "This is a log message");
        return data;
    

    StreamingContext 值不需要由 SQL 查询传入。 如果存在输入参数,Azure 流分析会自动提供上下文对象。 不会更改 MyUdfMethod 的使用,如下面的查询所示:

    SELECT udf.MyUdfMethod(input.value) as udfValue FROM input
    

    可以通过诊断日志访问日志消息。

    UDF 预览目前有以下限制:

  • 只能在 Visual Studio Code 或 Visual Studio 中编写 .NET Standard UDF 并将其发布到 Azure。 可以在 Azure 门户中的“Functions”下查看只读版本的 .NET Standard UDF。 Azure 门户中不支持创建 .NET Standard 函数。

  • 在门户中使用 .NET Standard UDF 时,Azure 门户查询编辑器显示一条错误。

  • 调用外部 REST 终结点,例如,执行反向 IP 查找,或者从外部源提取引用数据

  • 由于自定义代码与 Azure 流分析引擎共享上下文,因此自定义代码无法引用 namespace/dll_name 与 Azure 流分析代码发生冲突的任何内容。 例如,不能引用 Newtonsoft Json

  • 项目中包含的支持文件会复制到“用户自定义代码”压缩文件中,该文件在你将作业发布到云中时使用。 解压文件时,子文件夹中的所有文件都将直接复制到云中的“用户自定义代码”文件夹的根目录中。 解压缩时,压缩文件为“平展”。

  • 用户自定义代码不支持空文件夹。 不要将空文件夹添加到项目中的支持文件。

  • 教程:为 Azure 流分析作业编写 C# 用户定义函数(预览版)
  • 教程:Azure 流分析 JavaScript 用户定义的函数
  • 在 Visual Studio Code 中创建 Azure 流分析作业
  •  
    推荐文章