在Flink KeyedStream上暂停处理

时间:2018-10-26 21:07:34

标签: apache-flink flink-streaming

我有一个Flink流应用程序,该应用程序需要能够在特定键控流上“暂停”和“取消暂停”处理。 “处理”意味着仅对流执行一些简单的异常检测。

我们正在考虑的流程如下:

ProcessCommandPauseCommandResumeCommand的命令流,每个命令流都带有一个id,用于KeyBy

ProcessCommands将在处理密钥之前检查密钥是否已暂停,如果没有,则进行缓冲。

PauseCommands将暂停密钥的处理。

ResumeCommands将取消暂停键的处理并刷新缓冲区。

这种流程看起来合理吗?如果可以,我是否可以使用类似split的运算符来实现?

示例流,省略了单个记录时间戳:

[{command: process, id: 1}, {command: pause, id: 1}, {command: process, id: 1}, {command: resume, id: 1}, {command: process, id: 1}]

Flow:
=>
{command: process, id: 1} # Sent downstream for analysis
=> 
{command: pause, id: 1} # Starts the buffer for id 1
=>
{command: process, id: 1} # Buffered into another output stream
=> 
{command: resume, id: 1} # Turns off buffering, flushes [{command: process, id: 1}] downstream
=>
{command: process, id: 1} # Sent downstream for processing as the buffering has been toggled off 

1 个答案:

答案 0 :(得分:1)

可以使用Flink's Window operator来实现。首先,通过应用POJO操作来创建基于tuplemap的流。

然后,根据您的需要,您可以在该流上使用keyBy来获得keyedStream

现在,通过结合使用基于时间的无限windowtriggerwindow function,您可以实现命令流的切换行为。

基本上,您可以将windows用作缓冲区,该缓冲区在接收到暂停记录后将保留过程记录,直到接收到恢复记录为止。您将要编写一个自定义触发器,该触发器将根据您的情况逐出窗口(缓冲区)。

以下是Trigger具有onElement()被覆盖方法的自定义实现。

/**
 * We trigger the window processing as per command inside the record. The
 * process records are buffered when a pause record is received and the
 * buffer is evicted once resume record is received. If no pause record is
 * received earlier, then for each process record the buffer is evicted.
 */
@Override
public TriggerResult onElement(Tuple2<Integer, String> element, long timestamp, Window window,
        TriggerContext context) throws Exception {
    if (element.f1.equals("pause")) {
        paused = true;
        return TriggerResult.CONTINUE;
    } else if (element.f1.equals("resume")) {
        paused = false;
        return TriggerResult.FIRE_AND_PURGE;
    } else if (paused) // paused is a ValueState per keyed stream.
        return TriggerResult.CONTINUE;
    return TriggerResult.FIRE_AND_PURGE;
}

在此github repository

中查看完整的工作示例