在实践(不是理论)中,迷你批处理与实时流有什么区别?理论上,我理解迷你批处理是在给定的时间框架内批量处理的东西,而实时流更像是在数据到达时做一些事情,但我最大的问题是为什么不使用epsilon时间框架(比如一毫秒)的迷你批处理,或者我想了解为什么一个会是一个有效的解决方案?
我最近遇到了一个例子,其中迷你批处理(Apache Spark)用于欺诈检测,实时流(Apache Flink)用于欺诈预防。有人还评论说,小批量不会是防止欺诈的有效解决方案(因为目标是防止交易发生)。现在我想知道为什么小批量(Spark)不会如此有效?为什么用1毫秒的延迟运行小批处理是无效的?批处理是一种无处不在的技术,包括操作系统和内核TCP/IP堆栈,其中到磁盘或网络的数据确实是缓冲的,那么这里说一个比另一个更有效的令人信服的因素是什么?
免责声明:我是Apache Flink的提交者和PMC成员。我熟悉Spark Streaming的整体设计,但不了解它的详细内部。
Spark Streaming实现的小批量流处理模型如下:
- 流的记录收集在缓冲区(mini-batch)中。
- 定期使用Spark作业处理收集到的记录。这意味着,对于每个小批处理,将调度并执行一个完整的分布式批处理作业。
- 作业运行时,收集下一批的记录。
那么,为什么每1ms运行一个小批处理是无效的呢?这很简单,因为这意味着每毫秒调度一个分布式批处理作业。尽管Spark在调度作业方面非常快,但这有点太过了。它还将显著降低可能的吞吐量。在操作系统或TCP中使用的批处理技术,如果它们的批处理变得太小,也不能很好地工作。
我知道一个答案被接受了,但我认为必须再说一个才能完全回答这个问题。我认为回答像"Flink的实时是更快/更好的流媒体"是错误的,因为它在很大程度上取决于你想做什么。
Spark小批处理模型有一个缺点——正如它在前面的回答中所写的那样——对于每个小批处理必须创建新的作业。
然而,Spark结构化流具有默认处理时间触发器设置为0,这意味着读取新数据尽可能快地完成。这意味着:
- 一个查询开始
- 数据到达,但是第一次查询没有结束
- 第一个查询结束,因此数据将立即处理。
在这种情况下,延迟非常小。
相对于Flink的一个很大的优势是Spark有统一的api 用于批处理和流处理,因为这个小批处理模型。您可以轻松地将批处理作业转换为流作业,将流数据与批处理中的旧数据连接起来。用Flink是不可能做到的。Flink也不允许你对收到的数据进行交互式查询。
如前所述,微批处理和实时流的用例是不同的:
- 对于非常非常小的延迟,Flink或一些计算网格,如Apache Ignite,将是很好的。它们适用于延迟非常低的处理,但不适用于非常复杂的计算。
- 对于中等和较大的延迟,Spark将有更统一的API,允许以与批处理作业相同的方式进行更复杂的计算,只是因为这个统一
有关结构化流媒体的更多详细信息,请查看此博客文章
这是我经常思考的问题,因为技术人员和非技术人员的答案总是很难明确。
我试着回答这部分:
为什么用1毫秒的延迟运行mini-batch不有效?
我认为问题不在于模型本身,而在于Spark如何实现它。经验证明,减少小批窗口过多会导致性能下降。实际上,建议至少使用0.5秒或更长时间来防止这种退化。在大的卷上,甚至这个窗口大小也太小了。我从来没有机会在生产环境中测试它,但我从来没有强烈的实时需求。
我比Spark更了解Flink,所以我不太了解它的内部结构,但我相信,如果你的批处理至少需要几秒钟的时间来处理,但如果它们引入了固定的延迟,并且你不能低于这个延迟,那么在批处理设计中引入的开销就无关紧要了。要了解这些开销的本质,我认为您必须深入研究Spark文档、代码和开放问题。
行业现在承认需要一种不同的模式,这就是为什么现在许多"流媒体优先"引擎正在成长,Flink是领先者。我不认为这只是流行语和炒作,因为这种技术的用例,至少现在,是非常有限的。基本上,如果你需要对大而复杂的数据进行实时的自动化决策,你需要一个实时快速的数据引擎。在任何其他情况下,包括接近实时的实时流都是多余的,而mini-batch则很好。