虽然 Lambda 架构使用起来十分灵活,并且可以适用于很多的应用场景,但在实际应用的时候,Lambda 架构也存在着一些不足,主要表现在它的维护很复杂。使用 Lambda 架构时,架构师需要维护两个复杂的分布式系统,并且保证他们逻辑上产生相同的结果输出到服务层中。

1. Kappa 架构

Kappa 架构是由 LinkedIn 的前首席工程师杰伊·克雷普斯(Jay Kreps)提出的一种架构思想。

像 Apache Kafka 这样的流处理平台是具有永久保存数据日志的功能的,通过平台的这一特性,我们可以重新处理部署于速度层架构中的历史数据。

与 Lambda 架构不同的是,Kappa 架构去掉了批处理层这一体系结构,而只保留了速度层。你只需要在业务逻辑改变又或者是代码更改的时候进行数据的重新处理。

Kappa 架构的核心思想包括以下三点:

  1. 用 Kafka 或者类似的分布式队列系统保存数据,你需要几天的数据量就保存几天。
  2. 当需要全量重新计算时,重新起一个流计算实例,从头开始读取数据进行处理,并输出到一个新的结果存储中。
  3. 当新的实例做完后,停止老的流计算实例,并把老的一些结果删除。

和 Lambda 架构相比,在 Kappa 架构下,只有在有必要的时候才会对历史数据进行重复计算,并且实时计算和批处理过程使用的是同一份代码。或许有些人会质疑流式处理对于历史数据的高吞吐量会力不从心,但是这可以通过控制新实例的并发数进行改善。

上面架构图中,新老实例使用了各自的结果存储,这便于随时进行回滚,更进一步,假如我们产出的是一些算法模型之类的数据,用户还可以同时对新老两份数据进行效果验证,做一些A/B test或者使用bandit算法来最大限度的使用这些数据。

2. Kappa 选型

3. Kappa 实现

Apache Kafka 这样的流处理平台是具有永久保存数据日志的功能的。通过平台这一特性,我们可以重新处理部署速度层架构的历史数据了。

截屏2020-09-15 上午9.31.26
  1. 第一步。部署 Apache Kafka,并设置数据日志的保留期。这里的保留期指的是希望能够重新处理的历史数据的时间区间。

    例如,你希望重新处理最多一年的历史数据,那就可以把 Apache Kafka 中的保留期设置为 365 天。如果你希望能够处理所有的历史数据,那就可以把 Apache Kafka 中的保留期设置成“永久”。

  2. 第二步。如果我们需要改进现有的逻辑算法,那就表示需要对历史数据进行重新处理。

    重新启动一个 Apache Kafka 作业实例。这个作业实例将重头开始,重新计算保留好的历史数据,并将结果输出到一个新的数据视图中,Apache Kafka 的底层是使用 Log Offset 来判断现在已经处理到哪个数据块了,所以只需要把 Log Offset 参数设置成0,新的作业实例就会重头开始处理历史数据。

  3. 第三步。当这个新的数据视图处理过的数据进度赶上了旧的数据视图时,我们的应用便可以切换到新的数据视图中读取。

  4. 第四步。停止旧版本的作业实例,并删除旧的数据视图。

4. Kappa 总结

因为 Kappa 架构只保留了速度层而缺少批处理层,在速度层上处理大规模数据可能会有数据更新出错的情况发生,这就需要花费更多的时间在处理这些错误异常上面。

还有一点,Kappa 架构的批处理和流处理都放在了速度层上,这导致了这种架构是使用同一套代码来处理算法逻辑的。所以 Kappa 架构并不适用于批处理和流处理代码逻辑不一致的场景。

1、消息中间件缓存的数据量和回溯数据有性能瓶颈。通常算法需要过去180天的数据,如果都存在消息中间件,无疑有非常大的压力。同时,一次性回溯订正 180 天级别的数据,对实时计算的资源消耗也非常大。

2、在实时数据处理时,遇到大量不同的实时流进行关联时,非常依赖实时计算系统的能力,很可能因为数据流先后顺序问题,导致数据丢失。

如果你所面对的业务逻辑是设计一种稳健的机器学习模型来预测即将发生的事情,那么你应该优先考虑使用 Lambda 架构,因为它拥有批处理层和速度层来确保更少的错误。

如果你所面对的业务逻辑是希望实时性比较高,而且客户端又是根据运行时发生的实时事件来做出回应的,那么你就应该优先考虑使用 Kappa 架构。