如何不落地本地文件系统将HDFS目录的part*文件直接传输到SFTP服务器
最优实现方案:管道直传(零本地磁盘落地)
利用Linux管道的内存传输特性,将HDFS文件读取的标准输出直接作为curl上传的数据源,全程无本地磁盘写入,完全适配你当前的CDH 5.16.2版本环境,无需额外安装或配置集群组件。
1. 合并所有part文件为单个文件上传
如果你需要将所有part*文件合并成一个文件上传到SFTP,直接执行以下命令:
hdfs dfs -cat "<HDFS_DIR>/part*" | curl -u "<sftp_username>:" \ --key "<private_key_file_path>" \ --pubkey "<public_key_file_path>" \ --upload-file - "sftp://<SFTP_HOST>/<Upload_dir>/<合并后的文件名>"
说明:curl的
--upload-file参数后接-代表从标准输入读取上传内容,管道会将hdfs命令的输出直接传递给curl,全程在内存中完成数据流转。
2. 逐个上传独立的part文件
如果需要保留每个part文件的独立性,不做合并,用循环遍历HDFS文件列表逐个传输即可:
# 遍历HDFS目录下所有part文件,逐个直传到SFTP hdfs dfs -ls "<HDFS_DIR>/part*" | awk '{print $8}' | while read hdfs_file_path; do part_filename=$(basename "${hdfs_file_path}") hdfs dfs -cat "${hdfs_file_path}" | curl -u "<sftp_username>:" \ --key "<private_key_file_path>" \ --pubkey "<public_key_file_path>" \ --retry 3 --retry-delay 5 \ --upload-file - "sftp://<SFTP_HOST>/<Upload_dir>/${part_filename}" done
注意事项
- 如果HDFS上的part文件是压缩格式(如Snappy、Gzip),需要解压后上传可以把
hdfs dfs -cat替换为hdfs dfs -text,不需要解压则保留-cat即可。 - 需要查看传输进度可以在管道中插入
pv命令,示例:hdfs dfs -cat <HDFS路径> | pv | curl ... - 该方案的传输效率仅受HDFS读取带宽和SFTP上行带宽限制,比本地落地的方案减少了两次磁盘IO开销,传输速度可提升1倍以上。
内容的提问来源于stack exchange,提问作者Rajuk
相关产品推荐
相关产品推荐

