Google cloud dataflow 数据流/光束模板、Productionization、初始化和ValueProviders

Google cloud dataflow 数据流/光束模板、Productionization、初始化和ValueProviders,google-cloud-dataflow,apache-beam,dev-to-production,Google Cloud Dataflow,Apache Beam,Dev To Production,我有一个Apache Beam作业在Google Cloud Dataflow上运行,作为其初始化的一部分,它需要对服务、发布/订阅、GCS Blob等运行一些基本的健全性/可用性检查。它是一个流式管道,旨在无限期地运行,处理数十万条发布/订阅消息 目前,它需要一堆必需的可变参数:它需要在哪个Google云项目中运行,它要在哪个bucket和目录前缀中存储文件,它需要从哪个pub/sub订阅中读取,等等。在调用pipeline.run之前,它会对这些参数进行一些处理—验证、字符串拆分等。在它当前

我有一个Apache Beam作业在Google Cloud Dataflow上运行,作为其初始化的一部分,它需要对服务、发布/订阅、GCS Blob等运行一些基本的健全性/可用性检查。它是一个流式管道,旨在无限期地运行,处理数十万条发布/订阅消息

目前,它需要一堆必需的可变参数:它需要在哪个Google云项目中运行,它要在哪个bucket和目录前缀中存储文件,它需要从哪个pub/sub订阅中读取,等等。在调用pipeline.run之前,它会对这些参数进行一些处理—验证、字符串拆分等。在它当前的形式中,为了开始一项工作,我们一直在将这些参数传递给PipelineOptionFactory,并每次都发布一个新的编译,但似乎应该有更好的方法。我已将参数设置为ValueProvider对象,但由于它们是在pipeline.run之外调用的,Maven在编译时抱怨ValueProvider.get()是在运行时上下文之外调用的(是的,确实如此)

我曾尝试在Google“”文档中使用NestedValueProviders,但如果我尝试使用NestedValueProvider.of返回文档中所示的字符串,我的IDE会抱怨。我能够让NestedValueProviders编译的唯一方法如下:

NestedValueProvider<String, String> pid = NestedValueProvider.of(
        pipelineOptions.getDataflowProjectId(),
        (SerializableFunction<String, String>) s -> s
);
NestedValueProvider pid=NestedValueProvider.of(
pipelineOptions.getDataflowProjectId(),
(SerializableFunction)s->s
);
(字符串pid=NestedValueProvider.of(…)导致以下错误:“不兼容的类型:不存在类型变量T,X的实例,因此org.apache.beam.sdk.options.ValueProvider.NestedValueProvider符合java.lang.String”)

我的管道选项中有以下内容:

ValueProvider<String> getDataflowProjectId();
void setDataflowProjectId(ValueProvider<String> value);
ValueProvider getDataflowProjectId();
void setDataflowProjectId(ValueProvider值);
由于我们将要处理的消息量很大,在管道前端为每一条通过的消息添加这些检查是不实际的;我们将很快达到其中一些呼叫的每日帐户管理限制

模板是我想要做的事情的正确方法吗?我该怎么做才能真正产生电离呢?我是否应该(可以?)用maven编译成一个jar,然后用我的参数在本地dev/qa/prod框上运行jar,而不必麻烦使用ValueProviders?或者是否可以向ValueProvider提供默认值,并将其作为传递给模板的选项的一部分覆盖


任何关于如何进行的建议都将不胜感激。谢谢

按照当前模板的实现方式,没有必要执行“模板创建后”操作,而是“管道启动前”初始化/验证

所有现有验证都在模板创建期间执行。如果验证检测到这些值不可用(由于是ValueProvider),则跳过验证

在某些情况下,可以通过添加运行时检查(作为自定义源的初始拆分的一部分或
DoFn的
@Setup
方法的一部分)来近似验证。在后一种情况下,
@Setup
方法将为创建的每个DoFn实例运行一次。如果管道是批处理的,在特定实例发生4次故障后,它将使管道失败

生产电离管道的另一个选择是构建运行管道的JAR,并有一个运行该JAR的生产流程来启动管道

关于您收到的编译错误--
NestedValueProvider
返回一个
ValueProvider
--无法从中获取
字符串。但是,您可以将验证代码放入
NestedValueProvider
中运行的
SerializableFunction

虽然我相信每次访问该值时都会重新运行验证,但让
NestedValueProvider
缓存转换后的值并不是不合理的。

好的,谢谢。我现在正在尝试jar路线,但是我在让它识别dataflow runner时遇到了一个问题:线程“main”java.lang.IllegalArgumentException中的异常:未知的“runner”指定了“dataflow”,支持的管道运行器[DirectRunner]有另一篇关于此的帖子,但唯一的答案是指定在编译时运行,这不是一个选项。这听起来像是类路径问题。确保包含Dataflow runner的JAR在运行时可用;问题是pom中的依赖项排序。我将dataflow runner移到了依赖项列表的顶部,一切都开始工作了。谢谢你!