在 Cloud Dataflow 中限制对第三方的并发调用
Limiting concurrent calls to a third party in Cloud Dataflow
我正在研究需要将调用中的调用限制为第三方系统的管道,并考虑了几种不同的方法。
对于单个管道,我正在考虑使用无操作 keyed state 方法,这样并行性就受限于键的数量。基本上,将其包含在相关阶段:
// Add a fake state entry to force serialization per-key.
@StateId("force-serialization")
private final StateSpec<ValueState<String>> myStateSpec = StateSpecs.value();
对于多个管道,我正在考虑使用二级租赁系统,我们尝试在 startBundle
中申请租约(并且 return 在 finishBundle
中)。
最后一个问题是,在某些情况下,连续的阶段会调用相同的服务,并且需要共享相同的运行中限制。我希望它能很好地与 fusion 配合使用,并且如果它们被融合,则不会有连续的阶段竞争相同的租约。例如,采取连续阶段:
DoFn<KV<String, Foo>, KV<String, Bar>> Stage1 // Calls third party API
DoFn<KV<String, Bar>, KV<String, Baz>> Stage2 // Calls third party API
我想我可以在 Foo 中包含一个 'sameBundle' 标志,它在序列化时被删除。如果 Stage1 + Stage2 融合在一起,那么这个标志将从 Stage1 传递到 Stage2,我可以假设它们将共享相同的飞行中行为。如果不是,则不会传递标志,因此这两个阶段将尝试独立申请租约。从线程的角度来看,这似乎应该没问题,因为融合中断意味着 Stage1 的输出将在被 Stage2 使用之前设置检查点。
是的,使用键来限制并行度会很好。如果您实际上没有使用状态,则可以使用 GroupByKey 而不是 KeyedState。
使用二级租赁系统也可以,但您正确地指出了融合可能存在的问题。这里的主要困难是区分两个融合的 DoFns(永远不会同时执行并且可以共享租约)和两个并行处理不同工作项的 DoFns。如果 acquiring/releasing 从外部系统租赁太贵而无法 per-element,您可以拥有某种 two-level 系统,其中工作人员持有 per-worker(静态)租赁管理器可以快速服务租约 request/release 参数,这些参数在本地由来自辅助系统的租约支持,这些租约在更大的时间范围内 acquired/released。这可能适用于流式处理和批处理。
另一种选择是设置位于 third-party 系统前面并处理全局吞吐量限制的代理服务。
对于所有这些,如果工作人员大部分时间都在闲置等待租约,则需要考虑对自动缩放的任何不利影响。
我正在研究需要将调用中的调用限制为第三方系统的管道,并考虑了几种不同的方法。
对于单个管道,我正在考虑使用无操作 keyed state 方法,这样并行性就受限于键的数量。基本上,将其包含在相关阶段:
// Add a fake state entry to force serialization per-key.
@StateId("force-serialization")
private final StateSpec<ValueState<String>> myStateSpec = StateSpecs.value();
对于多个管道,我正在考虑使用二级租赁系统,我们尝试在 startBundle
中申请租约(并且 return 在 finishBundle
中)。
最后一个问题是,在某些情况下,连续的阶段会调用相同的服务,并且需要共享相同的运行中限制。我希望它能很好地与 fusion 配合使用,并且如果它们被融合,则不会有连续的阶段竞争相同的租约。例如,采取连续阶段:
DoFn<KV<String, Foo>, KV<String, Bar>> Stage1 // Calls third party API
DoFn<KV<String, Bar>, KV<String, Baz>> Stage2 // Calls third party API
我想我可以在 Foo 中包含一个 'sameBundle' 标志,它在序列化时被删除。如果 Stage1 + Stage2 融合在一起,那么这个标志将从 Stage1 传递到 Stage2,我可以假设它们将共享相同的飞行中行为。如果不是,则不会传递标志,因此这两个阶段将尝试独立申请租约。从线程的角度来看,这似乎应该没问题,因为融合中断意味着 Stage1 的输出将在被 Stage2 使用之前设置检查点。
是的,使用键来限制并行度会很好。如果您实际上没有使用状态,则可以使用 GroupByKey 而不是 KeyedState。
使用二级租赁系统也可以,但您正确地指出了融合可能存在的问题。这里的主要困难是区分两个融合的 DoFns(永远不会同时执行并且可以共享租约)和两个并行处理不同工作项的 DoFns。如果 acquiring/releasing 从外部系统租赁太贵而无法 per-element,您可以拥有某种 two-level 系统,其中工作人员持有 per-worker(静态)租赁管理器可以快速服务租约 request/release 参数,这些参数在本地由来自辅助系统的租约支持,这些租约在更大的时间范围内 acquired/released。这可能适用于流式处理和批处理。
另一种选择是设置位于 third-party 系统前面并处理全局吞吐量限制的代理服务。
对于所有这些,如果工作人员大部分时间都在闲置等待租约,则需要考虑对自动缩放的任何不利影响。