傳統方案:FTP/HTTP 下載到本地磁盤 → 再上傳 HDFS,存在雙倍 I/O、磁盤佔用、延遲高等問題。
本方案:利用 InputStream → OutputStream 管道流式傳輸,數據僅在 JVM 堆內存中流轉,不落地本地磁盤,實現「邊下載、邊上傳」。
┌─────────────┐ InputStream ┌─────────────┐ OutputStream ┌─────┐
│ FTP/HTTP │ ───────────────────▶ │ FileTrans │ ───────────────────▶ │ HDFS│
│ Server │ (網絡流) │ (橋接轉發) │ (HDFS FSDataOutputStream) │ │
└─────────────┘ └─────────────┘ └─────┘
▲ │
│ ▼
│ ┌─────────────┐
└───────────────────────────── │ 可選:本地 │
│ 緩存前 N 行 │
└─────────────┘
統一封裝 FTP/HTTP 協議適配與 HDFS 上傳邏輯,構造器參數:
head:協議類型(ftp/http/https)hostname:遠端服務器地址filepath:遠端文件路徑hdfsnode:HDFS NameNode 地址hdfsFilePath:HDFS 目標路徑public class FileTrans {
private InputStream inStream;
private HDFSUtil hdfsutil;
private FtpClient ftp;
private HttpUtil http;
public FileTrans(String head, String hostname, String filepath,
String hdfsnode, String hdfsFilepath) {
// 1. 根據協議初始化客戶端
if ("ftp".equals(head)) {
this.ftp = new FtpClient(hostname);
} else if ("http".equals(head) || "https".equals(head)) {
String url = head + "://" + hostname + "/" + filepath;
this.http = new HttpUtil(url);
}
// 2. 初始化 HDFS 客戶端
this.hdfsutil = new HDFSUtil(hdfsnode);
this.hdfsutil.setHdfsPath(hdfsFilepath);
// ... hadoop-site.xml 等配置
}
public void transfer() throws IOException {
// 3. 獲取遠端輸入流
if (ftp != null) {
inStream = ftp.getStream(filepath);
} else {
inStream = http.getStream(url);
}
// 4. 直接管道流式上傳 HDFS
hdfsutil.upLoad(inStream, hdfsutil.getFilePath());
// 5. 可選:同步保存前 N 行到本地分析
if (sampleLines > 0) {
if (ftp != null) ftp.writeStream(inStream, localPath, sampleLines);
else http.downLoad(url, localPath, sampleLines);
}
}
}
FTPClient,提供 getStream(String remoteFile) 返回 InputStream。HttpURLConnection 或 HttpClient,同樣暴露 getStream(String url)。FileSystem API,upLoad(InputStream in, String hdfsPath) 內部用 IOUtils.copyBytes(in, fs.create(path), bufferSize)。hadoop-common、hadoop-hdfs、commons-net、httpclient 等 JAR 包。-classpath 或 -cp 包含所有依賴 JAR 路徑。| 優勢 | 局限/注意點 |
|---|---|
| 零磁盤落地,節省 I/O 與存儲 | 網絡抖動導致流中斷需重試機制(當前代碼無斷點續傳) |
| 內存常駐可控(流式處理),不佔堆 | 大文件需調大 HDFS 客戶端緩衝區(dfs.client.buffer.size) |
| 統一入口,協議無關 | FTP 被動模式/防火牆、HTTPS 憑證驗證需額外配置 |
| 可插攔截流做預覽/校驗 | 無進度條/熔斷/限流等企業級特性 |
DistCp 或 HDFS 原生 webhdfs/httpfs REST API 並行傳輸。