7

如您所知,Kappa 架构是 Lambda 架构的某种简化。Kappa 不需要批处理层,相反,速度层必须保证历史数据重新计算的计算精度和足够的吞吐量(更多的并行性/资源)。

当您需要基于历史数据进行分析时,Kappa 架构仍然需要两个服务层。例如,年龄小于 2 周的数据存储在 Redis(流服务层),而所有较旧的数据都存储在 HBase(批处理服务层)的某个位置。

何时(由于 Kappa 架构)我必须将数据插入批处理服务层? 如果流层将数据立即插入批处理和流服务层 - 那么延迟数据到达呢?还是流媒体层应该定期备份速度服务层到批量服务层?


示例:假设数据源是 Kafka,数据由 Spark Structured Streaming 或 Flink 处理,接收器是 Redis 和 HBase。何时写入 Redis 和 HBase?

4

1 回答 1

1

如果我们执行流处理,我们希望确保输出数据首先作为数据流可用。在您的示例中,这意味着我们将 Kafka 作为主要接收器写入。

现在你有两个选择:

  • 具有从该 Kafka 主题读取并写入 Redis 和 HBase 的辅助作业。这就是 Kafka 方式,因为 Kafka Streams 不支持直接写入这些系统中的任何一个,并且您设置了 Kafka 连接作业。然后可以针对特定的接收器定制这些辅助作业,但它们会增加额外的操作开销。(这是您提到的一些备份选项)。
  • 使用 Spark 和 Flink,您还可以选择在工作中直接使用辅助接收器。您可以添加额外的处理步骤以将 Kafka 输出转换为更适合接收器的形式,但在配置作业时您会受到更多限制。例如在 Flink 中,您需要对 Kafka 接收器和 Redis/HBase 接收器使用相同的检查点设置。不过,如果设置成功,您只需要运行一个流式作业而不是 2 或 3 个。

迟到的事件

现在的问题是如何处理迟到的数据。最好的解决方案是让框架通过水印来处理。也就是说,只有在框架确定没有迟到的数据到达时,才会在所有接收器上提交数据。如果这不起作用,因为您确实需要处理迟到的事件,即使它们很晚才到达并且仍然希望获得临时结果,那么您必须使用更新事件。

更新事件

(根据 OP 的要求,我将在更新事件中添加更多详细信息)

在 Kafka Streams 中,默认情况下,元素是通过连续细化机制发出的。这意味着,窗口聚合一旦有任何有效数据点就会发出结果,并在接收新数据时更新该结果。因此,任何迟到的事件都会被处理并产生更新的结果。虽然这种方法很好地减轻了用户的负担,因为他们不需要了解水印,但它有一些严重的缺点,导致 Kafka Streams 开发人员在 2.1 及更高版本中添加了Suppression

主要问题是它对向下的用户处理中间结果提出了相当大的挑战,这也在关于 Suppression 的文章中进行了解释。如果结果是临时的还是“最终的”(从某种意义上说,所有预期的事件都已处理)并不明显,那么许多应用程序就更难实现。特别是,需要在消费者端复制窗口操作以获得“最终”值。

另一个问题是数据量被炸毁。如果您有很强的聚合因子,那么使用基于水印的发射将在第一次操作后大大减少您的数据量。但是,随着每条记录触发所有中间步骤的新(中间)记录,连续细化将增加一个恒定的体积因子。

最后,对您来说特别有趣的是,如果您有更新事件,如何将数据卸载到外部系统。理想情况下,您将连续或定期卸载具有一定时间延迟的数据。该方法在消费者端再次模拟基于水印的发射。

混合选项

可以将水印用于初始发射,然后将更新事件用于后期事件。然后为所有“准时”事件减小音量。例如,Flink 提供允许延迟以使窗口再次触发延迟事件。

这种设置使卸载数据变得更加容易,因为只有在实际发生延迟事件时才需要将数据重新发送到外部系统。应该调整系统,因为迟到的事件是一种罕见的情况。

于 2019-11-25T07:52:05.690 回答