数据连接与集成构建管道Streaming pipelines流式密钥

注意:以下翻译的准确性尚未经过验证。这是使用 AIP ↗ 从原始英文文本进行的机器翻译。

流式密钥

Foundry流允许您指定一个或多个列作为密钥列,以及一个主键来识别已解析的记录。以下部分解释了如何设置和维护您的流式管道的分区和主键。

分区键

一般来说,Palantir平台中的主键用于唯一标识数据库记录。然而,Foundry流中的分区键将具有相同记录分组,例如特定设备的所有读数或特定客户的所有交易。与批处理管道中的主键相比,流中的分区键不会去重记录,因为它们不能唯一标识记录。

Foundry中的键允许用户确保特定键的所有记录将保持顺序。当记录进入Foundry时,它会在内部存储于Kafka。Kafka保证写入同一分区的记录在读取和写入时保持顺序。如果记录在没有键的情况下发送到Foundry,则记录将以循环方式写入内部Kafka主题的任何分区。但是,如果用户为记录指定了一个键,记录将被写入该键的专用分区,从而在下游消费时保持顺序。

类似地,Flink流任务会根据输入源上设置的分区键列自动维护排序。Flink变换任务可能会为每个变换操作运行一个或多个并行分区。对于分区键的输入流,Flink任务将自动将所有具有相同键列值的记录发送到同一并行操作实例。除非特别重新键(如使用Key by变换),否则整个管道的分区和排序由源上的键列和行值决定,即使变换逻辑删除列或覆盖值。

主键:变更数据捕获(CDC)模式

Foundry流中的主键与关系数据库和批处理数据集中的主键类似。然而,流式主键由一组去重列组成,这些列唯一标识已解析记录,并且不指定排序列。

主键是Foundry中流的架构中的一部分元数据。键不影响存储数据的内容或应用流数据管道和变换的方式。主键控制一些Foundry消费者如何读取数据;完整的数据可以被视为一个变更日志,而主键告诉消费者如何在应用所有更改后计算去重的当前视图

当前视图是数据的一个筛选视图,仅包含每个键最近流式传输的记录。键的完整最新记录将始终保留,即使它包含nulls。如果指定了一个删除列,并且键的最近流式传输记录的该值设置为true,则该记录将被筛选。

以下示例展示了一个主键和数据流,其中最近流式传输的行在表中较高。

主键:{去重列(s): [Key], isDeletedColumn: 非必填[isDeleted]}

KeyValueisDeleted
Key2nullfalse
Key1thirdValtrue
Key2secondValfalse
Key1firstValfalse

当CDC感知消费者读取此变更日志流时,它将被读取为以下当前视图:

KeyValueisDeleted
Key2nullfalse

如果您选择为流数据设置主键,您还必须将相同的列设置为分区键以维护排序并正确解析去重数据视图。一旦您在流设置界面中设置了主键,相同的列将自动添加为分区键列。

以下两个CDC感知任务将自动读取具有主键的流数据作为当前视图:

  1. 使用具有主键流的Ontology填充: 新的更新记录将根据需要创建、更新或删除一个新Object。
  2. 流的存档数据集被任何Spark变换任务读取: 在进行任何变换之前,源将被去重。特别是,几乎所有与存档数据集的交互都会运行一个Spark任务,包括数据集预览和轮廓分析。在查看存档数据集时,它将始终显示为去重的当前视图,即使数据本身包含完整的变更日志(如果您将数据下载为文件)。任何不运行Spark的流任务都会处理完整的变更日志,包括重放。

键传播

Pipeline Builder跟踪分区键和主键列通过管道变换的演变,并将任何有效键写入输出流的架构。如果您的变换没有使任何键列无效,相同的分区和去重指令将在任何数量的下游管道中自动维护。

如果您重命名一个键列,键将更新为包含新的列名。同样,如果您应用了一个变换删除或覆盖了一个键列,该列将从键中移除。由于任何覆盖键列内容的操作可能代表新的排序保证或新的去重策略,Pipeline Builder会完全从键中删除该列。如果您希望保留先前被覆盖的键列,必须再次应用Key by变换。即使由于删除或覆盖而导致分区键列被删除,相同的排序保证将在管道的剩余部分持续存在,除非您重新键。

如果所有分区键或去重CDC键被删除或覆盖,键将完全丢失。在删除或覆盖键列的内容时请小心,这样做可能导致意外结果,包括丢失排序保证或去重策略。

当前,用户定义函数(UDFs)永远不会传播键。由于函数是用户定义的,因此无法推断用户意图使用哪种键传播策略(如果有的话)。如果您打算传播键,请确保在您的UDF之后应用Key by变换。

此外,主键不会为有状态变换传播(大多数变换不是有状态的)。

使用流式键

在Pipeline Builder应用中的流式管道中,将Key by变换添加到您的图中。值得注意的是,您在此处设置的任何键都将覆盖并替换输入数据上的任何键。

如果您只想设置分区键,请关闭CDC模式选项,并仅提供Key by列列表。除非您处于CDC模式,否则其他参数不是必需或允许的。

要同时设置主键和分区键,请打开CDC模式选项。如果您有一个isDeleted列,可以选择在主键已删除字段中指定它。对于流应用案例,我们强烈建议将非必填的主键排序列参数留空。变换将同时设置分区和主键,其中分区键列与主键去重列相同。主键排序列参数仅在批处理任务中消费存档数据集时才重要,并且永远不会影响流如何看待去重。指定排序列的选项是为了向后兼容,批处理变换用户或意图以特定批处理方式消费流存档的用户。

检查当前键

以下部分描述了如何在您的Foundry流中查找和验证流式键逻辑。

检查分区键

打开您的流数据集,导航到详细信息标签,然后打开架构标签以查看JSON格式的数据架构。

搜索includeInParitioning,这将出现在fieldSchemaList中每个作为主键一部分的列的元素中:

Copied!
1 2 3 "customMetadata": { "includeInPartitioning": true // 指定是否在分区中包含该元数据 }

如果您没有看到任何带有 includeInParitioning 的模式字段,您的数据流没有键,因此无法保证数据的存储或处理顺序。要手动添加键,请将模式编辑为JSON文本,并将自定义元数据(如上所述)插入到您希望设置为分区键列的每个模式字段(列)中。

如果一个流已经有一个或多个分区键,添加新的分区键列将导致较弱的顺序保证,因为会有更多的分区;顺序仅对共享所有分区键列相同值的行保持保证。

在部署之前,如果在管道的输入流上设置了分区键列,则该源及其整个管道的所有变换都将保证排序,除非您有意重新设置键。分区键列可能在数据预览中以钥匙符号显示。

检查主键

打开您的流数据集,导航到 Details 选项卡,然后打开 Schema 选项卡以查看JSON格式的数据模式。

您将看到一个名为 primaryKey 的JSON属性。如果您的流具有去重列 uniqueCol1uniqueCol2,以及 isDeletedisDeletedCol,则模式应如下所示:

Copied!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 "primaryKey": { "columns": [ "uniqueCol1", // 用于唯一标识记录的第一列 "uniqueCol2" // 用于唯一标识记录的第二列 ], "resolution": { "type": "duplicate", // 解决重复问题的类型 "duplicate": { "resolutionStrategy": { "type": "customStrategy", // 自定义策略用于解决重复 "customStrategy": {} // 自定义策略的具体实现 }, "deletionColumn": "isDeletedCol" // 用于标识记录是否被删除的列 } } }

如果未设置主键,模式将显示null:

"primaryKey": null  // 主键为空

要手动设置或移除主键,您可以编辑模式JSON以指定上述格式的键,或者使用null来移除键。如果您手动设置主键,我们强烈建议将相同的列设置为分区键列。

确保排序的唯一方法是在整个流式数据沿袭上设置分区键列。设置后,分区键列将自动向下游传播。即使一个流被配置为只有一个分区,由于Flink应用程序的缩放和非确定性处理记录的方式,排序也不一定得到保证。

流式键最佳实践

仔细选择分区键,因为导致记录分布效率低下的键会人为增加负载并限制吞吐量。如果排序对您的应用案例很重要,那么请为您希望保持顺序的通用分组标识符设置分区键,例如邮件ID、客户ID或组织ID。如果排序对您的应用案例不重要,您可以选择使用唯一ID作为键,或者完全不为您的流使用键。

最终流式输出的排序保证将与流系列(由Kafka主题支持)和变换(Flink任务)中最弱的保证一样强。因此,请确保保持您所需的排序,并为您的整个数据沿袭设置正确的分区键,从起始的流式提取开始,将记录拉入Foundry。排序保证不会强于您从中提取到Foundry的系统。例如,如果您使用Kafka连接器从Kafka中提取,请将分区键列设置为Kafka键列,以允许Foundry在您的系统上保持等效的排序保证。

此外,如果在一系列数据变换期间完全更改了分区列(和排序保证),可能会出现问题。如果在应用新的Key by变换之前保证了不同的排序,变换将接收到来自新添加的键列的无序记录;这些记录将在变换系列中保持错误顺序。