让我一一回答你的问题。
为什么他们在这个例子中没有使用任何流媒体层(比如 Kafka)?
我认为您对 Flink 中的流式传输存在误解。首先,Flink 是流处理引擎。基本上,Flink 正在处理的一切都是流。
很多人都知道 Flink 可以在流模式或批处理模式下工作,但是对于 Flink 来说,批处理只是具有有限长度的流的一种特殊情况,而流通常是无限的。所以在 Flink 中一切都是事件流。所以问题是 Flink 从哪里获取数据。
Flink 可以从多个源中读取数据,而 Kafka 是可以在 Flink 中使用的源之一。看看Flink 存储库中的这个和这个文件夹。它们包含在 Flink 中实现不同的源,包括 Kafka、Kinesis、RabbitMQ 等。从 Flink 的角度来看,数据是来自外部系统、从文件中读取还是正在生成都无关紧要。
Flink 用户可以实现他/她将由 Flink 运行时使用的数据源。为此,需要扩展RichSourceFunction
类并实现该run
方法。例如,此数据源将生成从 0 开始的无限数字流:
public class DummySource extends RichParallelSourceFunction<Integer> {
public void run(SourceContext<Integer> sourceContext) throws Exception {
// You can specify custom termination conditions
// the source should not be inifite
int i = 0;
while (true) {
// provide an event for Flink processing
sourceContext.collect(i);
i++;
}
}
}
由于使用什么数据源并不重要,本教程的作者决定简化示例并使用使用随机数生成器生成数据的简单数据源:
MonitoringEvent monitoringEvent;
int rackId = random.nextInt(shard) + offset;
if (random.nextDouble() >= temperatureRatio) {
double power = random.nextGaussian() * powerStd + powerMean;
monitoringEvent = new PowerEvent(rackId, power);
} else {
double temperature = random.nextGaussian() * temperatureStd + temperatureMean;
monitoringEvent = new TemperatureEvent(rackId, temperature);
}
sourceContext.collect(monitoringEvent);
虽然实际上您会从 Kafka 或 Kinesis 等外部系统读取事件数据,但该示例有意简化以显示 CEP 库的要点。
何时何地需要流式传输?
如果“流式传输”是指非批处理,那么可以肯定地说,它应该在不断接收事件并且您需要接近实时的处理时间时使用。
如果您询问何时应该使用 Kafka,那么您可以将其用于处理事件流、将其用作消息代理、将其用于日志聚合等。以下是您可以使用 Apache Kafka 的用例列表。
参考 Flink CEP 示例,我想知道流层(如 Kafka/Kinesis)将在何处以及如何发挥作用?
如果像 Kafka/Kinesis 这样的流媒体层介于两者之间,会有什么优点/缺点?
在现实世界的应用程序中,您将使用 Kafka/Kinesis 数据源或从外部系统读取数据的不同数据源。
Kafka 是现有消息代理(如 RabbitMQ)的替代品,具有出色的性能特征,但您可以在 Flink 中使用其他数据源,甚至可以自己编写。