MergeContent

文档中心 › 组件索引 › MergeContent

MergeContent Processor

类型全限定名:cn.org.acal.lynxus.processors.standard.MergeContent

所属 Bundle:cn.org.acal.lynxus:lynxus-standard-nar:2.11.8

描述

根据用户定义的策略将一组 FlowFile 合并在一起,并将它们打包成单个 FlowFile。 建议仅使用单个传入连接配置处理器,因为不会从不同连接中的 FlowFiles 创建 FlowFiles 组。 该处理器根据需要更新 mime.type 属性。 注意:此处理器不应配置为使用 Cron 驱动来执行调度策略。

标签

mergecontentcorrelationtarzipstreamconcatenationarchiveflowfile-streamflowfile-stream-v3

使用场景

将具有文本内容的 FlowFile 连接在一起,以创建更少、更大的 FlowFile。

concatenatebundleaggregatebinmergecombinesmash
"Merge Strategy" = "Bin Packing Algorithm"
"Merge Format" = "Binary Concatenation"
"Delimiter Strategy" = "Text"
"Demarcator" = "\n"(可以通过按 Shift + Enter 插入换行符)
"Minimum Number of Entries" = "1"
"Maximum Number of Entries" = "500000000"
"Minimum Group Size" = 写入输出 FlowFile 的最小数据量。合理的值可能是 "128 MB"
"Maximum Group Size" = 写入输出 FlowFile 的最大数据量。合理的值可能是 "256 MB"
"Max Bin Age" = 在超时并继续传输 FlowFile(即使它小于 Max Bin Age)之前等待传入数据的最长时间。 合理的值可能是 "5 mins"

将具有二进制内容的 FlowFile 连接在一起,以创建更少、更大的 FlowFile。

说明:并非所有二进制数据都可以连接在一起。此配置是否有效取决于你的数据类型。

concatenatebundleaggregatebinmergecombinesmash
"Merge Strategy" = "Bin Packing Algorithm"
"Merge Format" = "Binary Concatenation"
"Delimiter Strategy" = "Text"
"Minimum Number of Entries" = "1"
"Maximum Number of Entries" = "500000000"
"Minimum Group Size" = 写入输出 FlowFile 的最小数据量。合理的值可能是 "128 MB"
"Maximum Group Size" = 写入输出 FlowFile 的最大数据量。合理的值可能是 "256 MB"
"Max Bin Age" = 在超时并继续传输 FlowFile(即使它小于 Max Bin Age)之前等待传入数据的最长时间。 合理的值可能是 "5 mins"

重新组装之前被 SplitText、UnpackContext、SplitRecord 等处理器拆分为较小 FlowFile 的 FlowFile。

reassemblerepackmergerecombine
"Merge Strategy" = "Defragment"
"Merge Format" = Merge Format 的值取决于期望的输出格式。如果文件之前被压缩为 zip 并由 UnpackContent 拆分,
    则 "ZIP" 的 Merge Format 是合理的。如果它之前是 .tar 文件,则 "TAR" 的 Merge Format 是合理的。如果数据是文本,"Binary Concatenation" 可以
    用于将文本合并为单个文档。
"Delimiter Strategy" = "Text"
"Max Bin Age" = 在超时并将分片传输到 'failure' 之前等待传入数据的最长时间。合理的值可能是 "5 mins"

对于文本数据,"Demarcator" 应设置为换行符(\n),在 UI 中通过按 Shift+Enter 设置。对于二进制数据,"Demarcator" 应留空。

属性

下表中,加粗的属性为必填项;其余为可选项。表格同时标注默认值、是否支持表达式语言,以及是否为敏感属性(值会被加密)。

名称默认值可选值描述
Merge StrategyBin-Packing Algorithm
  • Bin-Packing Algorithm — 生成 FlowFile 的 'bin',并尽可能填满每个 bin。FlowFile 根据其大小被放入 bin 中;如果设置了 <Correlation Attribute> 属性,还会根据其属性放置
  • Defragment — 将由属性关联的分片重新组合成一个完整连贯的 FlowFile。如果使用该策略,所有 FlowFile 必须具有 <fragment.identifier>、<fragment.count> 和 <fragment.index> 属性。所有 "fragment.identifier" 值相同的 FlowFile 将被分到一组,该组中所有 FlowFile 的 "fragment.count" 属性值必须相同。该组中所有 FlowFile 的 "fragment.index" 属性值必须唯一,且介于 0 与 "fragment.count" 属性值之间。
指定用于合并内容的算法。'Defragment' 算法将通过属性关联的片段合并回单个完整的 FlowFile。'Bin-Packing Algorithm' 生成一个由任意选择的 FlowFile 填充的 FlowFile
Merge FormatBinary Concatenation
  • TAR — 一个 bin 中的 FlowFile 将被合并成单个 TAR 文件。如果 <Keep Paths> 属性设为 true,将使用 FlowFile 的 <path> 属性在 TAR 文件中创建目录;否则所有 FlowFile 将被添加到 TAR 文件的根目录。如果某个 FlowFile 具有名为 <tar.permissions> 的属性,且为 3 个 0-7 之间的字符,则该属性将用作 TAR 条目的 'mode'。
  • ZIP — 一个 bin 中的 FlowFile 将被合并成单个 ZIP 文件。如果 <Keep Paths> 属性设为 true,将使用 FlowFile 的 <path> 属性在 ZIP 文件中创建目录;否则所有 FlowFile 将被添加到 ZIP 文件的根目录。<Compression Level> 属性指定要使用的 ZIP 压缩级别。
  • FlowFile Stream, v3 — 一个 bin 中的 FlowFile 将被合并成单个 Version 3 FlowFile Stream
  • FlowFile Stream, v2 — 一个 bin 中的 FlowFile 将被合并成单个 Version 2 FlowFile Stream
  • FlowFile Tar, v1 — 一个 bin 中的 FlowFile 将被合并成单个 Version 1 FlowFile Package
  • Binary Concatenation — 所有 FlowFile 的内容将被连接到一起,形成单个 FlowFile
  • Avro — 所有 FlowFile 的 Avro 内容将连接在一起形成一个 FlowFile
确定用于合并内容的格式。
Attribute StrategyKeep Only Common Attributes
  • 仅保留公共属性 — 任何在 bin 中的所有 FlowFile 上不相同的属性都将被丢弃。在所有 FlowFile 中相同的属性将被保留。
  • 保留所有唯一属性 — 任何在 bin 中的所有 FlowFile 上具有相同值或没有值的属性都将被保留。例如,如果一个 bin 包含 3 个 FlowFile,其中 2 个的 'greeting' 属性值为 'hello',第三个 FlowFile 没有 'greeting' 属性,则输出的 FlowFile 将获得值为 'hello' 的 'greeting' 属性。
确定哪些 FlowFile 属性应添加到捆绑包中。如果选择 'Keep All Unique Attributes',则捆绑包中任何 FlowFile 上的任何属性都会被保留,除非其值与另一个 FlowFile 的值冲突。如果选择 'Keep Only Common Attributes',则仅保留捆绑包中所有 FlowFile 上都存在且值相同的属性。
Correlation Attribute Name如果指定,相似的 FlowFile 将被分到同一组,其中'相似的 FlowFile' 是指在此属性上具有相同值的 FlowFile。如果未指定,FlowFile 将按从队列中拉取的顺序进行捆绑。
支持表达式语言:是(使用 FlowFile 属性与环境/系统变量求值)
Metadata StrategyDo Not Merge Uncommon Metadata
  • Use First Metadata — 对于任何支持元数据的输入格式(例如 Avro),bin 中第一个 FlowFile 的元数据将被设置到输出 FlowFile 上。
  • Keep Only Common Metadata — 对于任何支持元数据的输入格式(例如 Avro),元数据值与第一个 FlowFile 匹配的任何 FlowFile,其额外的元数据将被丢弃,但该 FlowFile 仍会被合并。任何元数据值与 bin 中第一个 FlowFile 不匹配的 FlowFile 都不会被合并。
  • Ignore Metadata — 忽略(不传输、不比较等)内容支持内嵌元数据的 FlowFile 的任何元数据。
  • Do Not Merge Uncommon Metadata — 对于任何支持元数据的输入格式(例如 Avro),任何元数据值与 bin 中第一个 FlowFile 的元数据值不匹配的 FlowFile 将不会被合并。
对于输入格式支持元数据的 FlowFile(如 Avro),此属性决定应将哪些元数据添加到捆绑包中。如果选择'使用第一个元数据',则将使用第一个捆绑的 FlowFile 的元数据键/值。如果选择'仅保留公共元数据',则仅保留捆绑包中所有 FlowFile 上都存在且值相同的元数据。如果选择'忽略元数据',则不会将任何元数据传输到输出的捆绑 FlowFile。如果选择'不合并不公共元数据',则任何元数据值与第一个捆绑 FlowFile 不匹配的 FlowFile 将不会被合并。
Minimum Number of Entries1捆绑包中包含的最小文件数
Maximum Number of Entries1000捆绑包中包含的最大文件数
Minimum Group Size0 B捆绑包的最小尺寸
Maximum Group Size捆绑包的最大尺寸。 如果未指定,则没有最大值。
Bin Termination Check指定一个表达式语言表达式,将对每个 FlowFile 进行求值。如果表达式的结果为 'true',则 FlowFile 对应的分组将被终止,即使该分组尚未达到最小条目数或最小大小。请注意,如果触发分组终止的 FlowFile 本身大于最大分组大小,它将被放入自己的分组中,而不会触发任何其他分组的终止。使用此属性时,建议在流的连接中使用优先级排序器以确保排序符合预期。
支持表达式语言:是(使用 FlowFile 属性与环境/系统变量求值)
FlowFile Insertion StrategyLast in Bin
  • Last in Bin — 将 FlowFile 插入到已终止的 Bin 的末尾
  • First in New Bin — 将 FlowFile 插入到新创建的 Bin 的开头
  • Isolated — 将 FlowFile 插入新的 Bin 中并立即终止 Bin,并将 FlowFile 作为唯一内容
如果给定的 FlowFile 基于 <Bin Termination Check> 属性终止 bin,则指定 FlowFile 应包含在 bin 中的位置。
Max Bin Age最大 age of a Bin that will trigger a Bin to be complete. Expected format is <duration> <time unit> where <duration> is a positive integer and time unit is one of seconds, minutes, hours
Maximum Number of Bins5指定任一时刻内存中可保存的最大 bin 数
Delimiter StrategyDo Not Use Delimiters
  • Filename — Header、Footer 和 Demarcator 的值将从某个文件的内容中获取
  • Text — Header、Footer 和 Demarcator 的值将作为属性值指定
  • Do Not Use Delimiters — 将不使用页眉、页脚或分界符
确定标头、页脚和分界符是指向包含相应内容的文件,还是使用属性的值作为内容。
Header指定要使用的标头的文件名或文本。 如果未指定,则不提供标头。
支持表达式语言:是(使用 FlowFile 属性与环境/系统变量求值)
Footer指定要使用的页脚的文件名或文本。 如果未指定,则不提供页脚。
支持表达式语言:是(使用 FlowFile 属性与环境/系统变量求值)
Demarcator指定要使用的分界符的文件名或文本。 如果未指定,则不提供分界符。
支持表达式语言:是(使用 FlowFile 属性与环境/系统变量求值)
Compression Level1
  • 0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
指定使用 Zip 合并格式时使用的压缩级别;如果不使用 Zip 合并格式,则忽略此值
Keep Pathfalse
  • true
  • false
如果使用 Zip 或 Tar 合并格式,请指定 FlowFiles 的路径是否应包含在其条目名称中。
Tar 修改时间${file.lastModifiedTime}如果使用 Tar 合并格式,指定 Tar 条目是否应通过表达式(例如 ${file.lastModifiedTime})或静态值存储修改时间戳,两者都必须符合 ISO8601 格式 'yyyy-MM-dd'T'HH:mm:ssZ'。
支持表达式语言:是(使用 FlowFile 属性与环境/系统变量求值)

关系 (Relationships)

名称描述自动终止
failure如果无法创建bundle,则用于创建bundle的所有FlowFiles将转为失败否
merged包含合并内容的FlowFile否
original用于创建捆绑包的 FlowFiles否

读取的 FlowFile 属性

名称描述
fragment.identifier仅在 <Merge Strategy> 属性设置为 Defragment 时适用。所有具有相同此属性值的 FlowFile 将被捆绑在一起。
fragment.index仅在 <Merge Strategy> 属性设置为 Defragment 时适用。此属性指示碎片的组装顺序。使用 Defragment 合并策略时,此属性必须存在于所有 FlowFile 上,且必须是 0 到 fragment.count 属性值之间的唯一整数(即在具有相同 'fragment.identifier' 属性值的所有 FlowFile 中唯一)。如果两个或多个 FlowFile 具有相同的 'fragment.identifier' 属性值和相同的 'fragment.index' 属性值,则第一个处理的 FlowFile 将被接受,后续 FlowFile 将不会被接受到桶中。
fragment.count仅在 <Merge Strategy> 属性设置为 Defragment 时适用。此属性指示给定包中应有多少 FlowFile。包中至少有一个 FlowFile 必须具有此属性。如果给定包中的多个 FlowFile 包含 'fragment.count' 属性,则它们的值必须相同。
segment.original.filename仅在 <Merge Strategy> 属性设置为 Defragment 时适用。此属性必须存在于具有相同 fragment.identifier 属性值的所有 FlowFile 上。同一包中的所有 FlowFile 必须具有相同的此属性值。此属性的值将用作完成合并后 FlowFile 的文件名。
tar.permissions仅在 <Merge Format> 属性设置为 TAR 时适用。此属性的值必须为 3 个字符;每个字符必须在 0 到 7(含)的范围内,表示 FlowFile 的 TAR 条目应使用的文件权限。如果此属性缺失或值无效,将使用默认值 644

写入的 FlowFile 属性

名称描述
filename当合并超过 1 个文件时,文件名来自 segment.original.filename 属性。如果该属性在源 FlowFile 中不存在,则文件名设置为匹配系统时间的纳秒数。然后可能会应用文件名扩展名:如果合并格式为 TAR,则文件名追加 .tar;如果合并格式为 ZIP,则追加 .zip;如果合并格式为 FlowFileStream,则追加 .pkg
merge.count合并到此捆绑包中的 FlowFile 数量
merge.bin.age箱被合并和输出时的存在时间(毫秒)。实际上这是此捆绑包中任何 FlowFile 在此处理器中等待输出的最长时间
merge.uuid将添加到原始 FlowFiles 属性的合并 FlowFile 的 UUID。
merge.reason该处理器允许配置多个阈值来合并 FlowFiles。 该属性指示哪个阈值 resulted in the FlowFiles being merged. For an explanation of each of the possible values and their meanings, see the Processor's Usage / documentation and see the 'Additional Details' page.

状态管理

该组件不存储状态。

受限 (Restricted)

该组件不受限。

输入要求

该组件要求有传入连接。

系统资源考量

资源描述
MEMORY虽然内容不存储在内存中,但 FlowFile 的属性是。MergeContent 的配置(最大桶大小、最大组大小、最大桶存在时间、最大条目数)将影响使用的内存量。如果合并许多小的 FlowFile,可能需要两阶段方法来避免过度使用内存。

详细说明

MergeContent

简介

MergeContent Processor 提供了把多个 FlowFile 合并为单个 FlowFile 的能力。数据流设计者可能有很多 理由这样做。例如,在发送到下游系统之前把数据组成批次可能很有帮助,因为下游系统对大文件的处理 往往比大量小文件更优化。Lynxus 本身也能从中受益,因为 Lynxus 在"微批处理(micro-batches)" 模式下运行效果最佳,即每个 FlowFile 的大小在数 KB 到数 MB 之间。

该 Processor 会创建若干个"箱(bin)"来放置 FlowFile。默认最多使用 5 个箱,但可以通过更新 属性的值来修改。限制箱的数量是为了避免耗尽 Java 堆空间。注意: 虽然 FlowFile 的内容存储在 Content Repository 而不是 Java 堆空间中,但该 Processor 必须把 FlowFile 对象本身保存在内存里。因此,这些带着 Attribute 的 FlowFile 可能占用大量堆空间, 导致抛出 OutOfMemoryError。为避免这种情况,如果预计要合并大量小 FlowFile,建议先用一个 MergeContent 把不超过(比如)1,000 个 FlowFile 合并成小包,再用第二个 MergeContent 把这些 小包合并成更大的包。例如,要合并 1,000,000 个 FlowFile,可以使用 为 1,000 的 MergeContent,并把 "merged" Relationship 路由到第二个同样设置 为 1,000 的 MergeContent。第二个 MergeContent 会把 1,000 个 含 1,000 条数据的小包合并,实际上就产生了含 1,000,000 条数据的包。

FlowFile 如何装箱

Processor 决定把 FlowFile 放入哪个箱,取决于若干配置选项。首先是 Merge Strategy。 Merge Strategy 可以设置为两个选项之一:"Bin Packing Algorithm"(装箱算法)或 "Defragment" (碎片重组)。如果目标只是把较小的 FlowFile 合并成一个更大的 FlowFile,应使用 Bin Packing Algorithm。该算法根据以下条件选择箱:按大小和 属性判断 FlowFile 是否能放进该箱,以及该 FlowFile 与箱中其他 FlowFile 是否"相似"。两个 "相似(like)FlowFile"的含义将在本节末尾讨论。

当需要把 FlowFile 显式地分配到同一个箱时,可以使用 "Defragment" 合并策略。例如,如果用 UnpackContent Processor 拆分了数据,每个拆出的 FlowFile 可以独立处理,之后再用本 Processor (Merge Strategy 设为 Defragment)合并回来。要在这种配置下把 FlowFile 加入同一个箱, 这些 FlowFile 的 "fragment.identifier" Attribute 必须具有相同的值。具有相同标识符的每个 FlowFile 还必须有唯一的 "fragment.index" Attribute 值,以便正确排序。对于给定的 "fragment.identifier",至少要有一个 FlowFile 带有 "fragment.count" Attribute(表示箱中 应包含多少个 FlowFile)。具有相同标识符的其他 FlowFile 要么与该 "fragment.count" Attribute 的值相同,要么可以省略该属性。注意: 虽然拆分后再重新合并有合理的使用场景, 但把一个较大的 FlowFile 拆成上百万个小 FlowFile 再重新合并是一种反模式。这样做可能消耗大量 Java 堆并导致 Out Of Memory 错误,还会给 Lynxus 框架带来很大负载,造成 CPU 和磁盘占用升高, 吞吐量往往会下降一个数量级、延迟升高一个数量级。作为替代方案,数据流应尽可能使用面向 Record 的 Processor,例如 QueryRecord、PartitionRecord、UpdateRecord、LookupRecord、 PublishKafkaRecord_2_6 等。

要被放入同一个箱,两个 FlowFile 必须是"相似(like)的"。两个相似 FlowFile 必须具有相同的 schema;如果设置了 属性,它们的指定 Attribute 还必须具有 相同的值。例如,如果 设为 "filename",那么两个 FlowFile 的 "filename" Attribute 必须相同才能装进同一个箱。如果需要用多个 Attribute 来关联两个 FlowFile,建议在 MergeContent 之前使用 UpdateAttribute Processor 把这些 Attribute 组合起来。例如,如果目标只在 "abc" 和 "xyz" 两个 Attribute 的值都相同时才把两个 FlowFile 装进同一个箱,那么可以用 UpdateAttribute 添加一个名为 "correlation.attribute"、 值为 "abc=${abc},xyz=${xyz}" 的属性,然后把 MergeContent 的 属性设为 "correlation.attribute"。

箱何时合并

上面讨论了如何为给定的 FlowFile 选择箱。一旦创建了箱并向其中添加了 FlowFile,就需要某种方式 判断箱何时"满了",从而把这些 FlowFile 合并成一个 "merged" FlowFile。

如果 属性设为 "Bin Packing Algorithm",则会评估以下规则。

MergeContent 暴露了若干不同的阈值,可用于创建大小理想的箱。例如,用户可以指定合并前必须打包在 一起的最少 FlowFile 数量,也可以配置最小字节数;此外,还可以指定最大 FlowFile 数量和字节数。

还有两种其他条件会导致箱内容被合并。Max Bin Age 属性指定了箱被合并之前,FlowFile 可以一起 装箱的最长时间。这个属性几乎总是应该设置,因为它相当于为箱设置了超时,这样即使数据暂时停止流入 该 Processor(由于上游系统问题、源 Processor 被停止等),FlowFile 也不会无限期地滞留在 MergeContent Processor 中。此外,该 Processor 还暴露了一个属性用于指定应使用的最大箱数量。 对某些用例来说这并不重要;但如果设置了 Correlation Attribute 属性,这就很重要了。当传入的 FlowFile 需要被放入某个箱时,Processor 必须找到合适的箱,否则就要创建新箱。如果必须创建新箱, 而现有的箱数量已经达到 属性的值,那么最旧的箱会被合并以腾出空间。

如果 属性设为 "Defragment",那么只有当箱中 FlowFile 的数量等于箱内某个 FlowFile 的 "fragment.count" Attribute 指定的数量时,箱才算满。所有带有该 Attribute 的 FlowFile 必须具有相同的值,否则会被路由到 "failure" Relationship。并不要求所有 FlowFile 都有这个值,但箱内至少要有一个,否则箱永远无法装满。如果在箱超时(由 属性 指定)之前所有必要的 FlowFile 没有装到同一个箱,这些 FlowFile 会被全部路由到 'failure' Relationship,而不是合并。

最后,如果配置了 属性,且收到的某个 FlowFile 满足指定条件,箱也可以 被合并。该条件以表达式语言(Expression Language)表达式指定。如果任何 FlowFile 使该表达式 返回 true,无论箱中有多少数据、箱已存在多久,箱都会被合并。这个触发合并的传入 FlowFile, 根据 属性的值,可以作为箱的最后一个条目加入、作为新箱的第一个 条目,或者作为独立的箱输出。

因此,当满足以下任意一个条件时,一箱 FlowFile 就会被合并:

  • 箱已达到最大字节数,由 属性配置。
  • 箱已达到最大 FlowFile 数,由 属性配置。
  • 箱已同时达到最小字节数(由 属性配置)和最小 FlowFile 数(由 属性配置)。
  • 箱已达到最大存活时间,由 属性配置。
  • 已达到最大箱数量(由 属性配置),且必须创建新箱。
  • 配置了 属性,且收到的某个 FlowFile 满足指定条件。

合并原因(Reason for Merge)

每当箱的内容被合并时,合并产生的 FlowFile 上都会添加一个名为 "merge.reason" 的 Attribute。 下表列出了该属性的所有可能取值及各自的含义。

Attribute 值 说明
MAX_BYTES_THRESHOLD_REACHED 箱已达到 属性配置的最大字节数。达到该阈值时,即使尚未达到 Minimum Number of Entries,箱的内容也会被合并。
MAX_ENTRIES_THRESHOLD_REACHED 箱已达到 属性配置的最大 FlowFile 数。达到该阈值时,即使尚未达到最小字节数(Min Group Size),箱的内容也会被合并。
MIN_THRESHOLDS_REACHED 箱已同时达到 属性配置的最小字节数和 属性配置的最小 FlowFile 数,且尚未达到最大字节数(Max Group Size)或最大 FlowFile 数(Maximum Number of Entries)。
TIMEOUT 箱已达到 属性配置的最大存活时间。达到该阈值时,即使箱尚未达到任何最小阈值,其内容也会被合并。注意,这里的"年龄"由箱的创建时间决定,而不是箱内 FlowFile 的年龄。因此,如果 Processor 一直停止,队列中有 100 万个各已存在 10 天的 FlowFile,而 Max Bin Age 设为 "1 day",那么至少要再等一整天才会触发合并,即使这些 FlowFile 本身早已超过该阈值。如果 Processor 停止后重启,所有箱都会被销毁并重建,计时器重置。
BIN_MANAGER_FULL 如果传入的 FlowFile 放不进任何现有的箱(由于设置了最大阈值、使用了 Correlation Attribute 等原因),就必须为传入的 FlowFile 创建新箱。如果活动箱的数量已经等于 属性的值,最旧的箱会被合并以腾出空间。这种情况称为 Bin Manager 已满,使用此取值。
BIN_TERMINATION_SIGNAL 某个 FlowFile 满足了配置的 属性,从而发出信号要求终止该箱。

注意,Attribute 的值命名得很简洁,而文字说明则详尽得多。这样做有几个原因:首先,存储较大的 Attribute 值成本更高,会占用更多堆空间并需要更多资源处理;其次,简洁的取值更便于表述;最重要的是, 这意味着必要时可以使用 RouteOnAttribute 这类 Processor 基于该 Attribute 的值进行路由。这样一来, 说明文字可以进一步扩充或更新,而无需改变 Attribute 的取值。