外部函数简介¶
本主题描述外部函数,这些函数会调用在 Snowflake 外部开发、维护、存储和执行的可执行代码。
本主题可以帮助您:
了解什么是外部函数。
确定外部函数是否是用于实施 UDF (用户定义的函数)的最佳方式。
选择适合外部函数云平台。
本主题内容:
外部函数是什么?¶
外部函数 调用在 Snowflake 外部执行的代码。
远程执行的代码称为 远程服务。
发送到远程服务的信息通常通过 代理服务 进行中继。
Snowflake 在 API 集成 中存储与安全性相关的外部函数信息。
下图展示了从客户端程序通过 Snowflake 到远程服务的基本信息流:
下面更详细地介绍了每个关键组件。
- 外部函数:
外部函数是一种 UDF。与其他 UDFs 不同,外部函数不包含自己的代码;相反,外部函数调用在 Snowflake 外部存储和执行的代码。
在 Snowflake 内部,外部函数存储为数据库对象,其中包含 Snowflake 用于调用远程服务的信息。此类存储信息包含 代理服务 的 URL。代理服务将信息中继到远程服务,以及从远程服务中继信息。此类信息通过 CREATE EXTERNAL FUNCTION 命令指定。
表示外部函数的数据库对象在特定的数据库和架构中创建。您可以使用点表示法来表示完全限定名称,从而调用外部函数。例如:
select my_database.my_schema.my_external_function(col1) from table1;
- 远程服务:
远程执行的代码称为远程服务。
远程服务必须像函数一样运行。例如,它必须返回值。
Snowflake 支持 标量 外部函数;远程服务必须正好为收到的每一行返回一行。
要通过 Snowflake External Function 功能调用,远程服务必须执行以下操作:
接受 JSON (https://www.json.org) 输入并返回 JSON 输出。(有关 Snowflake 兼容的 HTTP 标头和 JSON 格式化数据的更多信息,请参阅 远程服务输入和输出数据格式。)
公开 HTTPS 端点。
例如,远程服务可以通过以下方式实施:
AWS Lambda 函数。
Microsoft Azure 函数。
EC2 实例上运行的 HTTPS 服务器(例如 Node.js)。
- 代理服务:
Snowflake 不直接调用 远程服务。相反,Snowflake 调用代理服务,将数据中继到远程服务。
代理服务可以对面向远程服务的请求进行身份验证,从而提高安全性。
对于远程服务,代理服务可以支持基于订阅的计费。例如,代理服务可以验证远程服务的调用方是否是付费订阅者。
代理服务还将来自远程服务的响应中继回 Snowflake。
代理服务的示例包括:
Amazon API Gateway。
Microsoft Azure API Management 服务。
- API 集成:
集成 是一个 Snowflake 对象,在 Snowflake 和第三方服务之间提供接口。API 集成存储在使用代理服务或远程服务时所需的信息,例如安全信息。
API 集成是使用 CREATE API INTEGRATION 命令创建的。
用户可以编写并调用自己的远程服务,也可以调用第三方编写的远程服务。这些远程服务可以使用任何 HTTP 服务器堆栈编写,包括云无服务器计算服务(例如 AWS Lambda)。
从运行 SQL 语句的用户的角度来看,外部函数的行为与任何其他 UDF 类似。外部函数遵循以下规则:
外部函数返回一个值。
外部函数可以接受参数。
外部函数可以在 SQL 语句的任何子句中显示,在其中可以显示其他类型的 UDF。例如:
select my_external_function_2(column_1, column_2) from table_1; select col1 from table_1 where my_external_function_3(col2) < 0; create view view1 (col1) as select my_external_function_5(col1) from table9;
外部函数可以属于更复杂的表达式:
select upper(zipcode_to_city_external_function(zipcode)) from address_table;
返回值可以是复合值,例如包含 JSON 的 VARIANT。
外部函数可以重载;两个不同的函数可以具有相同的名称但不同的签名(输入参数的数量或数据类型不同)。
外部函数的工作原理¶
Snowflake 不直接调用远程服务。相反,Snowflake 通过云提供商的本地 HTTPS 代理服务(例如 AWS 上的 API Gateway)调用远程服务。
外部函数的主要调用步骤如下:
用户的客户端程序向 Snowflake 传递用于调用外部函数的 SQL 语句。
在执行查询期间评估外部函数时,Snowflake 会读取外部函数定义和相应的 API 集成信息。
来自外部函数定义的信息包括:
代理服务的 URL。
相应 API 集成的名称。
来自 API 集成的信息包括:
要使用的代理服务资源。资源包含有关远程服务的信息,例如相应服务的位置。
相应代理服务资源的身份验证信息。
然后,Snowflake 编写 HTTP POST 命令,包括:
要处理的数据。此数据采用 JSON 格式。
HTTP 标头信息。(有关详细信息,请参阅 CREATE EXTERNAL FUNCTION。)
来自 API 集成的身份验证信息。
然后,Snowflake 向代理服务发送 POST 请求。
代理服务接收 POST 请求,然后处理请求并将其转发给实际的远程服务。您可以大致将代理服务和资源视为用于调用远程服务的“中继函数”。
远程服务处理数据并返回结果,结果通过链传回原始 SQL 语句。
如果远程服务使用 HTTP 代码响应信号 异步 处理,则 Snowflake 会发送一个或多个 HTTP GET 请求,从远程服务中检索结果。只要 Snowflake 收到响应代码以继续请求,Snowflake 就会继续发送 GET 请求,直到外部函数超时或返回错误。
通常,当查询有大量行要发送到远程服务时,这些行会分成多个批次。批处理通常可以提高并行度并加快查询。在某些情况下,批处理可以减少远程服务的重载。
远程服务为收到的每个批次返回 1 批行。对于标量外部函数,返回批次中的行数等于接收批次中的行数。
每个批次都有唯一的批次 ID,包含在从 Snowflake 发送到远程服务的每个请求中。
重试操作(例如因超时而重试)通常在批处理级别完成。
外部函数的优势¶
相较于其他 UDFs,外部函数具有以下优势:
远程服务的代码可以用其他 UDFs 无法使用的语言编写,包括:
Go
C#
远程服务可以使用内部 UDFs 无法访问的函数和库。例如,远程服务可以与商用第三方库(例如机器学习评分库)进行交互。
开发者可以编写远程服务,这些服务既可以从 Snowflake 调用,也可以从使用相同接口编写的其他软件调用。
外部函数的限制¶
外部函数具有以下限制,这些限制可以大致分为创建时间限制和执行时间限制。
创建时间限制和要求¶
在第一次调用外部函数之前,管理员必须进行一些配置工作。这项工作需要云平台(例如 AWS 或 Microsoft Azure)的知识,尤其是关于安全性的知识。
Snowflake 通过云 HTTP 代理服务(例如 Amazon API Gateway)间接调用远程服务,因此外部函数的远程服务必须可以从代理服务调用。幸运的是,几乎任何可以充当 HTTPS 端点的函数都可以作为外部函数通过代理服务进行访问。函数作者必须对代理服务进行编程,才能调用远程服务(例如,基于 AWS Lambda 运行的函数)。
某些云平台可能有具体要求。例如,在 AWS 上,外部函数需要区域端点或专用端点。有关更多详细信息,请参阅 支持的平台。有关 Amazon API Gateway 区域端点和专用端点的更多详细信息,请参阅 选择端点类型:区域端点与专用端点。
External Functions 功能只能用于编写函数,而不能用于编写存储过程。
不支持 未来授予 外部函数的权限。
执行时间限制和问题¶
由于远程服务对 Snowflake 不透明,因此优化器可能无法执行一些可以对等效内部函数执行的优化。
外部函数的开销高于内部函数(内置函数和内部 UDFs),并且通常执行速度更慢。
目前,外部函数必须是标量函数。标量外部函数为每个输入行返回一个值。
目前,外部函数无法通过 Secure Data Sharing 与数据使用者共享。
每批次的响应大小上限为 10MB。
以下情况不能使用外部函数:
属于通过 Secure Data Sharing 共享的数据库对象的一部分(例如表、视图、UDF 或掩码策略)。例如,您无法创建使用外部函数的共享视图。不支持以下内容:
CREATE VIEW my_shared_view AS SELECT my_external_function(x) ...; CREATE SHARE things_to_share; ... GRANT SELECT ON VIEW my_shared_view TO SHARE things_to_share; ...
CREATE TABLE
语句的DEFAULT
子句。换句话说,列的默认值不能是调用外部函数的表达式。如果您尝试在DEFAULT
子句中包含外部函数,那么CREATE TABLE
语句会失败。
外部函数可能会引发额外的安全问题。例如,如果您调用第三方的函数,该方可以保留传递给该函数的数据的副本。
外部函数使用计费¶
使用外部函数会产生与以下内容相关的正常成本:
此外,您可能需要支付间接或第三方费用,包括远程服务提供商收取的费用。费用可能因供应商而异。
备注
通过 Amazon API Gateway Private Endpoints 发送的数据会针对入口和出口产生 AWS PrivateLink 费用。
支持的平台¶
支持调用外部函数的平台¶
一般来说,外部函数可以在 Snowflake 支持的任何云平台上通过 Snowflake 账户调用:
Amazon Web Services (AWS)
Microsoft Azure
Google Cloud Platform (GCP)
下面列出了例外情况:
通过 AWS API Gateway 专用端点访问的外部函数只能在 AWS 上和相同 AWS 区域中通过 Snowflake VPC (虚拟私有云)访问。有关 AWS 上专用端点的更多详细信息,请参阅 选择端点类型:区域端点与专用端点。
用于调用外部函数的 SQL 语法在所有平台上都相同。
用于配置对这些服务的访问的 SQL 语句(CREATE EXTERNAL FUNCTION 和 CREATE API INTEGRATION)对所有平台来说都相同。但是,这些语句中的子句会有所不同,具体取决于托管代理服务和远程服务的平台。
支持创建外部函数的远程服务和代理服务的平台¶
虽然外部函数可以从任何平台 调用,但是外部函数的远程服务和代理服务都必须在特定支持平台上 创建。
很多情况下,远程服务的平台和账户与代理服务的平台和账户相同。然而,这不是必需条件。例如,SQL 查询可以通过 AWS API Gateway(代理服务)调用 Azure 函数(远程服务)。SQL 查询本身可以在基于 GCP 运行的 Snowflake 实例上运行。
支持远程服务的平台¶
您需要 HTTP 服务器堆栈来托管远程服务。任何支持远程服务的 HTTP 服务器堆栈都应该与外部函数兼容。
要创建远程服务,您通常需要:
拥有云平台提供商的账户(例如,用于创建 Azure 函数的 Microsoft Azure 账户)。此账户为远程服务提供存储和计算服务。此账户与 Snowflake 账户不同。
Snowflake 提供关于以下列形式创建远程服务的说明:
AWS Lambda 函数。
Microsoft Azure 函数。
Google Cloud Function。
支持代理服务的平台¶
您需要云平台上本地 HTTP 代理服务的实例。
要配置代理服务,您通常需要:
拥有云平台提供商的账户(例如,要使用 AWS 的 Amazon 账户)。此账户为代理服务提供存储和计算服务。此账户与 Snowflake 账户不同。
具有配置代理服务所需权限的云平台角色。此云平台角色与 Snowflake 角色不同。
支持以下 HTTPS 代理服务:
Amazon API Gateway。
Microsoft Azure API Management 服务。
Google Cloud API Gateway。
以下部分包含用户在选择平台之前应了解的平台特定的信息。
平台特定的限制¶
- AWS:
此功能仅支持 Amazon API Gateway 的区域和私有端点。(有关不同类型的端点的描述,请参阅 端点 (https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-basic-concept.html)。)
Snowflake 外部函数和 API 集成不支持 AWS 自定义域 (https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-custom-domains.html)。要从 Snowflake 访问 Amazon API Gateway,请使用 AWS 生成的默认 URL,类似如下:
https://api-id.execute-api.region.amazonaws.com/stage