【问题标题】:Kappa architecture: when insert to batch/analytic serving layer happensKappa 架构:当插入到批处理/分析服务层时
【发布时间】:2020-02-11 21:31:07
【问题描述】:

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

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

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


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

【问题讨论】:

  • 作为回答我自己问题的选项之一 - Apache Kudu 可能会加入两个服务层

标签: apache-spark architecture streaming apache-flink lambda-architecture


【解决方案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 提供allowed lateness 让窗口再次触发延迟事件。

此设置使卸载数据更加容易,因为只有在实际发生延迟事件时才需要将数据重新发送到外部系统。应该对系统进行调整,但迟到的事件很少见。

【讨论】:

  • 您能否提供有关更新事件的更多详细信息?恐怕我不明白这个想法。例如,Spark Structured Streaming 具有 UPDATE 模式,但仅在水印周期内。附言在批处理中,如果您可以容忍最终的一致性并且您的数据不依赖于先前的时期/时期,则可能很容易解决“非常”迟到的问题。当数据到达时(按处理时间) - 按事件时间重新分区并附加。但是在流处理中,你总是被绑定到水印
  • 添加了有关更新事件的更多信息。仅当您没有聚合时,您概述的处理迟到的方法才有效,因为您最终会在附加分区中得到两个冲突的记录。我可能会选择delta lake 来解决这些冲突。
猜你喜欢
  • 1970-01-01
  • 2016-03-26
  • 2014-02-05
  • 2021-09-08
  • 1970-01-01
  • 2011-11-20
  • 2014-04-13
  • 2011-12-21
  • 1970-01-01
相关资源
最近更新 更多