首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 實現 FTP/HTTP 文件流式直傳 HDFS:零落地中轉的高效數據遷移方案

     編輯:Java 相關知識

核心思路

傳統方案:FTP/HTTP 下載到本地磁盤 → 再上傳 HDFS,存在雙倍 I/O、磁盤佔用、延遲高等問題。

本方案:利用 InputStream → OutputStream 管道流式傳輸,數據僅在 JVM 堆內存中流轉,不落地本地磁盤,實現「邊下載、邊上傳」。

架構設計

┌─────────────┐     InputStream      ┌─────────────┐     OutputStream      ┌─────┐
│ FTP/HTTP    │ ───────────────────▶ │ FileTrans   │ ───────────────────▶ │ HDFS│
│ Server      │  (網絡流)             │ (橋接轉發)   │  (HDFS FSDataOutputStream) │     │
└─────────────┘                      └─────────────┘                      └─────┘
       ▲                                      │
       │                                      ▼
       │                              ┌─────────────┐
       └───────────────────────────── │ 可選:本地  │
                                      │ 緩存前 N 行 │
                                      └─────────────┘

核心類:FileTrans

統一封裝 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:基於 Apache Commons Net FTPClient,提供 getStream(String remoteFile) 返回 InputStream。
  • HttpUtil:基於 HttpURLConnection 或 HttpClient,同樣暴露 getStream(String url)。
  • HDFSUtil:封裝 Hadoop FileSystem API,upLoad(InputStream in, String hdfsPath) 內部用 IOUtils.copyBytes(in, fs.create(path), bufferSize)。

編譯運行關鍵點

  1. 依賴 hadoop-common、hadoop-hdfs、commons-net、httpclient 等 JAR 包。
  2. Linux 下編譯運行需顯式指定 -classpath 或 -cp 包含所有依賴 JAR 路徑。
  3. 建議將四個類放同一包目錄,或按 Maven/Gradle 標準項目結構管理依賴。

優勢與局限

優勢局限/注意點
零磁盤落地,節省 I/O 與存儲網絡抖動導致流中斷需重試機制(當前代碼無斷點續傳)
內存常駐可控(流式處理),不佔堆大文件需調大 HDFS 客戶端緩衝區(dfs.client.buffer.size)
統一入口,協議無關FTP 被動模式/防火牆、HTTPS 憑證驗證需額外配置
可插攔截流做預覽/校驗無進度條/熔斷/限流等企業級特性

生產化建議

  1. 引入 Resilience4j 或 Hystrix 做重試、熔斷、限流。
  2. 集成 Micrometer/Prometheus 監控傳輸速率、錯誤率、延遲。
  3. 對大文件啟用 DistCp 或 HDFS 原生 webhdfs/httpfs REST API 並行傳輸。
  4. 補全單元/集成測試,覆蓋異常斷網、權限不足、磁盤滿等場景。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved