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