要使用托管算子状态,有状态函数可以实现更通用的CheckpointedFunction
接口或ListCheckpointed<T extends Serializable>
接口。官方参考链接:https://ci.apache.org/projects/flink/flink-docs-release-1.10/dev/stream/state/state.html#listcheckpointed
- 此文使用
ListCheckpointed
,如下是官网的案例
class CounterSource
extends RichParallelSourceFunction[Long]
with ListCheckpointed[Long] {
@volatile
private var isRunning = true
private var offset = 0L
override def run(ctx: SourceFunction.SourceContext[Long]): Unit = {
val lock = ctx.getCheckpointLock
while (isRunning) {
// output and state update are atomic
lock.synchronized({
ctx.collect(offset)
offset += 1
})
}
}
override def cancel(): Unit = isRunning = false
override def restoreState(state: util.List[Long]): Unit =
for (s <- state) {
offset = s
}
override def snapshotState(checkpointId: Long, timestamp: Long): util.List[Long] =
Collections.singletonList(offset)
}
- 上述官网案例再导入Long的时候会
报Scala的Long类型不是java.io.Serializable的下界的错误
。 - 错误如下
Error:(62, 10) type arguments [Long] do not conform to trait ListCheckpointed's type parameter bounds [T <: java.io.Serializable]
with ListCheckpointed[Long] {
- 只需要使用将Scala的Long改成Java类型的Long即可~!
在代码里加入import java.lang.{Long => JavaLong}
- 修改后的代码如下:
import java.lang.{Long => JavaLong}
class CounterSource
extends RichParallelSourceFunction[Long]
with ListCheckpointed[JavaLong] { //此处修改为JavaLang
@volatile
private var isRunning = true
private var offset = 0L
override def run(ctx: SourceFunction.SourceContext[Long]): Unit = {
val lock = ctx.getCheckpointLock
while (isRunning) {
// output and state update are atomic
lock.synchronized({
ctx.collect(offset)
offset += 1
})
}
}
override def cancel(): Unit = isRunning = false
override def restoreState(state: util.List[JavaLong]): Unit = //此处修改为JavaLang
for (s <- state) {
offset = s
}
override def snapshotState(checkpointId: Long, timestamp: Long): util.List[JavaLong] = //此处修改为JavaLang
Collections.singletonList(offset)
}