fastdfs簡介
fastdfs是一款開源的輕量級分布式文件系統,使用c實現,支持linux、bsd等unix-like操作系統。值得注意的是,fastdfs并不是通用的文件系統,只能通過專用的api訪問。
fastdfs為互聯網應用量身定做,解決了大容量文件存儲的問題,fastdfs追求高性能和高擴展性。fastdfs的主要概念:
tracker-server:跟蹤服務器。用于跟蹤文件,主要起調度作用。在內存中記錄了所有存儲組和存儲服務器的狀態信息,是客戶端和數據存儲的主要樞紐。相比gfs更為精簡,因為不記錄文件索引。
storage-server: 存儲服務器。用于存儲文件。直接使用操作系統的文件系統來管理和組織文件。
group: 組,卷。多個服務器存在一個組中,在一個組中的服務器存儲的文件是完全相同的,并且同一個組的服務器地位是對等的。對于文件的操作可以在任意一個組中的服務器上進行。
metadata: 元數據。以鍵值對的方式存儲,用于存儲文件的相關信息。
各大存儲系統的對比
話說沒有對比就沒有傷害,fastdfs也不是萬能的,需要根據業務來選擇適合的存儲系統。
存儲系統 | 適合存儲的文件類型 | 文件分布情況 | 系統性能 | 復雜度 | fuse(用戶文件系統) | posix() | 備份機制 | 通訊協議接口 | 社區情況 | 實現語言 |
---|---|---|---|---|---|---|---|---|---|---|
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 |
github項目主頁:https://github.com/happyfish100/fastdfs
fastdfs客戶端與服務器端交互原理
fastdfs+nginx整合
架構圖
安裝fastdfs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
mkdir /source cd /source yum install -y gcc gcc-c++ make cmake wget libevent wget https: //github.com/happyfish100/libfastcommon/archive/v1.0.35.tar.gz wget https: //github.com/happyfish100/fastdfs/archive/v5.10.tar.gz tar -zxvf v1. 0.35 .tar.gz tar -zxvf v5. 10 .tar.gz cd libfastcommon- 1.0 . 35 ./make.sh ./make.sh install ln -s /usr/lib64/libfastcommon.so /usr/local/lib/libfastcommon.so cd ../ cd fastdfs- 5.10 / ./make.sh ./make.sh install cd ../ rm -rf libfastcommon- 1.0 . 35 rm -rf fastdfs- 5.10 cp /etc/fdfs/tracker.conf.sample /etc/fdfs/tracker.conf cp /etc/fdfs/storage.conf.sample /etc/fdfs/storage.conf cp /etc/fdfs/client.conf.sample /etc/fdfs/client.conf mkdir -p /data/fdfs/tracker mkdir -p /data/fdfs/storage ln -s /usr/bin/stop.sh /usr/local/bin/stop.sh ln -s /usr/bin/restart.sh /usr/local/bin/restart.sh |
修改配置文件
修改跟蹤器配置文件:
1
|
base_path=/data/fdfs/tracker |
修改存儲器配置文件:
1
2
3
|
base_path=/data/fdfs/storage store_path0=/data/fdfs/storage tracker_server= 192.168 . 80.3 : 22122 |
修改客戶端配置文件:
1
2
|
base_path=/data/fdfs/client tracker_server= 192.168 . 80.3 : 22122 |
啟動
1
2
|
/etc/init.d/fdfs_trackerd start /etc/init.d/fdfs_storaged start |
1
2
3
4
|
netstat -tunlap | grep : 22122 tcp 0 0 0.0 . 0.0 : 22122 0.0 . 0.0 :* listen 7247 /fdfs_trackerd tcp 0 0 192.168 . 80.3 : 22122 192.168 . 80.3 : 39318 established 7247 /fdfs_trackerd tcp 0 0 192.168 . 80.3 : 39318 192.168 . 80.3 : 22122 established 7444 /fdfs_storaged |
啟動后要查看狀態, 出現 active (exited)
字樣可以嘗試重啟服務。
測試
1
2
|
/usr/bin/fdfs_upload_file /etc/fdfs/client.conf /source/fastdfs_v5. 05 .tar.gz group1/m00/ 00 / 00 /wkhqa1ysjsgapjxbaavfol7fju4.tar.gz |
文件存儲在:
1
|
ll /data/fdfs/storage/data/ 00 / 00 /wkhqa1ysjsgapjxbaavfol7fju4.tar.gz |
安裝nginx并配置模塊
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
# 安裝nginx需要的pcre(perl兼容正則表達式)庫,允許nginx使用rewrite模塊提供url重寫功能。 yum install pcre pcre-devel perl-extutils-embed -y # 安裝openssl-devel,允許nginx提供https服務。 yum install openssl-devel -y # 下載軟件包 cd /source wget http: //59.80.44.46/nginx.org/download/nginx-1.14.2.tar.gz wget http: //nchc.dl.sourceforge.net/project/fastdfs/fastdfs%20nginx%20module%20source%20code/fastdfs-nginx-module_v1.16.tar.gz # 解壓軟件包 tar xvf nginx- 1.14 . 2 .tar.gz tar xvf fastdfs-nginx-module_v1. 16 .tar.gz # 創建必要的軟連接 ln -s /usr/include/fastdfs/ /usr/local/include/fastdfs ln -s /usr/include/fastcommon/ /usr/local/include/fastcommon cp fastdfs/conf/http.conf /etc/fdfs/ cp fastdfs/conf/mime.types /etc/fdfs/ cp fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs/ mkdir -p /data/fdfs/fastdfs-nginx-module |
修改配置文件 /etc/fdfs/mod_fastdfs.conf
:
1
2
3
4
5
6
|
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 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
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區塊添加:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
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; } } |
測試配置文件正確性并啟動:
1
2
|
/applications/nginx/sbin/nginx -t /applications/nginx/sbin/nginx |
刪除臨時文件:
1
2
3
4
|
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)進行路由。
簡單的啟動停止服務的腳本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
# 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 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
# 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
中修改:
1
2
3
4
5
6
7
8
|
# 開啟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客戶端驗證:
將客戶端安裝到本地倉庫:
1
2
3
|
git clone https: //github.com/happyfish100/fastdfs-client-java.git cd fastdfs-client-java mvn clean install |
使用maven創建一個普通的項目,在pom文件中添加依賴:
1
2
3
4
5
6
7
|
<dependencies> <dependency> <groupid>org.csource</groupid> <artifactid>fastdfs-client-java</artifactid> <version> 1.27 -snapshot</version> </dependency> </dependencies> |
在resources目錄下創建fastdfs配置文件 fastdfs-client.properties
:
1
2
3
4
5
6
7
|
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
類文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
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" )); // 使用瀏覽器訪問返回的url system.out.println( "http://192.168.80.3:8000/" + remotefilename + "?token=" + token + "&ts=" + ts); } } |
如果訪問時顯示防盜鏈圖片,可能是測試客戶端與服務器之間的之間有一定差距,兩個主機之間不能有分鐘級別的差距,可以使用如下方法同步服務器:
1
2
3
4
|
# 安裝同步時間服務器的客戶端, 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
1
2
3
4
5
6
7
8
|
tar -xvf db- 6.2 . 23 .tar.gz cd db- 6.2 . 23 /build_unix/ ../dist/configure --prefix=/applications/db- 6.2 . 23 cd ../../ rm -rf db- 6.2 . 23 unzip fastdht-master.zip cd fastdht-master vim make.sh |
修改第27行代碼:
1
|
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
: 指定數據庫提供的庫文件目錄
1
2
3
4
|
./make.sh ./make.sh install cd ../ rm -rf fastdht-master |
配置
1
|
mkdir /data/fdht |
修改 /etc/fdht/fdht_client.conf
內容:
1
2
|
base_path=/data/fdht #include /etc/fdht/fdht_servers.conf |
修改 /etc/fdht/fdht_servers.conf
內容:
1
|
group0 = 192.168 . 80.3 : 11411 |
修改 /etc/fdht/fdhtd.conf
內容:
1
2
|
base_path=/data/fdht #include /etc/fdht/fdht_servers.conf |
修改 /etc/fdfs/storage.conf
內容:
1
2
3
4
|
check_file_duplicate= 1 key_namespace=fastdfs keep_alive= 1 #include /etc/fdht/fdht_servers.conf |
主要需要包含服務器端配置文件。
1
2
|
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 |
啟動并測試
1
|
fdhtd /etc/fdht/fdhtd.conf |
重啟使用:
1
|
fdhtd /etc/fdht/fdhtd.conf restart |
查看結果:
1
2
|
netstat -tunlap | grep : 11411 tcp 0 0 0.0 . 0.0 : 11411 0.0 . 0.0 :* listen 20605 /fdhtd |
由于安裝fastdht的時候關閉了fastdfs,因此需要啟動fastdfs
1
|
./start-service |
修改之前的 start-service
腳本, 在啟動tracker和storage服務之前添加:
1
|
fdhtd /etc/fdht/fdhtd.conf |
在查看tracker和ngixn網絡狀態之前添加:
1
|
netstat -tunlap | grep : 11411 |
測試:
1
2
3
4
5
6
7
8
9
|
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項目,我們可以自定義一個場景啟動器來解決。詳細信息: https://github.com/bluemiaomiao/fastdfs-spring-boot-starter .
下面使用springboot構建一個示例項目:
添加依賴:
1
2
3
4
5
|
<dependency> <groupid>com.bluemiaomiao</groupid> <artifactid>fastdfs-spring-boot-starter</artifactid> <version> 1.0 -snapshot</version> </dependency> |
在主配置類中添加注解:
1
2
3
4
5
6
7
8
9
10
11
|
@enablefastdfsclient @springbootapplication public class demoapplication { @autowired private fastdfsclientservice fastdfsclientservice; public static void main(string[] args) { springapplication.run(demoapplication. class , args); } } |
此時將會自動初始化好全局客戶端。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://blog.51cto.com/xvjunjie/2377669