Wait Processor
描述
将传入的 FlowFile 路由到 'wait' 关系,直到匹配的释放信号存储在分布式缓存中。
标签
属性
| 名称 | 默认值 | 可选值 | 描述 |
|---|---|---|---|
| Release Signal Identifier | | 指定特定释放信号缓存的键的值。为了决定由 Wait 处理器处理的 FlowFile 应发送到 'success' 还是 'wait' 关系,处理器会检查此键指定的缓存中的信号。 支持表达式语言:是(使用 FlowFile 属性与环境/系统变量求值) | |
| Target Signal Count | 1 | 缓存中(由释放信号标识符指定)需要存在的信号数量,以便 Wait 处理器处理的 FlowFile 被发送到 'success' 关系。如果缓存中的信号数已达到此数量,FlowFile 将被路由到 'success' 关系,并且缓存中的信号数将减少此值。如果指定了信号计数器名称,此处理器检查特定计数器,否则检查缓存中的信号总数。 支持表达式语言:是(使用 FlowFile 属性与环境/系统变量求值) | |
| Signal Counter Name | | 在缓存内(由释放信号标识符指定),信号可能属于不同的计数器。如果指定了此属性,处理器检查缓存中属于此特定计数器的信号数。如果未指定,处理器检查缓存中的信号总数。 支持表达式语言:是(使用 FlowFile 属性与环境/系统变量求值) | |
| 等待缓冲计数 | 1 | 指定可以缓冲以检查是否可以继续前进的最大传入 FlowFile 数量。更多的缓冲可以提供更好的性能,因为它通过按信号标识符分组 FlowFile 来减少与缓存服务的交互次数。每次处理器执行只能处理一个信号标识符。 | |
| Releasable FlowFile Count | 1 | 值或属性表达式语言语句的结果,将对 FlowFile 进行求值以确定可释放的 FlowFile 数量。这指定当目标计数达到目标信号数量时可以释放多少个 FlowFile。零 (0) 具有特殊含义,只要信号计数与目标匹配,就可以释放任意数量的 FlowFile。 支持表达式语言:是(使用 FlowFile 属性与环境/系统变量求值) | |
| Expiration Duration | 10 min | 指示等待的 FlowFiles 将被路由到“过期”关系的持续时间 | |
| Distributed Cache Service | | 控制器服务 API:AtomicDistributedMapCacheClientcn.org.acal.lynxus-lynxus-standard-services-api-nar-2.11.8 | 用于检查来自相应通知处理器的释放信号的Controller Service |
| Attribute Copy Mode | keeporiginal |
| 指定如何处理从进入通知处理器的 FlowFiles 复制的属性 |
| Wait Mode | wait |
| 指定如何处理等待通知信号的 FlowFile |
| Wait Penalty Duration | | 如果配置,当信号标识符被处理但未满足释放条件时,该信号标识符将被惩罚,并且具有该信号标识符的 FlowFile 在指定时间段内不会被再次处理,这样该信号标识符不会阻塞其他信号标识符的处理。这对于以下用例很有用:Wait 处理器需要处理多个信号标识符,每个信号标识符有多个 FlowFile,并且在同一信号标识符内释放 FlowFile 的顺序很重要。FlowFile 顺序可以通过优先级排序器配置。重要提示:可处理的排队信号数量有限,Wait 处理器可能无法检查所有排队的信号 ID。请参阅附加详情了解最佳实践。 |
关系 (Relationships)
| 名称 | 描述 | 自动终止 |
|---|---|---|
expired | 超过配置的过期时间的 FlowFile 将被路由到此关系 | 否 |
failure | 当无法到达缓存时,或者释放信号标识符评估为 null 或空时,FlowFiles 将被路由到此关系 | 否 |
success | 缓存中具有匹配释放信号的 FlowFile 将被路由到此关系 | 否 |
wait | 缓存中没有匹配释放信号的 FlowFile 将被路由到此关系 | 否 |
写入的 FlowFile 属性
| 名称 | 描述 |
|---|---|
wait.start.timestamp | 所有 FlowFile 将具有 'wait.start.timestamp' 属性,该属性设置文件首次进入此处理器时的初始纪元时间戳。这用于确定 FlowFile 的过期时间。当 FlowFile 传输到 failure、过期或 success 时不写入此属性 |
wait.counter.<counterName> | 每个计数器的名称,自上次缓存被清空以来至少有一个信号出现在缓存中,被复制到当前 FlowFile 作为属性。 |
状态管理
该组件不存储状态。
受限 (Restricted)
该组件不受限。
输入要求
该组件要求有传入连接。
详细说明
Wait
在 Wait Processor 中处理多个 signal id 的最佳实践
当 Wait Processor 需要处理多个 signal id(通过在 'Release Signal Identifier' 中配置 FlowFile Attribute 的表达式语言实现)时,为了获得预期结果,有几件事需要考虑。Processor 的 配置会因需求而异。同时,你还需要对 Wait Processor 的工作原理有总体了解:
- Wait Processor 一次只处理一个 signal id
- Wait Processor 的运行频率由 'Run Schedule' 定义
- 处理哪个 FlowFile 由 Prioritizer 决定
- 不仅限于 Wait Processor,对所有 Processor 而言,如果没有设置 Prioritizer, Connection 中排队 FlowFile 的顺序是不确定的
常见模式参见以下小节:
信号一经通知即释放对应 FlowFile
这是最常见的用例。FlowFile 之间相互独立,可以按任意顺序释放。
重要配置:
- 在 'wait' Relationship 上使用 FirstInFirstOutPrioritizer(FIFO) (如果 'Wait Mode' 为 'Keep in the upstream connection',则在上游 Connection 上使用)
下表演示了每个 Wait 运行周期中:已通知的 signal id、排队中的 FlowFile 以及会发生什么。
| # of Wait run | Notified Signals | Queue Index (FIFO) | FlowFile UUID | Signal ID | |
|---|---|---|---|---|---|
| 1 | B | 1 | a | A | 该 FlowFile 被处理。但其信号未找到,会被重新排到队列末尾。 |
| 2 | b | B | |||
| 3 | c | C | |||
| 2 | B | 1 | b | B | 该 FlowFile 被处理,由于其信号已被通知,它会被释放到 'success'。 |
| 2 | c | C | |||
| 3 | a | A | |||
| 3 | 1 | c | C | 该 FlowFile 将在下一次运行时被处理。 | |
| 2 | a | A |
在每个 signal id 内优先释放高优先级 FlowFile
多个 FlowFile 共享同一个 signal id,且释放顺序很重要。
重要配置:
- 在 'wait' Relationship 上使用 FIFO 之外的、符合你需求的一个(或一组)Prioritizer (如果 'Wait Mode' 为 'Keep in the upstream connection',则在上游 Connection 上使用), 例如 PriorityPrioritizer
- 指定合适的 'Wait Penalty Duration',例如 "3 sec"
- 'Wait Penalty Duration' 应大于 'Run Schedule',例如 "3 sec" > "1 sec"
- 增大 'Run Duration',以避免 signal id 数量的限制(参见下文说明)
下表演示了每个 Wait 运行周期中:已通知的 signal id、排队中的 FlowFile 以及会发生什么。 示例使用 PriorityPrioritizer 来控制同一 signal id 内 FlowFile 的处理顺序。如果配置了 'Wait Penalty Duration',Wait Processor 会跟踪未释放的 signal id 及其惩罚(表示何时再次检查)。
| # of Wait run | Notified Signals | Signal Penalties | Queue Index (via 'priority' attribute) | FlowFile UUID | Signal ID | 'priority' attr | |
|---|---|---|---|---|---|---|---|
| 1 (00:01) | B | 1 | a-1 | A | 1 | 该 FlowFile 被处理。但其信号未找到,被施加惩罚。 | |
| 2 | b-1 | B | 1 | 由于 a-1 和 b-1 的优先级 '1' 相同,b-1 可能先于 a-1 被处理。可以再加一个 Prioritizer 来定义更具体的顺序。 | |||
| 3 | b-2 | B | 2 | ||||
| 2 (00:02) | B | A (00:04) | 1 | a-1 | A | 1 | 按配置的 Prioritizer 该 FlowFile 排第一,但其 signal id 处于惩罚期。因此本次执行中该 FlowFile 被跳过。 |
| 2 | b-1 | B | 1 | 该 FlowFile 被处理。 | |||
| 3 | b-2 | B | 2 | ||||
| 3 (00:03) | A (00:04) | 1 | a-1 | A | 1 | 该 FlowFile 排第一,但仍在惩罚期。 | |
| 2 | b-2 | B | 2 | 该 FlowFile 被处理,但其信号尚未被通知,因此被施加惩罚。 | |||
| 4 (00:04) | B (00:06) | 1 | a-1 | A | 1 | 该 FlowFile 不再处于惩罚期并被处理。但其信号仍未被通知,因此再次被施加惩罚。 | |
| 2 | b-2 | B | 2 |
使用 'Wait Penalty Duration' 时 'Run Duration' 的重要性
基于 'Run Schedule' 与 'Wait Penalize Duration' 的组合,可检查的信号数量存在上限。一旦触及该 限制,即使某些 FlowFile 的 signal id 已被通知,它们也可能不被处理而一直留在 'wait' Relationship 中。假设 Wait 的配置为:
- Run Schedule = 1 sec
- Wait Penalize Duration = 3 sec
- Release Signal Identifier = ${uuid}
并且 'wait' Relationship 中有 5 个 FlowFile:F1、F2 ... F5。此时 F5 的信号被通知。Wait 的 工作方式如下:
- 00:00 时,Wait 检查 F1 的信号,未找到,对 F1 施加惩罚(至 00:03)
- 00:01 时,Wait 检查 F2 的信号,未找到,对 F2 施加惩罚(至 00:04)
- 00:02 时,Wait 检查 F3 的信号,未找到,对 F3 施加惩罚(至 00:05)
- 00:03 时,Wait 检查 F4 的信号,未找到,对 F4 施加惩罚(至 00:06)
- 00:04 时,Wait 再次检查 F1 的信号,因为它已不再处于惩罚期
上述循环反复进行,因此在 F1 ... F4 中某个被释放之前,F5 不会被释放。
为缓解这一限制,建议增大 'Run Duration'。增大 'Run Duration' 后,Wait Processor 可以在该时长内 持续被调度。例如,'Run Duration' 设为 500 ms 时,Wait 应当能在单次运行中遍历全部 5 个排队的 FlowFile。
使用计数器(counter)
计数器本质上是一个标签,用于区分缓存内的不同信号(这里的"缓存"是指包含具有相同 signal identifier 的信号的一个"容器")。
假设缓存中有如下信号(注意,这些不是 Wait Processor 传入(或 wait)Connection 上的 FlowFile,而是存储在缓存中的释放信号):
| Signal ID | Signal Counter Name |
|---|---|
| A | counter_1 |
| A | counter_1 |
| A | counter_2 |
在此状态下,以下 FlowFile 被 Wait Processor 处理(该 FlowFile 带有 signal_counter_name Attribute,且 Wait Processor 被配置为使用该 Attribute 的值作为 Signal Counter Name 属性的值):
| FlowFile UUID | Signal ID | signal_counter_name |
|---|---|---|
| a-1 | A | counter_3 |
尽管 Signal ID "A" 对应的缓存中有信号,上面的 FlowFile 仍会被发送到 'wait' Relationship, 因为缓存中没有属于名为 "counter_3" 的计数器的信号。
假设缓存状态与上面相同,以下 FlowFile 被 Wait Processor 处理:
| FlowFile UUID | Signal ID | signal_counter_name |
|---|---|---|
| a-2 | A | counter_1 |
该 FlowFile 会被传输到 'success' Relationship,因为缓存 "A" 中有信号,且存在属于 "counter_1" 的信号。输出的 FlowFile 会被追加以下 Attribute 及其值:
- wait.counter.counter_1 : 2
- wait.counter.counter_2 : 1
- wait.counter.total : 3
这里的关键点是:计数器可用于区分缓存内的不同信号。如果使用了计数器,经过 Wait Processor 的 每个计数器都会为 FlowFile 追加一个新 Attribute。如果一个缓存中使用了大量计数器,经过 Wait Processor 的 FlowFile 会被追加大量 Attribute。为避免这种情况,建议使用多个缓存、每个 缓存只含少量计数器,而不是一个缓存含很多计数器。
例如:
- Release Signal ID "A" 对应的缓存包含计数器:"counter_1" 和 "counter_2"
- Release Signal ID "B" 对应的缓存包含计数器:"counter_3" 和 "counter_4"
- Release Signal ID "C" 对应的缓存包含计数器:"counter_5" 和 "counter_6"
(计数器名不需要在缓存之间唯一,缓存 "A" 使用的计数器名也可以在缓存 "B" 和 "C" 中复用。)