HDFS 如何使用新的文件系统接口将文件从本地复制到远程?

xytpbqjk  于 2022-12-09  发布在  HDFS
关注(0)|答案(2)|浏览(171)

有人能给予我一个提示,告诉我如何使用PyArrow's new filesystem interface(即upload、copyFromLocal)将文件从本地文件系统复制到HDFS文件系统吗?
我反复阅读了文档,并尝试了一些方法(使用带有FS URI的copy_file()),但似乎都不起作用。legacy HDFS API的用法很简单,但它已被弃用,尽管新的API似乎不完整。当然,在文件描述符之间移动数据块是一种解决方案,但为什么存在copy_file()呢?

czq61nw1

czq61nw11#

新(或旧)文件系统API中没有用于在文件系统之间传输文件的函数。
当然,在文件描述符之间移动数据块是一种解决方案
我不知道这是否是你所想的,但这里有一个简单的实用程序(和演示),如何从python做到这一点:

import filecmp
import pyarrow.fs as pafs

BATCH_SIZE = 1024 * 1024

def transfer_file(in_fs, in_path, out_fs, out_path):
    with in_fs.open_input_stream(in_path) as in_file:
        with out_fs.open_output_stream(out_path) as out_file:
            while True:
                buf = in_file.read(BATCH_SIZE)
                if buf:
                    out_file.write(buf)
                else:
                    break

local_fs = pafs.LocalFileSystem()
s3fs = pafs.S3FileSystem()
in_path = '/tmp/in.data'
out_path = 'mybucket/test.data'
back_out_path = '/tmp/in_copy.data'

transfer_file(local_fs, in_path, s3fs, out_path)
transfer_file(s3fs, out_path, local_fs, back_out_path)

files_match = filecmp.cmp(in_path, back_out_path)
print(f'Files Match: {files_match}')

我希望transfer_file能获得很好的性能。可能有一些情况(例如从S3阅读)可以从使用read_at的并行读取中受益,这将需要更多的复杂性,但也应该是可行的。
但是为什么copy_file()存在呢?
copy_file将文件从文件系统上的一个名称复制到同一文件系统 * 上的另一个名称 *。它不能用于在不同的文件系统之间复制文件。

cyej8jka

cyej8jka2#

@Pace的回答(太长,无法评论):我复制了gzip文件(*.gz),pyarrow在每次read()调用时(默认情况下)解压缩这些文件,然后在每次write()调用时再次压缩。我用下面Pace版本的代码中的print语句验证了这一点。
因此,要获得 * 显著 * 更快的传输/复制速度,请关闭压缩:

def transfer_file(in_fs, in_path, out_fs, out_path):
    with in_fs.open_input_stream(in_path, compression=None) as in_file:
        with out_fs.open_output_stream(out_path, compression=None) as out_file:
            while True:
                buf = in_file.read(BATCH_SIZE)
                if buf:
                    print(f'buf size: len(buf)')
                    out_file.write(buf)
                else:
                    break

相关问题