flink状态,对象重用,触发器,数据覆盖相关问题

遇到的问题

对于以上代码,我们进行keyby之后,我们new 了对象,我们会以为里面所有的数据都是独一份,和别的key是隔离的。

所以利索当然的:这个类型对象的属性:ExitLessonCountMessage有classId,lessonId,studentId 我们也会认为是独一份和别的keyby之后的数据不重用。

当我们入下图我们在定时器触发的时候。用了classId,lessonId,studentId 一直不是自己想要的数据, 导致数据混乱,百思不得其解。

原因分析:

最后经过反复看源码。我们虽然keyBy 之后 并且new ExitLessonCountMessage对象。但是在flink中,假如有对象在,就不会重新new 对象,而是直接重复使用。

这样就会导致里面的属性classId,lessonId,studentId 一直都被重用,当你定时器触发的时候就是最后定时器触发前的最后一条记录。而不是我们自己原来存的值。

解决办法:

第一种:

    在创建定时器的时候把这三个属性放到状态里面存储,定时器触发的时候取出来。这时候一定是唯一的,一定是你想要的。

第二种:

  在我们触发定时器时,我们从定时器的上下文中再取一次数据,赋值给lessonId,studentId,这样下面用到的值肯定就是我们定时器触发所需要的数据。

注意:第二种情况,只适合我们所需要的数据在key中,我们才能取到。要不然只能用第一种方法

思考:

1.flink快就是因为在很多种情况下代码是重用的。(例如迭代器,keyby之后对象的属性)

2.keyby之后并不会把所有的变量,对象,数据隔离。

猜你喜欢

转载自blog.csdn.net/zhangyupeng0528/article/details/115417702