2

我有许多图像需要通过 java 程序运行以创建更多图像文件——一个令人尴尬的并行案例。每个输入文件大约 500 mb,在处理过程中需要大约 4 GB 的内存,并且需要 30 秒到 2 分钟才能运行。java 程序是多线程的,但更多的收益来自于输入文件的并行化而不是使用更多的线程。我需要每天启动几次进程(我不想手动打开/关闭集群,也不想 24/7 支付)。

我对那里的各种云选项有点迷失:

  • Amazon lambda系统资源不足(内存不足)。
  • Google Cloud DataFlow,看来我必须编写自己的管道源才能使用他们的 Cloud Storage 存储桶。很好,但是如果这不是一个合适的解决方案(可能是这样,我还不能确定),我不想浪费时间这样做。
  • 亚马逊数据管道看起来相当于谷歌云数据流。(为完整起见,在编辑中添加。
  • Google Cloud Dataproc,这不是 map/reduce hadoop-y 的情况,但可能仍然有效。不过,我宁愿不管理自己的集群。
  • 谷歌计算引擎或具有自动缩放功能的 AWS,我只是为机器上的每个核心启动进程。我有更多的管理,但没有 API 可以学习。
  • Microsoft Data Lake尚未发布,看起来像 hadoop-y。
  • Microsoft Batch似乎很合适(但我之所以这么问,是因为我对其他选项仍然感到好奇)。

谁能建议对此有什么合适的解决方案?

4

1 回答 1

5

您应该可以很容易地使用 Dataflow 做到这一点。管道可能类似于(假设您的文件位于Google Cloud Storage,GCS 上):

class ImageProcessor {
    public static void process(GcsPath path) {
        // Open the image, do the processing you want, write
        // the output to where you want.
        // You can use GcsUtil.open() and GcsUtil.create() for
        // reading and writing paths on GCS.
    }
}

// This will work fine until a few tens of thousands of files.
// If you have more, let me know.
List<GcsPath> filesToProcess = GcsUtil.expand(GcsPath.fromUri("..."));
p.apply(Create.of(filesToProcess))
 .apply(MapElements.via(ImageProcessor::process)
                   .withOutputType(new TypeDescriptor<Void>() {}));
p.run();

这是 Dataflow 被用作令人尴尬的并行编排框架而不是数据处理框架的常见案例之一,但它应该可以工作。

您将需要 Dataflow SDK 1.2.0 才能使用 MapElements 转换(对 Java 8 lambda 的支持是 1.2.0 中的新增功能)。

于 2015-10-09T21:26:36.260 回答