繁体   English   中英

谷歌云数据流可以在本地运行,但不能在云上运行

[英]google cloud dataflow can run locally but can't run on the cloud

我无法使用“ DirectPipelineRunner”在本地运行管道,但是当我使用“ BlockingDataflowPipelineRunner”在云上运行时,它始终显示“无法拆分源”。 我不知道我的管道问题在哪里。

我定义了自定义源,以读取存储桶中的许多tgz文件。 以下是我的代码。

class My_Compressed_Source(filebasedsource.FileBasedSource):
    def read_records(self, file_name, range_tracker):
        import tarfile
        import re    
        start_offset = range_tracker.start_position()
        with self.open_file(file_name) as f:
            tar = tarfile.open(fileobj = f)            
            for member in tar.getmembers():
            f = tar.extractfile(member)
            content = f.read()                    
            # do some regular expression process to content 

这是我的管道

pcoll = p | 'Read' >> beam.Read(My_Compressed_Source(args.input, splittable = False))
pcoll | beam.ParDo('parse tar member', Parse_Members())
p.run()

另外,我的存储桶的输入路径是“ --input gs://mybucket/source/*.tgz”,我的工作ID是“ 2016-10-14_09_21_43-4409773810679481086”。 我想知道是否应该将“ splittable”设置为True。 还是如果有什么问题。

由于必须将所有数据加载到内存中,因此不建议使用如上所述的StringIO读取tar文件。

自tarfile.open()使用方法seek()和tell()以来,似乎您的原始实现不起作用,而filebasedsource.open_file()返回的fileio._CompressedFile对象不支持这些方法。

我为此提交了https://issues.apache.org/jira/browse/BEAM-778

感谢您上面的所有评论。
我尝试了几种解决问题的方法。 而且我有一点进步。 我认为有必要再次描述我的问题。

我添加了compression_type参数并将其设置为fileio.CompressionTypes.GZIP 如下所示。

pcoll = p | "Read" >> beam.io.Read(My_Compressed_Source(args.input, split = False, compression_type = fileio.CompressionTypes.GZIP))
pcoll | beam.ParDo('parse tar member', Parse_Members())
p.run()

我尝试通过“ DirectPipelineRunner”在本地执行它,并且tarfile.open()显示错误。 因此,我将read_records函数修改为以下版本。

class My_Compressed_Source(filebasedsource.FileBasedSource):
    def read_records(self, file_name, range_tracker):
    import tarfile
    import re
    import StringIO
    start_offset = range_tracker.start_position()
    f = self.open_file(file_name)
    start = range_tracker.start_position
    text_str = str(f.read(f._read_size))
    tar = tarfile.open(fileobj=StringIO.StringIO(text_str), bufsize=f._read_size)
    for mem in tar.getmembers():
        print mem.name

我指定f.read()的字节数来获取tgz文件的全部内容。 现在文件只是tar。
然后,我使用StringIO模块创建一个临时的file_obj放入tarfile.open。 最后,我使用循环访问文件的每个名称。 我确实提取了一些文件名,但是只访问了几个文件。

在尝试了不同的数据源之后,我认为关键是无论哪个源,f._read_size的长度始终最大为16384 = 16k。 我想知道是否有一些地方可以设置最大缓冲区大小,以便让我访问整个内容,还是应该尝试另一种方法?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM