带有实例本地缓存+外部REST API调用的Google Dataflow Pipeline

时间:2017-04-21 06:10:42

标签: google-cloud-dataflow apache-beam

我们希望构建一个Cloud Dataflow Streaming管道,它从Pubsub中提取事件并对每个单独的事件执行多个类似ETL的操作。其中一个操作是每个事件都有一个 device-id 需要转换为不同的值(让我们称之为 mapped-id ),这个映射来自< em> device-id-&gt; mapped-id 由外部服务通过REST API提供。可能会在多个事件中重复相同的 device-id - 因此可以缓存并重新使用这些 device-id-&gt; mapped-id 映射。由于我们可能通过管道在峰值处理每秒多达3M个事件,因此需要尽可能减少对REST API的调用,并在实际需要调用时进行优化。

考虑到这种设置,我有以下问题。

  • 为优化REST API调用,Dataflow是否提供任何内置优化,如连接池,或者如果我们决定使用自己的此类机制,是否需要记住任何限制/限制?

  • 我们正在研究一些内存缓存选项,以本地缓存映射,其中一些也由本地文件支持。那么,这些缓存使用多少内存(作为总实例内存的一小部分)是否有任何限制而不影响工作者中的常规Dataflow操作?如果我们使用文件支持的缓存,那么每个工作者是否都有一个路径,应用程序本身可以安全地使用它来构建这些文件?

  • 唯一 device-id 的数量可能是数百万的数量级 - 因此并非所有这些映射都可以存储在每个实例中。因此,为了能够更好地利用本地缓存,我们需要在 device-id 与处理它们的工作者之间建立一些关联。我可以在发生此转换的阶段之前基于 device-id 进行分组。如果我这样做,是否可以保证相同的 device-id 或多或少会由同一个工作人员处理?如果有一些合理的保证,那么除了第一次调用之外,我不必在大多数时间点击外部REST API。或者是否有更好的方法来确保ids和工人之间的这种亲和力。

谢谢

1 个答案:

答案 0 :(得分:3)

以下是您可以做的一些事情:

  • 您的DoFn可以有实例变量,您可以将缓存放在那里。
  • 只要正确管理对它的多线程访问,也可以将常规Java静态变量用于VM本地的缓存。 Guava CacheBuilder在这里可能真的很有帮助。
  • 对工作人员的临时文件使用常规Java API是安全的(但同样要注意对文件的多线程/多进程访问,并确保清理它们 - 您可能会发现DoFn {{1 }}和@Setup方法很有用。)
  • 您可以通过设备ID执行@Teardown;那么,大多数情况下,至少在Cloud Dataflow运行器中,相同的密钥将由同一个工作程序处理(尽管密钥分配可以在管道运行时更改,但通常不会太频繁)。您可能希望通过立即触发来设置窗口/触发策略。