有状态流处理和流数据库两种数据处理方式比较


长期以来,在有状态流处理器和流数据库之间进行选择一直是一个有争议的问题。

  1. 一个流处理应用程序是一个DAG(直接无环图),其中每个节点是一个处理步骤。你通过编写单独的处理函数来编写DAG,这些函数在数据流经过它们时执行操作。这些函数可以是无状态的操作,如转换或过滤,也可以是有状态的操作,如记住前一次执行结果的聚合。有状态的流处理被用来从流数据中获得洞察力。
  2. 顾名思义,流式数据库可以从流式数据源摄取数据,并使其立即可用于查询。它们扩展了有状态的流处理,并带来了数据库世界的额外功能,如列式文件格式、索引、物化视图和散点收集查询执行。流数据库有两种变化:渐进式更新的物化视图和实时OLAP数据库。

1. 流式数据摄取和状态持久化
这两种技术同样能够从流数据源(如 Kafka、Pulsar、Redpanda、Kinesis 等)提取数据,在数据仍然新鲜时进行分析。他们还有可靠的水印策略来处理迟到的数据。
但是在持久化状态方面,它们是完全不同的。

  • 流处理器对状态进行分区并将其具体化到本地磁盘中以提高性能。此本地状态会定期复制到远程“状态后端”以实现容错。在大多数有状态流实现中,此过程称为检查点。
  • 另一方面,流式数据库遵循与许多数据库类似的方法。他们首先将摄取的数据写入磁盘支持的“段”,这是一种针对 OLAP 查询优化的面向列的文件格式。段在整个集群中复制,以实现可扩展性和容错。

2.查询状态
由于状态被划分为多个实例,因此单个流处理器节点仅保存整个状态的子集。您必须联系多个节点以针对完整状态运行交互式查询。在那种情况下,你怎么知道要联系哪些节点?

  • 幸运的是,许多流处理器提供端点来对状态运行交互式查询,例如Kafka Streams 中的状态存储。然而,它们并不像他们承诺的那样可扩展。或者,流处理器可以将聚合状态写入读优化存储,例如键值数据库,以减轻查询的复杂性。
  • 在查询状态时,流式数据库的行为类似于常规 OLAP 数据库。他们利用查询规划器、索引和智能查询修剪技术来提高查询吞吐量并减少延迟。
    一旦流式数据库接收到查询,查询代理会将其分散到托管相关段的节点上。查询在节点本地执行。代理收集结果,将它们拼接在一起,然后将它们返回给调用者。

3.放置状态操作逻辑

  • 流处理器要求你事先了解状态操作逻辑,并将其烘托到数据处理流程中。例如,为了计算事件的运行总数,你必须首先把逻辑写成一个流处理作业,对其进行编译、打包,并在流处理器的所有实例中进行部署。
  • 相反,流式数据库对状态操作有一个临时的和以人为中心的方法。它们将状态操作逻辑卸载给消费者应用程序,这可能是一个人、一个仪表板、一个API或一个数据驱动的应用程序。最终,消费者决定对状态做什么,而不是事先决定。

4.状态操作逻辑的实现

  • 流处理器为您提供了许多接口来实现访问和操作状态的逻辑。作为开发人员,您可以使用您选择的编程语言(例如 Java、Scala、Python、Go 等)编写数据流。流处理器然后获取该代码,将其转换为优化的 DAG,并在整个集群中分发。您还可以使用 SQL 来指定数据流。但是,编程语言为您提供了对 SQL 的更多控制和灵活性。
  • SQL 是访问大多数流式数据库中状态的主要接口。SQL 为消费者访问状态提供了一种通用的、声明性的、简洁的方法。此外,它还支持流式数据库和下游消费者(如 BI 和报告工具)之间的平滑集成。

5.在流式ETL管道中的位置
通过流处理器,你把处理逻辑开发成一个DAG,它有一个源(数据流的源头)和一个汇(数据流的终止点)。DAG中的每个节点代表一个处理功能,如map(转换)、过滤、聚合、减少等。
当这个DAG执行时,它将使进入流处理器的东西有可能在不同的地方结束,也许是不同的机器运行时间。
所以,流处理器可以执行流式ETL操作,在写入磁盘或其他系统之前对数据进行预处理。例如,我们可以结合流来充实、过滤不需要的数据,并在写入最终输出之前执行窗口化聚合。

流数据库在执行数据的预处理方面并不出色。虽然它们仍然可以在数据摄取期间用小型静态表进行查找连接,并进行一些轻量级的转换,但它们并不是为了处理复杂的数据处理而设计的。因此,流处理器被放置在流ETL管道的中间位置,而流数据库被放置在管道的服务端(终端)。

6. 理想用例

  • 部署状态操作逻辑后,流处理器将继续执行,无需进一步的人工干预。因此,流处理器非常适合您需要以最小的人为错误做出快速决策的用例。异常检测、实时个性化、监控和警报是决策可以自动化并转移到机器上的一些示例。
  • 流式数据库以一种特殊的方式(基于拉取的方法)迎合了需要快速和新鲜数据的用例。因此,它们非常适合通过应用程序、仪表板或 API 查询状态的人类决策者。面向用户的分析、数据驱动的应用程序和 BI 是流式数据库的一些很好的用例。


结论
有状态的流处理器和流式数据库之间的界限已经开始模糊。两者都试图以不同的方式解决问题。选择任何一种都应该由用例、技能差距以及你想以多快的速度进入市场来决定。
因此,让我给您一些建议,以帮助您确定选择标准。

在以下情况下使用流处理器
当您提前确切知道如何操作状态时,有状态流处理器是很好的。它们非常适合为机器设计的用例,在这些用例中,低延迟决策是重中之重,人工干预较少。此外,如果您的流数据需要在最终决策之前进一步清理和按摩,您可以使用流处理器作为流 ETL 管道。
如果您需要快速访问具体化状态,可以将状态写入读取优化的数据库并运行查询。

在以下情况下使用流式数据库
流式数据库非常适合无法提前预测数据访问模式的用例。它们首先捕获传入的流,并允许您使用随机访问模式按需查询。当您不需要对传入数据进行大量转换并且您的管道终止于服务层时,流式数据库也很好。

将它们都放在一个部署中将是一个白日梦。
MaterializeRisingWaveDeltaStream是该领域的新兴技术,它们试图将流处理和流数据库整合为一个自助服务平台。