首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将许多文件从hdfs移到hdfs

将许多文件从hdfs移到hdfs
EN

Stack Overflow用户
提问于 2014-01-07 17:50:40
回答 2查看 5.4K关注 0票数 2

我需要将许多文件从一个hdfs dir移动到同一个集群中的另一个hdfs dir (而不是复制)。

我可以使用distcp,但是由于它正在复制文件(复制它),所以它看起来有点过分了,我只想move it。两个问题:

A)外面有什么东西吗:

我希望使用mapreduce来实现这一点,因为需要移动数百万个文件(或将其重命名为新路径)。我也想把它和oozie结合起来。我可以自己写一份mapreduce工作,但我想知道是否有什么东西可以完成这项工作。

B)我真的需要这样做吗?

不幸的是,我对hdfs重命名的性能特性还不太了解;您认为我可以用单线程方法来重命名文件吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-01-07 20:53:26

移动本身是有效的,因为它只是在元数据(即inode)级别,而不是在数据级别。换句话说,发出一个移动(在Hadoop的代码中称为rename,而不是move)比复制数据要快得多。您可以查看源代码,以防您对细节感兴趣。

因此,不应该执行distcp,因为这将是数据的实际副本。如果您想并行化它(因为您谈论的是数百万个文件),那么使用hadoop流应该不会太难:

  1. 编写多个文件,其中包含要重命名的文件列表(src +目标值),每行一个。
  2. 编写一个shell脚本,为它在stdin上读取的每一行发出重命名(hdfs命令mv)。
  3. 使用流:包含文件的文件是输入,shell脚本是映射器。

外面有什么东西吗?

我不知道,但可能有。

我真的需要这样做吗?

如果您有数百万个文件,那么联系namenode的延迟就会增加,即使HDFS重命名本身是有效的。但是,如果这是一次性的事情,我宁愿发布一个单线程的方法并等待,因为编写和调试(甚至简单的代码)也需要一段时间。如果您计划经常这样做(为什么?),那么我将考虑实现我前面描述的方法。

票数 1
EN

Stack Overflow用户

发布于 2020-03-31 23:33:28

如果您想要在HDFS中将文件的子集从文件夹复制到另一个文件夹,我想出了这个问题:

代码语言:javascript
复制
import pandas as pd
import os
from multiprocessing import Process
from subprocess import Popen, PIPE
hdfs_path_1 = '/path/to/the/origin/'
hdfs_path_2 = '/path/to/the/destination/'

df = pd.read_csv("list_of_files.csv")  
to_do_list = list(df.tar) # or any other lists that you have
print(f'To go: {len(to_do_list)}')

def copyy(f):
    process = Popen(f'hdfs dfs -mv {hdfs_path_1}{f} {hdfs_path_2}', shell=True, stdout=PIPE, stderr=PIPE)
    std_out, std_err = process.communicate()
    if std_out!= b'':
        print(std_out)

ps = []
for f in to_do_list:
    p = Process(target=copyy, args=(f,))
    p.start()
    ps.append(p)
for p in ps:
    p.join()
print('done')

此外,如果您想拥有目录中所有文件的列表,请使用以下命令:

代码语言:javascript
复制
from subprocess import Popen, PIPE
hdfs_path = '/path/to/the/designated/folder'
process = Popen(f'hdfs dfs -ls -h {hdfs_path}', shell=True, stdout=PIPE, stderr=PIPE)
std_out, std_err = process.communicate()
list_of_file_names = [fn.split(' ')[-1].split('/')[-1] for fn in std_out.decode().readlines()[1:]][:-1]
list_of_file_names_with_full_address = [fn.split(' ')[-1] for fn in std_out.decode().readlines()[1:]][:-1]
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20978428

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档