FastDFS 是用 c 語言編寫的一款開源的分佈式文件系統。FastDFS 爲互聯網量身定製, 充分考慮了冗餘備份、負載均衡、線性擴容等機制,並注重高可用、高性能等指標,使用 FastDFS 很容易搭建一套高性能的文件服務器集羣提供文件上傳、下載等服務。html
FastDFS 架構包括 Tracker server 和 Storage server。客戶端請求 Tracker server 進行文 件上傳、下載,經過 Tracker server 調度最終由 Storage server 完成文件上傳和下載。python
Tracker server 做用是負載均衡和調度,經過 Tracker server 在文件上傳時能夠根據一些 策略找到 Storage server 提供文件上傳服務。能夠將 tracker 稱爲追蹤服務器或調度服務 器。nginx
Storage server 做用是文件存儲,客戶端上傳的文件最終存儲在 Storage 服務器上, Storageserver 沒有實現本身的文件系統而是利用操做系統 的文件系統來管理文件。能夠將 storage 稱爲存儲服務器。git
服務端兩個角色:github
Tracker:管理集羣,tracker 也能夠實現集羣。每一個 tracker 節點地位平等。收集 Storage 集羣的狀態。django
Storage:實際保存文件 Storage 分爲多個組,每一個組之間保存的文件是不一樣的。每 個組內部能夠有多個成員,組成員內部保存的內容是同樣的,組成員的地位是一致的,沒有 主從的概念。ubuntu
首先客戶端請求Tracker服務獲取到存儲服務器的ip地址和端口,而後客戶端根據返回的IP地址和端口號請求上傳文件,存儲服務器接收到請求後生產文件,而且將文件內容寫入磁盤並返回給客戶端file_id、路徑信息、文件名等信息,客戶端保存相關信息上傳完畢。vim
客戶端上傳文件後存儲服務器將文件 ID 返回給客戶端,此文件 ID 用於之後訪問該文 件的索引信息。文件索引信息包括:組名,虛擬磁盤路徑,數據兩級目錄,文件名。服務器
組名:文件上傳後所在的 storage 組名稱,在文件上傳成功後有 storage 服務器返回, 須要客戶端自行保存。架構
虛擬磁盤路徑:storage 配置的虛擬路徑,與磁盤選項 store_path*對應。若是配置了 store_path0 則是 M00,若是配置了 store_path1 則是 M01,以此類推。
數據兩級目錄:storage 服務器在每一個虛擬磁盤路徑下建立的兩級目錄,用於存儲數據 文件。
文件名:與文件上傳時不一樣。是由存儲服務器根據特定信息生成,文件名包含:源存儲 服務器 IP 地址、文件建立時間戳、文件大小、隨機數和文件拓展名等信息。
內部機制以下:
當集羣中不止一個tracker server時,因爲tracker之間是徹底對等的關係,客戶端在upload文件時能夠任意選擇一個trakcer。
選擇存儲的group
當tracker接收到upload file的請求時,會爲該文件分配一個能夠存儲該文件的group,支持以下選擇group的規則:
當選定group後,tracker會在group內選擇一個storage server給客戶端,支持以下選擇storage的規則:
當分配好storage server後,客戶端將向storage發送寫文件請求,storage將會爲文件分配一個數據存儲目錄,支持以下規則:
選定存儲目錄以後,storage會爲文件生一個Fileid,由storage server ip、文件建立時間、文件大小、文件crc32和一個隨機數拼接而成,而後將這個二進制串進行base64編碼,轉換爲可打印的字符串。
選擇兩級目錄
當選定存儲目錄以後,storage會爲文件分配一個fileid,每一個存儲目錄下有兩級256*256的子目錄,storage會按文件fileid進行兩次hash(猜想),路由到其中一個子目錄,而後將文件以fileid爲文件名存儲到該子目錄下。
當文件存儲到某個子目錄後,即認爲該文件存儲成功,接下來會爲該文件生成一個文件名,文件名由group、存儲目錄、兩級子目錄、fileid、文件後綴名(由客戶端指定,主要用於區分文件類型)拼接而成。
客戶端帶上文件名信息請求Tracker服務獲取到存儲服務器的ip地址和端口,而後客戶端根據返回的IP地址和端口號請求下載文件,存儲服務器接收到請求後返回文件給客戶端。
跟upload file同樣,在download file時客戶端能夠選擇任意tracker server。tracker發送download請求給某個tracker,必須帶上文件名信息,tracke從文件名中解析出文件的group、大小、建立時間等信息,而後爲該請求選擇一個storage用來服務讀請求。因爲group內的文件同步時在後臺異步進行的,因此有可能出如今讀到時候,文件尚未同步到某些storage server上,爲了儘可能避免訪問到這樣的storage,tracker按照以下規則選擇group內可讀的storage。
當一個文件上傳成功後,客戶端立刻發起對該文件下載請求(或刪除請求)時,tracker是如何選定一個適用的存儲服務器呢?
其實每一個存儲服務器都須要定時將自身的信息上報給tracker,這些信息就包括了本地同步時間(即,同步到的最新文件的時間戳)。而tracker根據各個存儲服務器的上報狀況,就可以知道剛剛上傳的文件,在該存儲組中是否已完成了同步。同步信息上報以下圖:
寫文件時,客戶端將文件寫至group內一個storage server即認爲寫文件成功,storage server寫完文件後,會由後臺線程將文件同步至同group內其餘的storage server。
每一個storage寫文件後,同時會寫一份binlog,binlog裏不包含文件數據,只包含文件名等元信息,這份binlog用於後臺同步,storage會記錄向group內其餘storage同步的進度,以便重啓後能接上次的進度繼續同步;進度以時間戳的方式進行記錄,因此最好能保證集羣內全部server的時鐘保持同步。
storage的同步進度會做爲元數據的一部分彙報到tracker上,tracke在選擇讀storage的時候會以同步進度做爲參考。
好比一個group內有A、B、C三個storage server,A向C同步到進度爲T1 (T1之前寫的文件都已經同步到B上了),B向C同步到時間戳爲T2(T2 > T1),tracker接收到這些同步進度信息時,就會進行整理,將最小的那個作爲C的同步時間戳,本例中T1即爲C的同步時間戳爲T1(即全部T1之前寫的數據都已經同步到C上了);同理,根據上述規則,tracker會爲A、B生成一個同步時間戳。
精巧的文件ID-FID
說到下載就不得不提文件索引(又稱:FID)的精巧設計了。文件索引結構以下圖,是客戶端上傳文件後存儲服務器返回給客戶端,用於之後訪問該文件的索引信息。文件索引信息包括:組名,虛擬磁盤路徑,數據兩級目錄,文件名。
快速定位文件
知道FastDFS FID的組成後,咱們來看看FastDFS是如何經過這個精巧的FID定位到須要訪問的文件。
簡易FastDFS架構
5.1 安裝fastdfs依賴包
1. 解壓縮libfastcommon-master.zip
2. 進入到libfastcommon-master的目錄中
3. 執行 ./make.sh
4. 執行 sudo ./make.sh install
5.2 安裝fastdfs
1. 解壓縮fastdfs-master.zip
2. 進入到 fastdfs-master目錄中
3. 執行 ./make.sh
4. 執行 sudo ./make.sh install
5.3 配置跟蹤服務器tracker
1. sudo cp /etc/fdfs/tracker.conf.sample /etc/fdfs/tracker.conf
2. 在/home/python/目錄中建立目錄 fastdfs/tracker
mkdir –p /home/python/fastdfs/tracker
3. 編輯/etc/fdfs/tracker.conf配置文件 sudo vim /etc/fdfs/tracker.conf
修改 base_path=/home/python/fastdfs/tracker
5.4 配置存儲服務器storage
1. sudo cp /etc/fdfs/storage.conf.sample /etc/fdfs/storage.conf
2. 在/home/python/fastdfs/ 目錄中建立目錄 storage
mkdir –p /home/python/fastdfs/storage
3. 編輯/etc/fdfs/storage.conf配置文件 sudo vim /etc/fdfs/storage.conf
修改內容:
base_path=/home/python/fastdfs/storage
store_path0=/home/python/fastdfs/storage
tracker_server=本身ubuntu虛擬機的ip地址:22122
5.5 啓動tracker 和 storage
sudo service fdfs_trackerd start
sudo service fdfs_storaged start
5.6 測試是否安裝成功
1. sudo cp /etc/fdfs/client.conf.sample /etc/fdfs/client.conf
2. 編輯/etc/fdfs/client.conf配置文件 sudo vim /etc/fdfs/client.conf
修改內容:
base_path=/home/python/fastdfs/tracker
tracker_server=本身ubuntu虛擬機的ip地址:22122
3. 上傳文件測試:
fdfs_upload_file /etc/fdfs/client.conf 要上傳的圖片文件
若是返回相似group1/M00/00/00/rBIK6VcaP0aARXXvAAHrUgHEviQ394.jpg的文件id則說明文件上傳成功
5.7 安裝nginx及fastdfs-nginx-module
1. 解壓縮 nginx-1.8.1.tar.gz
2. 解壓縮 fastdfs-nginx-module-master.zip
3. 進入nginx-1.8.1目錄中
4. 執行
sudo ./configure --prefix=/usr/local/nginx/ --add-module=fastdfs-nginx-module-master解壓後的目錄的絕對路徑/src
sudo ./make
sudo ./make install
5. sudo cp fastdfs-nginx-module-master解壓後的目錄中src下的mod_fastdfs.conf /etc/fdfs/mod_fastdfs.conf
6. sudo vim /etc/fdfs/mod_fastdfs.conf
修改內容:
connect_timeout=10
tracker_server=本身ubuntu虛擬機的ip地址:22122
url_have_group_name=true
store_path0=/home/python/fastdfs/storage
7. sudo cp 解壓縮的fastdfs-master目錄中的http.conf /etc/fdfs/http.conf
8. sudo cp 解壓縮的fastdfs-master目錄中的mime.types /etc/fdfs/mime.types
9.sudo vim /usr/local/nginx/conf/nginx.conf
在http部分中添加配置信息以下:
server { listen 8888; server_name localhost; location ~/group[0-9]/ { ngx_fastdfs_module; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }
10. 啓動nginx
sudo /usr/local/nginx/sbin/nginx
1. workon django_py3
2. 進入fdfs_client-py-master.zip所在目錄
3. pip install fdfs_client-py-master.zip
4.進行文件上傳
>>> from fdfs_client.client import Fdfs_client >>> client = Fdfs_client('/etc/fdfs/client.conf') >>> ret = client.upload_by_filename('test') >>> ret {'Group name':'group1','Status':'Upload successed.', 'Remote file_id':'group1/M00/00/00/ wKjzh0_xaR63RExnAAAaDqbNk5E1398.py','Uploaded size':'6.0KB','Local file name':'test' , 'Storage IP':'192.168.243.133'}
官方接口文檔 https://github.com/jefforeilly/fdfs_client-py