基于 processTime 的作业失败,从checkPoint 重启作业的数据问题
val lahuo = Lahuo.Atta3639.newBuilder() .setEi(ei) .setId(id) .setSchemeFrom(schemeFrom) .setOmgid(omgid) .setQimei36(qimei36) .setOriginImei(originImei) .setAndroidId(androidId) .setOaid(oaid) .setFtime(ftime) .setOld(in) .build()
|
代码中添加了old,用来标记从kafka读取的原始json字符串,经过测试发现,从checkPoint 重启作业时,会产生序列化后old字段为空的数据,不从checkPoint恢复数据时没有old字段为空的数据
结论:基于事件处理时间的flink程序,checkPoint会保存当前窗口期内未处理完的数据,作业重启时会从checkPoint中读取旧的没有old的数据,导致old字段为空
基于eventTime事件时间的作业,数据不往下游发送
env.addSource(Atta3639Consumer) .flatMap(new AmsLahuo3639FlatMap()).uid("atta3639") .assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor[((String, String, String, Long), Array[Byte])](Time.seconds(60)) { override def extractTimestamp(t: ((String, String, String, Long), Array[Byte])): Long = { t._1._4 } }) .map(data => { // 转换k ((data._1._1, data._1._2, data._1._3), data._2) }) .keyBy(_._1) // 根据scheme_from、omgid、qimei36分组 .reduce((a, b) => { // 本批次数据去重 a }) .keyBy(_._1._1) // 根据 scheme_from 分组 .timeWindow(Time.seconds(BATCH_TIME)) .process(new LahuoBatchWindowProcess()).uid("schemeBatch") .connect(lahuoConfBroadcast) .process(new LahuoConfBroadcastProcess).uid("broadcastRes") .assignAscendingTimestamps(res => { DateUtil.parseDateStrToTimeStamp(res.time) }) .timeWindowAll(org.apache.flink.streaming.api.windowing.time.Time.seconds(5)) .apply(new AllWindowFunction[LahuoFlowRes, List[LahuoFlowRes], TimeWindow] { override def apply(window: TimeWindow, input: Iterable[LahuoFlowRes], out: Collector[List[LahuoFlowRes]]): Unit = { println("窗口apply方法:" + input) out.collect(input.toList) } }) // .map(data => { // List(data) // }) .addSink(new LahuoFlowResMysqlSink)
|
由于代码前边指定了eventTime,后续timeWindowAll未指定ts字段,导致该问题的产生,在timeWindowAll前指定了ts,问题解决
基于eventTime,启动作业时,读取mysql 配置文件作为广播变量,休眠时间内的 java.lang.InterruptedException: sleep interrupted 异常处理
val lahuoConfBroadcast = env.addSource(new LahuoConfMysqlSource).broadcast()
|
原代码读取mysql 配置时,srouce未指定并行度,虽然FliinkUI中 的 执行图 显示广播变量的并行度为1,但是依然会抛出 java.lang.InterruptedException: sleep interrupted
改为:
val lahuoConfBroadcast = env.addSource(new LahuoConfMysqlSource).setParallelism(1).broadcast() |
问题解决
查阅资料发现:继承自SourceFunction 的自定义source,并行度只能为1,自定义多并行度的source需要继承RichParallelSource 并实现其中的方法,该问题已解决,但导致该问题的原因暂未查明