我在一个Java类中定义了某些变量,并用另一个类来访问它,以便为唯一元素过滤流。请参考代码以更好地了解问题。
我面临的问题是此筛选器功能无法正常运行,并且无法筛选唯一事件。我怀疑该变量在不同线程之间共享,这是原因!如果这不是正确的方法,请提出另一种方法。预先感谢。
**ClassWithVariables.java**
public static HashMap<String, ArrayList<String>> uniqueMap = new HashMap<>();
**FilterClass.java**
public boolean filter(String val) throws Exception {
if(ClassWithVariables.uniqueMap.containsKey(key)) {
Arraylist<String> al = uniqueMap.get(key);
if(al.contains(val) {
return false;
} else {
//Update the hashmap list(uniqueMap)
return true;
}
} else {
//Add to hashmap list(uniqueMap)
return true;
}
}
答案 0 :(得分:0)
对流进行重复数据删除的正确方法包括通过密钥对流进行分区,以便包含相同密钥的所有元素都将由同一工作人员处理,并使用flink的托管,键控状态机制,以使状态为故障宽容和可伸缩。这是一个示例实现:
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.addSource(new EventSource())
.keyBy(e -> e.key)
.flatMap(new Deduplicate())
.print();
env.execute();
}
public static class Deduplicate extends RichFlatMapFunction<Event, Event> {
ValueState<Boolean> seen;
@Override
public void open(Configuration conf) {
ValueStateDescriptor<Boolean> desc = new ValueStateDescriptor<>("seen", Types.BOOLEAN);
seen = getRuntimeContext().getState(desc);
}
@Override
public void flatMap(Event event, Collector<Event> out) throws Exception {
if (seen.value() == null) {
out.collect(event);
seen.update(true);
}
}
}
这也可以实现为RichFilterFunction,btw。但是请注意,如果您拥有无限制的密钥空间,则使用的状态将无限期增长,直到耗尽堆空间或磁盘上的空间为止,这取决于您选择的Flink的状态后端。如果这是一个问题,则可能要通过State Time-to-Live设置状态保留策略。
还请注意,无法在Flink管道的不同部分之间共享状态。与看似正常的情况相比,您需要将事情从内到外翻转,并将事件流带入状态,而不是获取事件流。