文章大綱
一、FastDFS介紹
二、FastDFS安裝與啓動(Linux系統)
三、Java客戶端上傳圖片
四、參考文章
一、FastDFS介紹
1. 什麼是FastDFS
FastDFS是用C語言編寫的一款開源的分佈式文件系統。FastDFS爲互聯網量身定製,充分考慮了冗餘備份、負載均衡、線性擴容等機制,並注重高可用、高性能等指標,使用FastDFS很容易搭建一套高性能的文件服務器集羣提供文件上傳、下載等服務。
2. FastDFS架構
FastDFS架構包括 Tracker server和Storage server
Tracker server作用是對Storage server進行負載均衡和調度,在文件上傳時會直接請求Tracker server,然後Tracker server可以根據一些策略找到Storage server來提供文件上傳服務。所以可以將tracker稱爲追蹤服務器或調度服務器。
Storage server作用是文件存儲,客戶端上傳的文件最終存儲在Storage服務器上,Storage server沒有實現自己的文件系統而是利用操作系統的文件系統來管理文件。可以將storage稱爲存儲服務器。
具體架構如下圖:
2.1 Tracker 集羣
FastDFS集羣中的Tracker server可以有多臺,Tracker server之間是相互平等關係同時提供服務,Tracker server不存在單點故障。客戶端請求Tracker server採用輪詢方式,如果請求的tracker無法提供服務則換另一個tracker。
2.2 Storage集羣
Storage集羣採用了分組存儲方式。storage集羣由一個或多個組構成,一個組由一臺或多臺存儲服務器組成,組內的Storage server之間是平等關係,不同組的Storage server之間不會相互通信,同組內的Storage server之間會相互連接進行文件同步,從而保證同組內每個storage上的文件完全一致的。一個組的存儲容量爲該組內存儲服務器容量最小的那個,集羣存儲總容量爲集羣中所有組的存儲容量之和,由此可見組內存儲服務器的軟硬件配置最好是一致的。
採用分組存儲方式的好處是靈活、可控性較強。比如上傳文件時,可以由客戶端直接指定上傳到的組也可以由tracker進行調度選擇。一個分組的存儲服務器訪問壓力較大時,可以在該組增加存儲服務器來擴充服務能力(縱向擴容)。當系統容量不足時,可以增加組來擴充存儲容量(橫向擴容)。
2.3 文件上傳流程
客戶端上傳文件後存儲服務器將文件ID返回給客戶端,此文件ID用於以後訪問該文件的索引信息。文件索引信息包括:組名,虛擬磁盤路徑,數據兩級目錄,文件名。
上傳說明
(1)組名:文件上傳後所在的storage組名稱,在文件上傳成功後有storage服務器返回,需要客戶端自行保存。
(2)虛擬磁盤路徑:storage配置的虛擬路徑,與磁盤選項store_path*對應。如果配置了store_path0則是M00,如果配置了store_path1則是M01,以此類推。
(3)數據兩級目錄:storage服務器在每個虛擬磁盤路徑下創建的兩級目錄,用於存儲數據文件。
(4)文件名:與文件上傳時不同。是由存儲服務器根據特定信息生成,文件名包含:源存儲服務器IP地址、文件創建時間戳、文件大小、隨機數和文件拓展名等信息。
2.4 文件下載流程
tracker根據請求的文件路徑即文件ID 來快速定義文件。
比如請求下邊的文件:
下載說明
(1)通過組名tracker能夠很快的定位到客戶端需要訪問的存儲服務器組是group1,並選擇合適的存儲服務器提供客戶端訪問。
(2)存儲服務器根據“文件存儲虛擬磁盤路徑”和“數據文件兩級目錄”可以很快定位到文件所在目錄,並根據文件名找到客戶端需要訪問的文件。
二、FastDFS安裝與啓動(Linux系統)
1. 安裝libfastcommon
(1)獲取libfastcommon安裝包:
獲取libfastcommon安裝包:
wget https://github.com/happyfish100/libfastcommon/archive/V1.0.38.tar.gz
(2)解壓安裝包:tar -zxvf V1.0.38.tar.gz
(3)進入目錄:cd libfastcommon-1.0.38
(4)執行編譯:./make.sh
(5)安裝:./make.sh install
(6)可能遇到的問題
-bash: make: command not found
-bash: gcc: command not found
解決方案:
debian通過apt-get install gcc make安裝
centos通過yum -y install gcc make安裝
2. 安裝FastDFS
(1)獲取fdfs安裝包:
wget https://github.com/happyfish100/fastdfs/archive/V5.11.tar.gz
(2)解壓安裝包:tar -zxvf V5.11.tar.gz
(3)進入目錄:cd fastdfs-5.11
(4)執行編譯:./make.sh
(5)安裝:./make.sh install
(6)查看可執行命令:ls -la /usr/bin/fdfs*
3. 配置Tracker服務
(1)進入/etc/fdfs目錄,有三個.sample後綴的文件(自動生成的fdfs模板配置文件),通過cp命令拷貝tracker.conf.sample,刪除.sample後綴作爲正式文件:
(2)編輯tracker.conf:vi tracker.conf,修改相關參數
base_path=/home/mm/fastdfs/tracker #tracker存儲data和log的跟路徑,必須提前創建好
port=23000 #tracker默認23000
http.server_port=80 #http端口,需要和nginx相同
(3)啓動tracker(支持start|stop|restart):
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf start
(4)查看tracker啓動日誌:進入剛剛指定的base_path(/home/mm/fastdfs/tracker)中有個logs目錄,查看tracker.log文件
(5)查看端口情況:netstat -apn|grep fdfs
(6)可能遇到的報錯
/usr/bin/fdfs_trackerd: error while loading shared libraries: libfastcommon.so: cannot open shared object file: No such file or directory
解決方案:建立libfastcommon.so軟鏈接
ln -s /usr/lib64/libfastcommon.so /usr/local/lib/libfastcommon.so
ln -s /usr/lib64/libfastcommon.so /usr/lib/libfastcommon.so
4. 配置Storage服務
(1)進入/etc/fdfs目錄,有cp命令拷貝storage.conf.sample,刪除.sample後綴作爲正式文件;
(2)編輯storage.conf:vi storage.conf,修改相關參數:
base_path=/home/mm/fastdfs/storage #storage存儲data和log的跟路徑,必須提前創建好
port=23000 #storge默認23000,同一個組的storage端口號必須一致
group_name=group1 #默認組名,根據實際情況修改
store_path_count=1 #存儲路徑個數,需要和store_path個數匹配
store_path0=/home/mm/fastdfs/storage #如果爲空,則使用base_path
tracker_server=10.122.149.211:22122 #配置該storage監聽的tracker的ip和port
(3)啓動storage(支持start|stop|restart)
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf start
(4)查看storage啓動日誌:進入剛剛指定的base_path(/home/mm/fastdfs/storage)中有個logs目錄,查看storage.log文件
(5)此時再查看tracker日誌:發現已經開始選舉,並且作爲唯一的一個tracker,被選舉爲leader
(6)查看端口情況:netstat -apn|grep fdfs
(7)通過monitor來查看storage是否成功綁定
/usr/bin/fdfs_monitor /etc/fdfs/storage.conf
5. 安裝Nginx和fastdfs-nginx-module模塊
(1)下載Nginx安裝包
wget http://nginx.org/download/nginx-1.15.2.tar.gz
(2)下載fastdfs-nginx-module安裝包
wget https://github.com/happyfish100/fastdfs-nginx-module/archive/V1.20.tar.gz
(3)解壓nginx:tar -zxvf nginx-1.15.2.tar.gz
(4)解壓fastdfs-nginx-module:tar -xvf V1.20.tar.gz
(5)進入nginx目錄:cd nginx-1.10.1
(6)安裝依賴的庫
apt-get update
apt-get install libpcre3 libpcre3-dev openssl libssl-dev libperl-dev
(7)配置,並加載fastdfs-nginx-module模塊:
./configure --prefix=/usr/local/nginx --add-module=/usr/local/src/fastdfs-nginx-module-1.20/src/
(8)編譯安裝:
make
make install
(9)查看安裝路徑:whereis nginx
- 啓動、停止:
cd /usr/local/nginx/sbin/
./nginx
./nginx -s stop #此方式相當於先查出nginx進程id再使用kill命令強制殺掉進程
./nginx -s quit #此方式停止步驟是待nginx進程處理任務完畢進行停止
./nginx -s reload
(11)驗證啓動狀態:wget "http://127.0.0.1"
(12)查看此時的nginx版本:發現fastdfs模塊已經安裝好了
(13)可能的報錯
/usr/include/fastdfs/fdfs_define.h:15:27: fatal error: common_define.h: No such file or directory
解決方案:修改fastdfs-nginx-module-1.20/src/config文件,然後重新第7步開始
ngx_module_incs="/usr/include/fastdfs /usr/include/fastcommon/"
CORE_INCS="$CORE_INCS /usr/include/fastdfs /usr/include/fastcommon/"
6. 配置Nginx和fastdfs-nginx-module模塊
(1)配置mod-fastdfs.conf,並拷貝到/etc/fdfs文件目錄下
cd fastdfs-nginx-module-1.20/src/
cp mod_fastdfs.conf /etc/fdfs
(2)進入/etc/fdfs修改mod-fastdfs.conf
base_path=/home/mm/fastdfs
tracker_server=10.122.149.211:22122 #tracker的地址
url_have_group_name=true #url是否包含group名稱
storage_server_port=23000 #需要和storage配置的相同
store_path_count=1 #存儲路徑個數,需要和store_path個數匹配
store_path0=/home/mm/fastdfs/storage #文件存儲的位置
(3)配置nginx,80端口server增加location如圖
cd /usr/local/nginx/conf/
vi nginx.conf
(4)最後需要拷貝fastdfs解壓目錄中的http.conf和mime.types
cd /usr/local/src/fastdfs-5.11/conf
cp mime.types http.conf /etc/fdfs/
7. FastDFS常用命令測試
7.1 上傳文件
(1)進入/etc/fdfs目錄,有cp命令拷貝client.conf.sample,刪除.sample後綴作爲正式文件;
(2)修改client.conf相關配置:
base_path=/home/mm/fastdfs/tracker //tracker服務器文件路徑
tracker_server=10.122.149.211:22122 //tracker服務器IP地址和端口號
http.tracker_server_port=80 # tracker服務器的http端口號,必須和tracker的設置對應起來
(3)新建一個測試文檔1.txt,內容爲abc
(4)命令
/usr/bin/fdfs_upload_file <config_file> <local_filename>
(5)示例
/usr/bin/fdfs_upload_file /etc/fdfs/client.conf 1.txt
組名:group1
磁盤:M00
目錄:00/00
文件名稱:CnqV01trmeyAbAN0AAAABLh3frE677.txt
(6)查看結果,進入storage的data目錄
(7)通過wget和瀏覽器方式訪問成功
wget http://10.122.149.211/group1/M00/00/00/CnqV01trmeyAbAN0AAAABLh3frE677.txt
7.2 下載文件
(1)命令
/usr/bin/fdfs_download_file <config_file> <file_id> [local_filename]
(2)示例
/usr/bin/fdfs_download_file /etc/fdfs/client.conf group1/M00/00/00/CnqV01trmeyAbAN0AAAABLh3frE677.txt a.txt
(3)查看結果
7.3 刪除文件
(1)命令
/usr/bin/fdfs_delete_file <config_file> <file_id>
(2)示例
/usr/bin/fdfs_delete_file /etc/fdfs/client.conf group1/M00/00/00/CnqV01trmeyAbAN0AAAABLh3frE677.txt
(3)查看結果,進入storage的data目錄文件不存在,通過wget再次獲取404:
溫馨提示:現在FastDFS的安裝好像不支持Windows
三、Java客戶端上傳圖片
1. 新建maven項目
2. pom.xml文件添加相關依賴
<dependencies>
<!--引入FastDFS工具類-->
<dependency>
<groupId>cn.bestwu</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27</version>
</dependency>
<!--引入testng單元測試-->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>RELEASE</version>
</dependency>
<!--引入IO工具類庫-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
3. 添加配置文件內容
connect_timeout = 2
network_timeout = 30
charset = UTF-8
# Tracker配置文件中配置的http端口
http.tracker_http_port = 80
http.anti_steal_token = no
http.secret_key = FastDFS1234567890
# Tracker服務器地址
tracker_server = 192.168.105.133:22122
tracker_server = 192.168.105.134:22122
4. 創建Java_Tools類,使用單元測試測試文件上傳和下載
import org.apache.commons.io.IOUtils;
import org.csource.common.MyException;
import org.csource.fastdfs.*;
import org.testng.annotations.Test;
import java.io.FileOutputStream;
import java.io.IOException;
public class Java_Tools {
// 本地文件位置
String local = "C:\\Users\\XY\\Documents\\上傳.txt";
// 聲明跟蹤器客戶端對象
TrackerClient trackerClient = null;
// 聲明存儲器客戶端對象
StorageClient1 storageClient1 = null;
// 聲明跟蹤器服務對象
TrackerServer trackerServer = null;
// 聲明存儲器服務對象
StorageServer storageServer = null;
// 文件上傳
@Test
public void testUpload() {
try {
// 初始化配置文件
ClientGlobal.init("fdfs_client.conf");
// 創建跟蹤器客戶端對象
trackerClient = new TrackerClient();
// 獲取跟蹤器連接
trackerServer = trackerClient.getConnection();
// 獲取存儲器客戶端對象
storageClient1 = new StorageClient1(trackerServer, storageServer);
// 上傳文件,返回文件標識
String index = storageClient1.upload_file1(local, null, null);
// 查看標識
System.out.println(index);
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
}
}
// 文件下載
@Test
public void testDownload() {
try {
ClientGlobal.init("fdfs_client.conf");
trackerClient = new TrackerClient();
trackerServer = trackerClient.getConnection();
storageClient1 = new StorageClient1(trackerServer, storageServer);
// 根據文件標識下載文件
byte[] by = storageClient1.download_file1("group1/M00/00/00/wKhphVrxnTeAPEznAANfM1yHJic535.txt");
// 將數據寫入輸出流
IOUtils.write(by, new FileOutputStream("C:\\Users\\XY\\Documents\\下載.txt"));
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
}
}
// 文件刪除
@Test
public void testDelete() {
try {
ClientGlobal.init("fdfs_client.conf");
trackerClient = new TrackerClient();
trackerServer = trackerClient.getConnection();
storageClient1 = new StorageClient1(trackerServer, storageServer);
// 根據文件標識刪除文件,返回0則刪除成功
int i = storageClient1.delete_file1("group1/M00/00/00/wKhphVry2QmAXgH2AANfM1yHJic724.txt");
if (i == 0) {
System.out.println("刪除成功");
} else {
System.out.println("刪除失敗");
}
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
}
}
// 文件信息
@Test
public void testGetFileInfo() {
try {
ClientGlobal.init("fdfs_client.conf");
trackerClient = new TrackerClient();
trackerServer = trackerClient.getConnection();
storageClient1 = new StorageClient1(trackerServer, storageServer);
// 根據文件標識獲取文件信息
FileInfo fileInfo = storageClient1.get_file_info1("group1/M00/00/00/wKhphVry2QmAXgH2AANfM1yHJic724.txt");
// 文件IP地址
System.out.println(fileInfo.getSourceIpAddr());
// 文件大小
System.out.println(fileInfo.getFileSize());
// 創建時間
System.out.println(fileInfo.getCreateTimestamp());
// 錯誤校驗碼
System.out.println(fileInfo.getCrc32());
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
}
}
}