一篇文章掌握 FTP 和本地文件系統的橋梁 -CurlFtpFS
本文轉載自微信公眾號「明哥的IT隨筆」,作者 IT明哥。轉載本文請聯系明哥的IT隨筆公眾號。
大家好,我是明哥!
本片博文是 “基于 FTP 狀態文件檢測結果觸發 JENKINS 數據同步作業” 系列文章的最后一篇,我們來看下 FTP 和本地文件系統的橋梁 - CurlFtpFS.
1 背景回顧
某客戶現場,每天都會批量生成大量 CSV 文件存放到 FTP 系統,這些 CSV 文件需要導入到大數據平臺 HIVE 數倉中做后續離線分析,且 HIVE 數倉中的離線分析作業目前是使用 JENKINS 來調度的。
由于這些 CSV 文件是每天都會生成,且文件數比較多數據量也比較大,初步計劃使用 DATAX 來導入 FTP 上的 CSV 文件。
但在調度系統 JENKINS 中,如何檢測 ftp 上的 csv 文件是否 ready,并及時觸發 DATAX 導入作業,成為了一個問題。
為探索和驗證 JENKINS 中 FTP 文件的檢測和觸發機制,筆者基于 vsftpd 搭建了 FTP 服務器,并通過 CurlFtpFS 掛載了遠程 FTP 目錄到本地文件系統。
以下是正文。
2 curlftpfs 與 FUSE 簡介
CurlFtpFS 是一個基于 libcurl 提供對遠程 FTP 節點上文件系統的訪問功能的用戶態文件系統,可以讓用戶像訪問本地文件系統一樣去訪問遠程 ftp 節點的文件系統。
- CurlFtpFS is a filesystem for accessing FTP hosts based on FUSE and libcurl.
- It features SSL support, connecting through tunneling HTTP proxies, and automatically reconnecting if the server times out.
所謂 FUSE (Filesystem in Userspace),即用戶態文件系統,是指完全在用戶態而不是內核態實現的文件系統,其底層由 Linux 通過內核模塊進行支持:
- FUSE 允許在不重新編譯操作系統內核的前提下,在用戶態提供一個自定義的文件系統實現;
- 最終用戶態的應用程序,可以通過普通的 POSIX API, 讀取 FUSE 文件系統中的文件;
- 允許非超級用戶在用戶空間開發文件系統,普通用戶也可以掛載FUSE;
- 大致來說,FUSE 包含一個內核模塊和一個用戶空間 FUSE 服務進程,將應用對 VFS 的調用傳遞給這個用戶空間 FUSE 服務程序來處理;
- 可以使用命令 fusermount 對 FUSE 文件系統進行掛載和卸載操作;(使用命令 man fusermount 查看說明)
- FUSE 的架構原理和工作機制如下圖:
fuse-architecture
fuse
fuse主要由三部分組成:FUSE 內核模塊、用戶空間庫 libfuse 以及掛載工具fusermount:
- fuse 內核模塊:實現了和 VFS 的對接,實現了一個能被用戶空間進程打開的設備,當VFS發來文件操作請求之后,將請求轉化為特定格式,并通過設備傳遞給用戶空間進程,用戶空間進程在處理完請求后,將結果返回給fuse內核模塊,內核模塊再將其還原為Linux kernel需要的格式,并返回給VFS;
- fuse 庫libfuse:負責和內核空間通信,接收來自/dev/fuse 的請求,并將其轉化為一系列的函數調用,將結果寫回到/dev/fuse;提供的函數可以對fuse文件系統進行掛載卸載、從linux內核讀取請求以及發送響應到內核。libfuse提供了兩個APIs:一個“high-level”同步API 和一個“low-level” 異步API 。這兩種API 都從內核接收請求傳遞到主程序(fuse_main函數),主程序使用相應的回調函數進行處理。當使用high-level API時,回調函數使用文件名(file names)和路徑(paths)工作,而不是索引節點inodes,回調函數返回時也就是一個請求處理的完成。使用low-level API 時,回調函數必須使用索引節點inode工作,響應發送必須顯示的使用一套單獨的API函數;
掛載工具:實現對用戶態文件系統的掛載;
現在很多文件系統,出于易用性等各種考量因素,都提供了 FUSE 的使用方式,比如云原生分布式文件系統 JuiceFS,和云原生數據編排框架/基于內存的分布式文件系統 Alluxio,都不約而同提供了 FUSE 服務:
- 通過 FUSE,JuiceFS 文件系統能夠以 POSIX 兼容的方式掛載到服務器,將海量云端存儲直接當做本地存儲來使用;
- Alluxio FUSE 服務通過提供 Unix/Linux 下的標準 POSIX 文件系統接口,讓應用程序(比如Tensorflow,PyTorch等)在不修改代碼的前提下,以訪問本地文件系統的方式訪問 Alluxio分布式文件系統中的數據;
- Alluxio 和 JuiceFS, 都是數字化轉型大背景下,筆者比較看好也比較關注的兩個云原生分布式文件系統;
alluxio-fuse
juicefs-fuse
3 curlftpfs 的安裝
- 由于 Linux 操作系統的 epel 源中自帶了curlftpfs,所以安裝很方便:yum install curlftpfs;
- curlftpfs 不是系統常駐服務,不用通過 systemctl 進行啟停管理;
4 臨時掛載遠程 FTP 目錄到本地文件系統
可以使用命令 curlftpfs,臨時掛載遠程 ftp 目錄到本地文件系統:
- sudo curlftpfs ftp://3.22.42.20:21 /tmp/ftp1 -o user=awsftpuser:awsftpuser,rw,allow_other
- sudo curlftpfs ftp://awsftpuser:awsftpuser@3.22.42.20:21 /tmp/ftp2 -o rw,allow_other
- sudo curlftpfs 3.22.42.20:21 /tmp/ftp11 -o user=awsftpuser:awsftpuser,allow_other,no_verify_peer,no_verify_hostname
- sudo curlftpfs awsftpuser:awsftpuser@3.22.42.20:21 /tmp/ftp21 -o allow_other
- curlftpfs 命令有大量參數,需要注意比較重要的參數 allow_other,allow_root, user=user:password 等
- 更多關于命令 curlftpfs 的詳情,請 man curlftpfs;
5 永久掛載遠程 FTP 目錄到本地文件系統
使用命令 curlftpfs 掛載的 FTP 目錄,在服務器重啟后就失效了,如果要實現永久掛載,需要更改文件 /etc/fstab,添加以下條目:
- curlftpfs#awsftpuser:awsftpuser@3.22.42.20:21 /tmp/ftp3 fuse auto,user,uid=1000,allow_other,_netdev 0 0
- curlftpfs#3.22.42.20:21 /tmp/ftp31 fuse user=awsftpuser:awsftpuser,auto,user,uid=1000,allow_other,_netdev 0 0
- curlftpfs#ftp://3.22.42.20:21 /tmp/ftp32 fuse user=awsftpuser:awsftpuser,auto,user,uid=1000,allow_other,_netdev 0 0
- curlftpfs#ftp://3.22.42.20:21 /tmp/ftp33 fuse user=awsftpuser:awsftpuser,auto,user,uid=1000,allow_other,_netdev 0 0
- 以上各個參數的含義,跟命令 curlftpfs 的參數一致;圖片
6 最終方案思路概述
- “基于 FTP 狀態文件檢測結果觸發 JENKINS 數據同步作業”的最終方案,思路概括如下:
- 首先通過 CurlFtpFS 將遠程 FTP 特定目錄映射到本地文件系統;
- 然后使用 jenkins 的插件 FSTrigger 來監控映射到本地文件系統的狀態文件,當監控到狀態文件 READY 時,觸發數據同步作業;
- 也可以在 jenkins 中編寫 groovy 腳本代碼來監控映射到本地文件系統的狀態文件,當監控到狀態文件 READY 時,觸發數據同步作業;
- 數據同步作業,可以直接使用 hive load 命令,來加載映射到本地文件系統的 csv 數據文件到 HIVE 中;(前提:CurlFtpFS 節點需要安裝 HIVE 客戶端);
- 當 curlftpfs 掛載到本地的遠程 ftp 文件數量眾多且數據量大時,如果 HIVE LOAD 直接同步數據的方式不穩定或效率不高,可以結合使用 datax 直接導入遠程 ftp 數據文件到 HIVE 中;