[英]Flink 1.10.1 behaves different with parallelism max than 1
首先,我已经在这里找到了这个问题: flink 程序在并行性方面表现不同,它看起来和我现在面临的问题一样,但我认为在我的场景中确实需要 CEP,因为我有超过 1.000 个。每小时分析属于不同用户密钥的 000 条记录。
因此,当我以并行度 1 运行 cep 时,一切正常,即使对于不同的用户键,但有点慢,因为 flink 需要在单个线程中逐个用户分析用户,并且此操作需要足够快以识别某些模式然后发送例如,不到 1 分钟的通知,这就是为什么我需要超过 1 个并行线程。
就我而言,我正在使用 RichFlatMapFunction 来保持以前的模式以识别下一个模式,然后发送通知,这是我的代码:
final DataStream<EventPush> eventsStream = RabbitMQConnector.eventStreamObject(env)
.flatMap(new RabbitMQPushConsumer())
.keyBy(k -> k.id);
private static SingleOutputStreamOperator<String> getPushToSend(KeyedStream<EventPush, String> stream) {
return stream.flatMap(new WebPushFlatMapFunction())
.map(x -> new ObjectMapper().writeValueAsString(x));
}
/*the code below belongs to WebPushFlatMapFunction class, which is the RichFlatMapFunction using ValueState*/
private boolean inTime(long start, long end) {
final long difference = (end > start) ? (end - start) : (start - end);
long time_frame = 120000L;
return difference > 0 && time_frame >= difference;
}
@Override
public void flatMap(EventPush value, Collector<EventPush> out) {
final String pageName= value.pageName.trim();
Tuple4<String, String, Long, Timestamp> prev;
try {
prev = previous.value();
if (b_pageName.equalsIgnoreCase(pattern)) {
LOG.info("umid " + value.idsUmid + " match (" + pattern + ") at: " + value.timestamp);
previous.update(new Tuple4<>(value.idsUmid, pageName, value.timestamp.getTime(), value.timestamp));
}
if (prev != null) {
if (inTime(value.timestamp.getTime(), prev.f2)) {
if ((prev.f1 != null && !prev.f1.equals("")) && prev.f1.equals(full_pattern) && pageName.equals(home) && prev.f3.before(value.timestamp)) {
if (PropertyFileReader.isWebPushLoggerActivated())
LOG.info("umid " + value.idsUmid + " match (" + home + ")" + "triggered at: " + value.timestamp);
prev.f1 = "";
out.collect(value);
}
if ((prev.f1 != null && !prev.f1.equals("")) && prev.f1.equals(pattern) && pageName.equals(full_pattern) && prev.f3.before(value.timestamp)) {
LOG.info("umid " + value.idsUmid + " match (" + full_pattern + ") at: " + value.timestamp);
prev.f3 = value.timestamp;
prev.f1 = pageName;
previous.update(prev);
}
}
}
} catch (IOException e) {
CatchHandler.generalCatchHandler(e);
}
}
通过并行度 1,我得到了正确的顺序:1,2,3。 除此之外,我可以在一个线程中接收 1 个,从另一个线程接收 3 个,因为所有这些都属于同一个用户密钥,并且这 3 个状态将在不同的线程中进行分区。 我的问题:有没有办法以更多的并行性来做到这一点? 亲切的问候。
听起来您希望将每个用户的所有分析放在一起,但同时对不同用户执行分析。 执行此操作的方法是通过 userId 键入 stream。 这确实意味着对于单个用户,他们的事件由单个(非并行)管道处理。
如果这太慢了,您可能可以采取一些措施来加快速度。 通常最有帮助的事情包括:更有效的序列化、进行预聚合或增量聚合、删除 keyBys 或重新平衡,以及启用 object 重用。
我发现了问题,在后端,它将相同的 userId 分配给不同的用户(不知道如何但正在发生并且不是 flink),这就是为什么模式永远不匹配,因为不同的用户具有相同的以不同顺序发送事件的 userId 在同一个子任务中处理,它们在最后合并,例如来自 user1 的 event1 可以出现在来自 user2 的 event2 之后。 亲切的问候
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.