我正在使用mget参数使用lftp从远程位置复制文件。该任务大约需要2分钟,才能将50个xml文件从sftp机器复制到我的本地Unix机器。我希望能够复制2万个文件。 XML文件约为15kb。数据框df_files包含我要复制的所有XML文件的列表。
我已经尝试使用下面的代码处理20000个文件,似乎需要几个小时才能用这些文件创建数据框。
for row in df_files.tolist():
print row
cmd_p1 = """lftp sftp://username:password!@remotelocation-e "lcd /var/projects/u_admin/folder/;mget /var/projects/storage/folder/"""+row
cmd_p2 = """;bye " """
cmd_get_xml = cmd_p1+cmd_p2
s=subprocess.call(cmd_get_xml,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
j=0
for row in df_file.itertuples(index=True, name='Pandas'):
print getattr(row,'filename')
if j==0:
acq = sqlContext.read.format("com.databricks.spark.xml").option("rowTag","Message").load("file:///var/projects/u_admin/folder/"+df_file['filename'].iloc[j])
schema = acq.schema
else :
acq2 = sqlContext.read.format("com.databricks.spark.xml").option("rowTag","Message").load("file:///var/projects/u_admin/folder/"+df_file['filename'].iloc[j], schema = schema)
acq = acq.union(acq2)
我希望能够在最短的时间内复制这些文件。
答案 0 :(得分:0)
首先,使用SCP module for Paramiko将所有.xml
文件放入一个目录。假设您的.xml
文件具有相同的架构,因为您能够在同一目录上执行union
,因此,一旦将所有这些xml文件放在一个目录中,就可以直接读取整个目录,而无需读取文件。
此解决方案将节省您在for循环中花费的大量时间。
import paramiko
from scp import SCPClient
def createSSHClient(server, port, user, password):
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(server, port, user, password)
return client
ssh = createSSHClient(server, port, user, password)
scp = SCPClient(ssh.get_transport())
然后调用scp.get()
或scp.put()
进行SCP操作。
acq_all = sqlContext.read.format("com.databricks.spark.xml").option("rowTag","Message").load("file:///var/projects/u_admin/folder/", schema = schema)
我知道您的用例可能有所不同,因为您也有一个if-else
块,但是架构是相同的,因此一旦读取文件就可以完成。
您可以读取一个文件以获得正确的架构,也可以在读取之前自行定义。