Samza 重新处理以前处理的数据

2018-08-22 18:07 更新

有时您可能希望部署新版本的 Samza 作业,以不同的方式计算结果;也许你修复了一个 bug 或者引入了一个新功能。例如,假设您有一个 Samza 工作,将邮件分类为垃圾邮件或非垃圾邮件,使用您在离线培训的机器学习模型。您希望定期部署 Samza 工作的更新版本,其中包括最新的分类模型。

当您启动新版本的工作时,会出现一个问题:您以前用旧版本的作业处理的邮件要做什么?答案取决于你想要的行为:

  1. 无重新处理:默认情况下,Samza 假定旧版本处理的消息不需要再次处理。当新版本启动时,它将在旧版本停止时恢复处理(假设您启用了检查点)。如果这是你想要的行为,没有什么特别需要做的。
  2. 简单的倒带:也许你想回去并使用新版本的工作重新处理旧邮件。例如,也许旧版本的分类器将垃圾邮件标记为太大,所以您现在想要使用改进的分类器重新审视其以前的垃圾邮件/非垃圾邮件决定。您可以通过在流中较旧的时间点重新启动作业,并从该时间开始运行所有消息来执行此操作。因此,您的工作开始重新处理已经看到的消息,但是当重新处理完成后,它将无缝地继续新的消息。

这种方法需要一个输入系统,如 Kafka,它允许您在时间上跳回到流中的上一个点。下面我们来讨论这个工作原理。

  1. 平行倒带:这种方法避免了简单的倒带方法的缺点。通过简单的倒带,作业正在重新处理旧数据时出现的任何新消息都将排队,并在重新处理完成后进行处理。排队延迟不需要太长时间,因为 Samza 可以快速流式传输历史数据,但一些延迟敏感的应用程序需要更快地处理消息。

在并行重绕方法中,您并行运行两个作业:一个作业继续处理低延迟(实时作业)的实时更新,而另一个作业在流中的较旧点启动并重新处理历史数据(后处理工作)。这两个作业在不同的时间点消耗相同的输入流,最终后处理工作可以满足实时工作。

在部署并行倒带之前,您需要仔细思考一些细节,我们在下面讨论。

及时跳回

简单的倒带和平行倒带方法的一个常见方面是:您有一个工作可以在输入流中跳回旧的时间点,并从那时起就消耗所有的消息。通过与 Samza 的检查点合作来实现这一点。

通常,当 Samza 作业启动时,它会读取最新的检查点,以确定需要恢复处理的输入流中哪个偏移量。如果你需要回到更早的时间,可以采取以下两种方式之一:

  1. 您可以停止该作业,操作其最后一个检查点以指向较旧的偏移量,然后重新启动该作业。Samza 包括一个名为 CheckpointTool 的命令行工具,可用于操作检查点。
  2. 您可以使用不同的 job.name 或 job.id 启动新作业(例如,每当您需要及时跳回时,都会增加 job.id)。这给工作一个新的检查点流,没有旧的检查点信息。您还需要设置 samza.offset.default =最旧的,这样当作业启动时没有检查点,它开始消耗在可用的最旧的偏移量。

使用这些方法之一,您可以让 Samza 在输入系统中重新处理消息的整个历史记录。输入系统如 Kafka 可以保留大量的历史 - 参见下面的讨论。为了加快历史数据的再处理,可以(增加容器数 job.container.count 如果你在纱线行走 Samza),以提高你的工作的计算资源。

如果您的工作保持任何持续状态,则需要在及时跳回时小心:重置检查点不会自动更改持久状态,因此您可以在稍后使用状态时最终重新处理旧消息。在大多数情况下,及时跳回的工作应以空状态开始。您可以通过删除更改日志主题或更改作业配置中更改日志主题的名称来重置状态。

当你及时回来时,你使用 Samza 有点像一个批处理框架(例如 MapReduce) - 区别在于处理所有历史数据后,你的工作不会停止,而是继续运行处理新消息流时,它的优势在于您不需要编写和维护您的工作的单独批量和流式版本:您可以使用相同的 Samza API 来处理实时和历史数据。

保留历史

Samza 本身不保留历史 - 输入系统的责任,如 Kafka。你可以跳多远的时间取决于该系统中保留的历史记录数量。

Kafka 旨在保持相当大的历史:Kafka 经纪人通常可以保留一个或两个星期的消息历史记录,即使是大量的话题。保留期大部分取决于您有多少磁盘空间。即使你有太字节的历史,Kafka 的表现仍然很高。

X- 200 200 X- 200 200 X- 200 200 X-

  • 活动事件包括用户跟踪事件,Web 服务器日志事件等。这种流通常配置有基于时间的保留,例如数周。比保留期更早的事件将被删除(或存档在脱机系统,如 HDFS)中。
  • 数据库更改是在数据库中显示插入,更新和删除的事件。在这种流中,每个事件通常都有一个主键,一个新的事件用于覆盖同一个键的任何较旧的事件。如果相同的密钥更新了很多次,那么您只对最近的值感兴趣。(Samza 持续状态使用的更改日志流属于此类别。)

在数据库更改流中,当您重新处理数据时,通常要重新处理整个数据库。你不想错过一个值,因为它上次更新是在几个星期前。换句话说,您不希望只是因为比某个阈值更早而删除更改事件。在这种情况下,当您及时跳回时,您需要重新开始时间,即先对数据库进行的更改(在 Kafka 中称为 “offset 0”)。

幸运的是,可以使用称为日志压缩的 Kafka 功能有效地完成此操作。

例如,假设您的数据库包含计数器:每当发生一些事情时,您将增加相应的计数器并使用新的计数器值更新数据库。每个更新都会发送到更改日志,并且由于有更多更新,更改日志流将占用大量空间。启用日志压缩后,Kafka 会在后台对数据流进行重复数据删除,只保留每个密钥的最新计数器值,并删除相同计数器的任何旧值。这样可以减少流的大小,以便您可以保留每个密钥的最新更新,即使最近更新了很久以前。

启用日志压缩后,数据库更改流将成为整个数据库的完整副本。通过跳转到 0,您的 Samza 作业可以扫描整个数据库并重新处理它。这是构建可扩展应用程序的非常强大的方法。

平行回卷的细节

如果您采用上述并行重绕方法,并行运行两个作业,则需要仔细配置它们以避免出现问题。特别要注意的是:

  • 确保两个作业不会相互干扰。他们需要不同的 job.name 或 job.id 配置属性,以便每个作业都有自己的检查点流。如果作业保持持续状态,每个作业都需要自己的更改日志(两个不同的作业写入相同的更新日志会产生未定义的结果)。
  • 工作输出会怎样?如果作业将其结果发送到输出流或写入数据库,则最简单的解决方案是为每个作业提供单独的输出流或数据库表。如果写入相同的输出,则需要注意确保较新的数据不被旧数据覆盖(由于两个作业之间的竞争条件)。
  • 您是否需要在旧版本和新版本的工作之间支持A / B测试,例如,测试新版本是否改进了您的指标?平行倒带是理想的:每个作业写入单独的输出,输出的客户端或消费者可以从旧版本或新版本的输出读取,具体取决于用户是否在测试组A或B中。
  • 回收资源:即使新版本已经完成重新处理历史数据(尤其是在A / B测试中使用旧版本的输出),您可能希望保持旧版本的作业运行一段时间。但是,最终你需要关闭它,并删除属于旧版本的检查点和 changelog 流。

Samza 为您提供了重新处理历史数据的很多灵活性,您不需要针对单独的批处理 API 进行编程,以利用它。如果您注意到这些问题,您可以建立一个非常强大的数据系统,但是您仍然可以随时更改处理逻辑。

Web UI 和 REST API  »

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号