使用Cloud Dataflow运行外部库

时间:2017-10-25 00:01:14

标签: java shared-libraries google-cloud-dataflow apache-beam

我尝试使用类似于此处所述的云数据流运行一些外部共享库函数:Running external libraries with Cloud Dataflow for grid-computing workloads

根据方法,我有几个的问题。

文章mentioned earlier中有以下段落:

  

如果要调用外部库,则需要手动为该库执行此步骤。方法是:

     
      
  • 将代码(以及版本信息)存储在云端存储中,如果在流中运行10,000个核心,这将消除对吞吐量的任何担忧。
  •   
  • @beginBundle [sic] 方法中,创建一个synchronized块以检查该文件是否在本地资源上可用。如果没有,请使用云存储客户端库将文件拉过来。
  •   

但是,使用我的Java包,我只需将库.so文件放入src/main/resource/linux-x86-64目录,并按以下方式调用库函数(为了简洁起见,将其剥离为最小值)< / EM>:

import com.sun.jna.Library;
import com.sun.jna.Native;
import org.apache.beam.sdk.transforms.DoFn;
import org.apache.beam.sdk.values.KV;

public class HostLookupPipeline {

  public interface LookupLibrary extends Library {
    String Lookup(String domain);
  }

  static class LookupFn extends DoFn<String, KV<String, String>> {
    private static LookupLibrary lookup;

    @StartBundle
    public void startBundle() {
      // src/main/resource/linux-x86-64/liblookup.so
      lookup = Native.loadLibrary("lookup", LookupLibrary.class);
    }

    @ProcessElement
    public void processElement(ProcessContext c) {
      String domain = c.element();
      String results = lookup.Lookup(domain);
      if (results != null) {
        c.output(KV.of(domain, results));
      }
    }
  }
}

这种方法是否被认为是可接受的,或者从GAR下载.so文件与从GCS下载相比效果不佳?如果没有,我应该在下载后将文件放在哪里以使其可供Cloud Dataflow工作人员访问?

我注意到调用外部库函数的转换工作速度相当慢 - 大约90个元素 - 利用15个Cloud Dataflow工作者(自动扩展,默认最大工作者)。如果我的粗略计算是正确的,它应该快两倍。我想这是因为我为每个元素调用外部库函数。

使用Java运行时是否有任何改善外部库性能的最佳实践?

1 个答案:

答案 0 :(得分:2)

该博客文章中的指导略有不正确 - 放置初始化代码的更好的地方是@Setup方法,而不是@StartBundle

调用

@Setup来初始化每个将要执行它的worker的每个线程中的DoFn实例。它是重型设置代码的预定位置。它的对应部分是@Teardown

@StartBundle@FinishBundle的粒度更精细:每个 bundle ,这是一个非常低级别的概念,我相信他们编写批次的唯一合法用途外部服务的元素:通常在@StartBundle中,您将初始化下一批,并在@FinishBundle中刷新它。

通常,要调试性能,请尝试向DoFn方法添加日志记录,并查看调用所花费的毫秒数以及与预期的比较方式。如果您遇到问题,请在问题中包含Dataflow作业ID,工程师将对其进行查看。