Java高级架构之FastDFS分布式文件集群
FastDFS簡介
FastDFS是一款開源的輕量級分布式文件系統,使用C實現,支持Linux、BSD等unix-like操作系統。值得注意的是,fastdfs并不是通用的文件系統,只能通過專用的API訪問。
fastdfs為互聯網應用量身定做,解決了大容量文件存儲的問題,fastdfs追求高性能和高擴展性。fastdfs的主要概念:
tracker-server:跟蹤服務器。用于跟蹤文件,主要起調度作用。在內存中記錄了所有存儲組和存儲服務器的狀態信息,是客戶端和數據存儲的主要樞紐。相比GFS更為精簡,因為不記錄文件索引。
storage-server: 存儲服務器。用于存儲文件。直接使用操作系統的文件系統來管理和組織文件。
group: 組,卷。多個服務器存在一個組中,在一個組中的服務器存儲的文件是完全相同的,并且同一個組的服務器地位是對等的。對于文件的操作可以在任意一個組中的服務器上進行。
- metadata: 元數據。以鍵值對的方式存儲,用于存儲文件的相關信息。
各大存儲系統的對比
話說沒有對比就沒有傷害,fastdfs也不是萬能的,需要根據業務來選擇適合的存儲系統。
| FastDFS | 4KB至500MB | 將小文件合并存儲 | 很高 | 簡單 | 不支持 | 不支持 | 組內冗余備份 | HTTP API | 國內用戶 | C |
| TFS | 所有文件 | 小文件合并以塊組織分片 | - | 復雜 | 不支持 | 不支持 | 塊存儲多份,主輔災備 | HTTP API | 少 | C++ |
| MFS | 大于64K | 分片存儲 | Master節點占用內存較高 | - | 支持 | 支持 | 多點備份,動態冗余 | 使用FUSE掛載 | 較多 | Perl |
| HDFS | 大文件 | 大文件分片塊存儲 | - | 簡單 | 支持 | 支持 | 多副本 | 原生API | 較多 | Java |
| Ceph | 對象大文件 | OSD一主多從 | - | 復雜 | 支持 | 支持 | 多副本 | 原生API | 較少 | C++ |
| MogileFS | 海量小圖片 | - | 高 | 復雜 | 支持 | 不支持 | 動態冗余 | 原生API | 文檔少 | Perl |
| ClusterFS | 大文件 | - | - | 簡單 | 支持 | 支持 | - | - | 多 | C |
FastDFS客戶端與服務器端交互原理
FastDFS+Nginx整合
- 架構圖
- 安裝FastDFS
- 修改配置文件
修改跟蹤器配置文件:
base_path=/data/fdfs/tracker復制代碼修改存儲器配置文件:
base_path=/data/fdfs/storage store_path0=/data/fdfs/storage tracker_server=192.168.80.3:22122復制代碼修改客戶端配置文件:
base_path=/data/fdfs/client tracker_server=192.168.80.3:22122復制代碼- 啟動
啟動后要查看狀態, 出現 active (exited) 字樣可以嘗試重啟服務。
- 測試
文件存儲在:
ll /data/fdfs/storage/data/00/00/wKhQA1ysjSGAPjXbAAVFOL7FJU4.tar.gz復制代碼- 安裝Nginx并配置模塊
修改配置文件 /etc/fdfs/mod_fastdfs.conf :
connect_timeout=10 base_path=/data/fdfs/fastdfs-nginx-module # 配置服務器的地址 tracker_server=192.168.80.3:22122 url_have_group_name = true store_path0=/data/fdfs/storage復制代碼mkdir /applications mkdir /tmp/nginx useradd nginx -s /sbin/nologin -M cd nginx-1.14.2 ./configure \ --user=nginx \ --group=nginx \ --prefix=/applications/nginx-1.14.2 \ --with-http_ssl_module \ --with-http_gzip_static_module \ --http-client-body-temp-path=/tmp/nginx/client \ --http-proxy-temp-path=/tmp/nginx/proxy \ --http-fastcgi-temp-path=/tmp/nginx/cgi \ --with-poll_module \ --with-file-aio \ --with-http_realip_module \ --with-http_addition_module \ --with-http_random_index_module \ --with-pcre \ --with-http_stub_status_module \ --with-stream \ --add-module=/source/fastdfs-nginx-module/src make make install ln -s /applications/nginx-1.14.2/ /applications/nginx chown -R nginx.nginx /applications/nginx chown -R nginx.nginx /applications/nginx-1.14.2/ chown -R nginx.nginx /tmp/nginx/復制代碼修改配置文件 /applications/nginx/conf/nginx.conf, 在http區塊添加:
server {listen 8000;server_name media;location / {root html;index index.html index.htm;}# 攔截文件請求,轉發到下面的模塊location ~/group[0-9] {ngx_fastdfs_module;}error_page 500 502 503 504 /50x.html;location = /50x.html {root html;}}復制代碼測試配置文件正確性并啟動:
/applications/nginx/sbin/nginx -t /applications/nginx/sbin/nginx復制代碼刪除臨時文件:
rm -rf FastDFS rm -rf fastdfs-nginx-module rm -rf libfastcommon-1.0.35 rm -rf nginx-1.14.2復制代碼測試Nginx文件下載功能, 在瀏覽器輸入: http://192.168.80.3:8000/group1/M00/00/00/wKhQA1ysjSGAPjXbAAVFOL7FJU4.tar.gz
一個nginx只能訪問一個storage服務器的數據,所以多個storage服務器要配置多個nginx,然后將nginx按照請求路徑中的組id(groupid)進行路由。
簡單的啟動停止服務的腳本:
# start-service # usage: ./start-service echo "============================================Sync datetime===========================================" ntpdate time7.aliyun.com echo "===========================================Getting status===========================================" /etc/init.d/fdfs_trackerd status /etc/init.d/fdfs_storaged status echo "==========================================Starting service==========================================" /etc/init.d/fdfs_storaged start /etc/init.d/fdfs_trackerd start echo "===========================================Getting status===========================================" /etc/init.d/fdfs_trackerd status /etc/init.d/fdfs_storaged status echo "=========================================Testing config file========================================" /applications/nginx/sbin/nginx -t echo "=========================================Starting web server========================================" /applications/nginx/sbin/nginx echo "=======================================Getting network status=======================================" sleep 5s netstat -tunlap | grep :22122 netstat -tunlap | grep :8000復制代碼# stop-service # usage: ./stop-service echo "===========================================Getting status===========================================" /etc/init.d/fdfs_trackerd status /etc/init.d/fdfs_storaged status echo "==========================================Stopping service==========================================" /etc/init.d/fdfs_storaged stop /etc/init.d/fdfs_trackerd stop echo "========================================Stopping web server=========================================" kill `cat /applications/nginx/logs/nginx.pid` echo "===========================================Getting status===========================================" /etc/init.d/fdfs_trackerd status /etc/init.d/fdfs_storaged status echo "=======================================Getting network status=======================================" sleep 5s netstat -tunlap | grep :22122 netstat -tunlap | grep :8000復制代碼基于Token的防盜鏈實現
FastDFS內置使用Token的方式實現防盜鏈,Token是帶有時效性的,Token中包含了文件id、時間戳ts和token。在FastDFS中使用URL帶上ts和token的方式請求資源。在FastDFS中提供了生成Token的算法,擴展模塊會對Token進行驗證。由于Token的生成和校驗都在服務器端,因此不會存在安全性問題。鏈接示例:
http://192.168.1.15:8080/group1/M01/01/01/wKgBD01c15nvKU1cAABAOeCdFS466570.c?token=b32cd06a53dea4376e43d71cc882f9cb&ts=1297930137復制代碼在 /etc/fdfs/http.conf 中修改:
# 開啟Token校驗 http.anti_steal.check_token=true # Token的聲明周期為240秒 http.anti_steal.token_ttl=240 # 加密字符串,可以使用 openssl rand -base64 64 生成 http.anti_steal.secret_key=2scPwMPctXhbLVOYB0jyuyQzytOofmFCBIYe65n56PPYVWrntxzLIDbPdvDDLJM8QHhKxSGWTcr+9VdG3yptkw # Token校驗失敗的時候返回的圖片 http.anti_steal.token_check_fail=/data/fdfs/error.svg復制代碼- 使用Java客戶端驗證:
將客戶端安裝到本地倉庫:
git clone https://github.com/happyfish100/fastdfs-client-java.git cd fastdfs-client-java mvn clean install復制代碼使用Maven創建一個普通的項目,在POM文件中添加依賴:
<dependencies><dependency><groupId>org.csource</groupId><artifactId>fastdfs-client-java</artifactId><version>1.27-SNAPSHOT</version></dependency> </dependencies>復制代碼在resources目錄下創建FastDFS配置文件 fastdfs-client.properties :
fastdfs.connect_timeout_in_seconds = 5 fastdfs.network_timeout_in_seconds = 30 fastdfs.charset = UTF-8 fastdfs.http_anti_steal_token = true fastdfs.http_secret_key = 2scPwMPctXhbLVOYB0jyuyQzytOofmFCBIYe65n56PPYVWrntxzLIDbPdvDDLJM8QHhKxSGWTcr+9VdG3yptkw fastdfs.http_tracker_http_port = 8080 fastdfs.tracker_servers = 192.168.80.3:22122復制代碼創建 com.bluemiaomiao.Demo.java 類文件:
package com.bluemiaomiao;import org.csource.common.MyException; import org.csource.fastdfs.ClientGlobal; import org.csource.fastdfs.ProtoCommon; import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.util.Properties;public class Demo {public static void main(String[] args) throws IOException, MyException, NoSuchAlgorithmException {// 加載配置文件Properties prop = new Properties();prop.load(Demo.class.getResourceAsStream("/fastdfs-client.properties"));ClientGlobal.initByProperties(prop);// 顯示初始化配置信息System.out.println(ClientGlobal.configInfo());// 使用文件上傳工具返回的地址,一般情況下保存在數據庫中String remoteFileName = "group1/M00/00/00/wKhQA1ysjSGAPjXbAAVFOL7FJU4.tar.gz";// 獲取當前時間戳int ts = (int)(System.currentTimeMillis()/1000);// 獲取Token, 傳入的文件ID不要含有分組信息String token = ProtoCommon.getToken("M00/00/00/wKhQA1ysjSGAPjXbAAVFOL7FJU4.tar.gz", ts, prop.getProperty("fastdfs.http_secret_key"));// 使用瀏覽器訪問返回的URLSystem.out.println("http://192.168.80.3:8000/" + remoteFileName + "?token=" + token + "&ts=" + ts);} }復制代碼如果訪問時顯示防盜鏈圖片,可能是測試客戶端與服務器之間的之間有一定差距,兩個主機之間不能有分鐘級別的差距,可以使用如下方法同步服務器:
# 安裝同步時間服務器的客戶端, Windows系統也需要與該服務器同步 # 控制面板->時鐘和區域->設置日期和時間->Internet時間->更改設置 yum install ntpdate ntpdate time7.aliyun.com復制代碼整合FastDHT實現數據去重
FastDHT是分布式哈希系統(DHT),使用BerkeleyDB做數據存儲,使用libevent做網絡IO處理。依賴于libfastcommon組件。
- 下載
去Oracle官方網站下載 Berkeley DB 數據庫,去Fastdfs的GitHub主頁下載FastDHT的源碼包。由于之前已經安裝過linevent和libfastcommon,因此只需要安裝數據庫和FastDHT即可。
- 安裝配置數據庫與FastDHT
修改第27行代碼:
CFLAGS='-Wall -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -I /applications/db-6.2.23/include/ -L /applications/db-6.2.23/lib/'復制代碼-I: 指定數據庫提供的頭文件目錄
-L: 指定數據庫提供的庫文件目錄
./make.sh ./make.sh install cd ../ rm -rf fastdht-master復制代碼- 配置
修改 /etc/fdht/fdht_client.conf 內容:
base_path=/data/fdht #include /etc/fdht/fdht_servers.conf復制代碼修改 /etc/fdht/fdht_servers.conf 內容:
group0 = 192.168.80.3:11411復制代碼修改 /etc/fdht/fdhtd.conf 內容:
base_path=/data/fdht #include /etc/fdht/fdht_servers.conf復制代碼修改 /etc/fdfs/storage.conf 內容:
check_file_duplicate=1 key_namespace=FastDFS keep_alive=1 #include /etc/fdht/fdht_servers.conf復制代碼主要需要包含服務器端配置文件。
ln -s /applications/db-6.2.23/lib/libdb-6.2.so /usr/lib/libdb-6.2.so ln -s /applications/db-6.2.23/lib/libdb-6.2.so /usr/lib64/libdb-6.2.so復制代碼- 啟動并測試
重啟使用:
fdhtd /etc/fdht/fdhtd.conf restart復制代碼查看結果:
netstat -tunlap | grep :11411 tcp 0 0 0.0.0.0:11411 0.0.0.0:* LISTEN 20605/fdhtd復制代碼- 由于安裝FastDHT的時候關閉了FastDFS,因此需要啟動FastDFS
修改之前的 start-service 腳本, 在啟動tracker和storage服務之前添加:
fdhtd /etc/fdht/fdhtd.conf復制代碼在查看tracker和ngixn網絡狀態之前添加:
netstat -tunlap | grep :11411復制代碼測試:
fdfs_upload_file /etc/fdfs/client.conf /source/db-6.2.23.tar.gz group1/M00/00/00/wKhQA1yu2L6APTk-AqQOLABfhaQ.tar.gz fdfs_upload_file /etc/fdfs/client.conf /source/db-6.2.23.tar.gz group1/M00/00/00/wKhQA1yu2MKAOmIiAqQOLHUWXfw.tar.gz ll /data/fdfs/storage/data/00/00/ total 45268 -rw-r--r-- 1 root root 44305964 Apr 11 14:03 wKhQA1yu2L6AM0aiAqQOLKFBFuc.tar.gz lrwxrwxrwx 1 root root 64 Apr 11 14:03 wKhQA1yu2L6APTk-AqQOLABfhaQ.tar.gz -> /data/fdfs/storage/data/00/00/wKhQA1yu2L6AM0aiAqQOLKFBFuc.tar.gz lrwxrwxrwx 1 root root 64 Apr 11 14:03 wKhQA1yu2MKAOmIiAqQOLHUWXfw.tar.gz -> /data/fdfs/storage/data/00/00/wKhQA1yu2L6AM0aiAqQOLKFBFuc.tar.gz復制代碼自定義 fastdfs-spring-boot-starter
為了快速構建SpringBoot項目,我們可以自定義一個場景啟動器來解決。詳細信息:github.com/bluemiaomia… .
下面使用SpringBoot構建一個示例項目:
- 添加依賴:
在主配置類中添加注解:
@EnableFastdfsClient @SpringBootApplication public class DemoApplication {@Autowired private FastdfsClientService fastdfsClientService;public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args); } }復制代碼
此時將會自動初始化好全局客戶端。
對文章有興趣的朋友可以關注小編掘金好,以后會有更多的優質文章輸出。
轉載于:https://juejin.im/post/5cb4949c6fb9a068565681f5
總結
以上是生活随笔為你收集整理的Java高级架构之FastDFS分布式文件集群的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: js 小数点 精准算法
- 下一篇: java8升级java11到底敢不敢?