RichParallelSourceFunction中的水印

时间:2018-10-19 12:54:05

标签: apache-flink flink-streaming flink-sql

我正在实现SourceFunction,该功能从数据库读取数据。 如果停止或破坏了该数据(即保存点和检查点),并且该数据仅被处理了一次,则该作业应该能够恢复。

到目前为止我所拥有的:

@SerialVersionUID(1L)
class JDBCSource(private val waitTimeMs: Long) extends 
RichParallelSourceFunction[Event] with StoppableFunction with LazyLogging{

    @transient var client: PostGreClient = _
    @volatile var isRunning: Boolean = true
    val DEFAULT_WAIT_TIME_MS = 1000

    def this(clientConfig: Serializable) =
        this(clientConfig, DEFAULT_WAIT_TIME_MS)

    override def stop(): Unit = {
        this.isRunning = false
    }

    override def open(parameters: Configuration): Unit = {
        super.open(parameters)
        client = new JDBCClient
    }

    override def run(ctx: SourceFunction.SourceContext[Event]): Unit = {

        while (isRunning){
           val statement = client.getConnection.createStatement()
           val resultSet = statement.executeQuery("SELECT name, timestamp FROM MYTABLE")

            while (resultSet.next()) {
                val event: String = resultSet.getString("name")
                val timestamp: Long = resultSet.getLong("timestamp")

                ctx.collectWithTimestamp(new Event(name, timestamp), timestamp)

            }
        }
    }

    override def cancel(): Unit = {
        isRunning = false
    }
}

如何确保仅获取尚未处理的数据库行? 我假设ctx变量将具有有关当前水印的一些信息,以便可以将查询更改为:

select name, timestamp from myTable where timestamp > ctx.getCurrentWaterMark

但是它对我没有任何相关方法。任何想法如何解决这个问题将不胜感激

1 个答案:

答案 0 :(得分:1)

您必须实现CheckpointedFunction,以便您可以自己管理检查点。该界面的文档非常全面,但是如果您需要一个示例,我建议您看一下example

从本质上讲,您的函数必须使用Flink的托管状态来实现CheckpointedFunction#snapshotState来存储所需的状态,然后在执行还原时,它将在CheckpointedFunction#initializeState中读取相同的状态。