有没有办法为数据流作业上传 jar,这样我们就不必序列化所有内容?

Is there a way to upload jars for a dataflow job so we don't have to serialize everything?

举个例子,我记得在 hadoop 中,我可以使 类 可序列化,或者提供一个包含我工作所需的 jars 的路径。我有两种选择。我想知道这在数据流作业中是否属实,这样我就可以将 jar 文件中的所有客户端打包供所有工作人员使用。

在我们的例子中,我们有 MicroserviceApi 和一个生成的客户端等,并且更愿意输出到下游微服务而不必使其可序列化。

有没有办法做到这一点?

  1. 首先,让我澄清一下序列化

当您将 implements Serializable 添加到 Java 中的 class 时,您可以使该 class 的 对象实例 ] 可以序列化(不是 class 本身)。目标 JVM 需要访问 class 才能理解您发送给它的序列化实例。所以,实际上你总是需要为它提供 JAR。

Beam 有代码自动查找您的 class 路径中的所有 JAR 并将它们上传到 Dataflow 或您正在使用的任何 运行ner,所以如果 JAR 在您的 classpath,那么你就不必担心它(如果你使用 Maven/Gradle 并将其指定为依赖项,那么你很可能没问题)。


  1. 现在,如果 class 不可序列化,我如何在 Beam 中使用它?

在Beam中,更重要的部分是弄清楚wherewhen管道代码的不同部分将执行.有些事情在 管道构建时间 执行,有些事情在 管道 运行 宁时间 .

执行

施工时运行的东西

  • 所有 classes(DoFns、PTransform 等)的构造函数
  • 您的 PTransforms 的 expand 方法

在执行时运行的东西

  • 对于您的 DoFns:ProcessElementStartBundleFinishBundleSetupTearDown 方法。

如果您的 class 没有实现可序列化,但您想在 执行时访问它 ,那么您需要 在执行时创建它时间。所以,假设你有一个 DoFn:

class MyDoFnImplementation extends DoFn<String, String> {

  // All members of the object need to be serializable. String is easily serializable.
  String config;
  // Your MicroserviceApi is *not* serializable, so you can mark it as transient.
  // The transient keyword ensures that Java will ignore the member when serializing.
  transient MicroserviceApi client;

  public MyDoFnImplementation(String configuration) {
    // This code runs at *construction time*.
    // Anything you create here needs to be serialized and sent to the runner.
    this.config = configuration;
  }

  @ProcessElement
  public void process(ProcessContext c) {
    // This code runs at execution time. You can create your object here.
    // Add a null check to ensure it's only created once.
    // You can also create it at @Setup or @StartBundle.
    if (client == null) client = new MicroserviceApi(this.config);
  }
}

通过确保在执行时创建对象,您可以避免使它们可序列化的需要 - 但您的配置需要可序列化。