Apache flink Flink CEP不是确定性的

Apache flink Flink CEP不是确定性的,apache-flink,flink-cep,Apache Flink,Flink Cep,我在没有群集的情况下在本地运行以下代码: val count = new AtomicInteger() val env = StreamExecutionEnvironment.getExecutionEnvironment env.setParallelism(1) val text: DataStream[String] = env.readTextFile("file:///flink/data2") val mapped: DataStream[Map[String, Any]] =

我在没有群集的情况下在本地运行以下代码:

val count = new AtomicInteger()
val env = StreamExecutionEnvironment.getExecutionEnvironment
env.setParallelism(1)
val text: DataStream[String] = env.readTextFile("file:///flink/data2")
val mapped: DataStream[Map[String, Any]] = text.map((x: String) => Map("user" -> x.split(",")(0), "val" -> x.split(",")(1)))
val pattern: ...
CEP.pattern(mapped, pattern).select(eventMap => {
  println("Found: " + (patternName, eventMap))
  count.incrementAndGet()
})

env.execute()
println(count)
我的数据是以下格式的CSV文件(用户,val):

我试图检测模式为
event(val=1)->event(val=2)->event(val=3)
的事件。当我在一个大的输入流上运行它时,我知道流中存在一定数量的事件,我得到的检测到的事件数不一致,几乎总是少于系统中的事件数。如果我执行
env.setParallelism(1)
(就像我在代码第3行中所做的那样),所有事件都会被检测到

我假设问题是,当并行度大于1时,多个线程正在处理来自流的事件,这意味着当一个线程具有
event(val=1)->event(val=2)
event(val=3)
可能被发送到另一个线程,并且可能无法检测到整个模式

这里有我遗漏的东西吗?我不能丢失流中的任何模式,但将parallelism设置为1似乎无法实现像Flink这样的系统检测事件的目的

更新:

我已尝试使用以下方法为流设置关键帧:

val mapped: KeyedStream[Map[String, Any]] = text.map(...).keyBy((m) => m.get("user"))
尽管这可以防止不同用户之间发生相互干扰的事件:

1,1
2,2
1,3

这并不能阻止Flink无序地将事件发送到节点,这意味着非确定性仍然存在。

您是否考虑过用userid(您的第一个值)为流设置键控?Flink保证一个密钥的所有事件都到达同一个处理节点。
当然,这只有在您想要检测每个用户的val=1->val=2->val=3模式时才有帮助。

最可能的问题在于在map操作符之后应用keyBy操作符

因此,不是:

val mapped: KeyedStream[Map[String, Any]] = text.map(...).keyBy((m) => m.get("user"))
应该有:

val mapped: KeyedStream[Map[String, Any]] = text.keyBy((m) => m.get("user")).map(...)

我知道这是一个老生常谈的问题,但也许它对某人有帮助。

是的,我试过了。不幸的是,这也没有帮助。键入流后有什么问题?结果是什么?你期望的结果是什么?它仍然不确定。尽管它可以防止检测到诸如:1,1 2,2 1,3之类的事件,但键控仍然不能阻止事件在多个线程中无序地进入处理节点。
val mapped: KeyedStream[Map[String, Any]] = text.keyBy((m) => m.get("user")).map(...)