FastDFS
FastDFS是用c語言編寫的一款開源的分布式文件系統(tǒng)。FastDFS為互聯(lián)網(wǎng)量身定制,充分考慮了冗余備份、負(fù)載均衡、線性擴(kuò)容等機(jī)制,并注重高可用、高性能等指標(biāo),使用FastDFS很容易搭建一套高性能的文件服務(wù)器集群提供文件上傳、下載等服務(wù)。

FastDFS服務(wù)端有兩個角色:跟蹤器(tracker)和存儲節(jié)點(storage)。跟蹤器主要做調(diào)度工作,在訪問上起負(fù)載均衡的作用。
存儲節(jié)點存儲文件,完成文件管理的所有功能:就是這樣的存儲、同步和提供存取接口,F(xiàn)astDFS同時對文件的metadata進(jìn)行管理。所謂文件的meta data就是文件的相關(guān)屬性,以鍵值對(key value)方式表示,如:width=1024,其中的key為width,value為1024。文件metadata是文件屬性列表,可以包含多個鍵值對。
跟蹤器和存儲節(jié)點都可以由一臺或多臺服務(wù)器構(gòu)成。跟蹤器和存儲節(jié)點中的服務(wù)器均可以隨時增加或下線而不會影響線上服務(wù)。其中跟蹤器中的所有服務(wù)器都是對等的,可以根據(jù)服務(wù)器的壓力情況隨時增加或減少。
為了支持大容量,存儲節(jié)點(服務(wù)器)采用了分卷(或分組)的組織方式。存儲系統(tǒng)由一個或多個卷組成,卷與卷之間的文件是相互獨立的,所有卷的文件容量累加就是整個存儲系統(tǒng)中的文件容量。一個卷可以由一臺或多臺存儲服務(wù)器組成,一個卷下的存儲服務(wù)器中的文件都是相同的,卷中的多臺存儲服務(wù)器起到了冗余備份和負(fù)載均衡的作用。
在卷中增加服務(wù)器時,同步已有的文件由系統(tǒng)自動完成,同步完成后,系統(tǒng)自動將新增服務(wù)器切換到線上提供服務(wù)。
當(dāng)存儲空間不足或即將耗盡時,可以動態(tài)添加卷。只需要增加一臺或多臺服務(wù)器,并將它們配置為一個新的卷,這樣就擴(kuò)大了存儲系統(tǒng)的容量。
FastDFS中的文件標(biāo)識分為兩個部分:卷名和文件名,二者缺一不可。

上傳交互過程
- client詢問tracker上傳到的storage,不需要附加參數(shù);
- tracker返回一臺可用的storage;
- client直接和storage通訊完成文件上傳。
下載交互過程

搭建環(huán)境文件下載列表
- FastDFS_v5.05.tar.gz
- nginx-1.14.0.tar.gz
- fastdfs-nginx-module_v1.16.tar.gz
- fastdfs_client_v1.20.jar
- libfastcommonV1.0.7.tar.gz
搭建FastDFS環(huán)境
1.上傳所有下載的壓縮源碼包
選擇CentOS6.4系統(tǒng),具體安裝見JavaEE進(jìn)階——CentOS開發(fā)環(huán)境搭建
2.安裝FastDFS之前,先安裝libevent工具包
yum -y install libevent
3.安裝libfastcommon工具包。
tar -zxvf libfastcommonV1.0.7.tar.gz
cd libfastcommon1.0.7
./make.sh
./make.sh install
cp /usr/lib64/libfastcommon.so /usr/lib/
ll |grep libfast* # 查看lib下是否存在libfastcommon.so
4.安裝Tracker服務(wù)
tar -zxvf FastDFS_v5.05.tar.gz
cd FastDFS
./make.sh
./make.sh install
cd /usr/bin/
ll fdfs_* # 查看編譯結(jié)果是否產(chǎn)生fdfs相關(guān)文件
cp FastDFS/conf/* /etc/fdfs/ # 拷貝配置文件到/etc/fdfs/目錄下
修改配置文件:
vim /etc/fdfs/tracker.conf

啟動tracker:
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf # 啟動Tracker服務(wù)
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart # 重啟Tracker服務(wù)
5.安裝Storage服務(wù)
如果是在不同的服務(wù)器安裝,需要在新的機(jī)器編譯FastDFS_v5.05.tar.gz源碼包,不需要配置Tracker服務(wù)而已。
修改配置文件:
vim /etc/fdfs/storage.conf



啟動storage服務(wù):
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf # 啟動Storage服務(wù)
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart # 重啟Storage服務(wù)
測試服務(wù)
1、修改配置文件/etc/fdfs/client.conf


2、啟動測試
/usr/bin/fdfs_test /etc/fdfs/client.conf upload anti-steal.jpg
搭建nginx提供http服務(wù)
- 解壓插件壓縮包fastdfs-nginx-module_v1.16.tar.gz
-
修改/root/fastdfs-nginx-module/src/config文件,把其中的local去掉。
- 對nginx重新config,添加Fastdfs-nginx-module:
mkdir -p /var/temp/nginx ./configure \ --prefix=/usr/local/nginx \ --pid-path=/var/run/nginx/nginx.pid \ --lock-path=/var/lock/nginx.lock \ --error-log-path=/var/log/nginx/error.log \ --http-log-path=/var/log/nginx/access.log \ --with-http_gzip_static_module \ --http-client-body-temp-path=/var/temp/nginx/client \ --http-proxy-temp-path=/var/temp/nginx/proxy \ --http-fastcgi-temp-path=/var/temp/nginx/fastcgi \ --http-uwsgi-temp-path=/var/temp/nginx/uwsgi \ --http-scgi-temp-path=/var/temp/nginx/scgi \ --add-module=/root/fastdfs-nginx-module/src # 指定自己的路徑 make make install -
把/root/fastdfs-nginx-module/src/mod_fastdfs.conf文件復(fù)制到/etc/fdfs目錄下,進(jìn)行編輯:
- nginx的配置
server { listen 80; server_name 192.168.101.3; location /group1/M00/{ ngx_fastdfs_module; } } - 將libfdfsclient.so拷貝至/usr/lib下:
cp /usr/lib64/libfdfsclient.so /usr/lib/ -
啟動nginx。
測試http服務(wù)是否成功
- 上傳圖片:
/usr/bin/fdfs_test /etc/fdfs/client.conf upload /root/anti-steal.jpg

- 訪問命令行輸出網(wǎng)址:http://192.168.74.129/group1/M00/00/00/wKhKgVslH5GAKcLdAAB1_3EXRGc833_big.png
- 如果不行,檢查22122和23000端口防火墻是否關(guān)閉,或者臨時關(guān)閉防火墻:
service iptables stop # 臨時關(guān)閉防火墻
Java使用FastDFS
官方提供一個jar包:fastdfs_client_v1.20.jar。如果使用maven管理,可以添加:
<!-- https://mvnrepository.com/artifact/net.oschina.zcx7878/fastdfs-client-java -->
<dependency>
<groupId>net.oschina.zcx7878</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27.0.0</version>
</dependency>
使用方法:
- 把FastDFS提供的jar包添加到工程中
- 初始化全局配置。加載一個配置文件。
- 創(chuàng)建一個TrackerClient對象。
- 通過TrackerClient獲得一個TrackerServer對象。
- 聲明一個StorageServer對象,null。
- 通過TrackerServer對象和StorageServer對象獲得一個StorageClient對象。
- 直接調(diào)用StorageClient對象方法上傳文件即可。
創(chuàng)建配置文件client.conf:
tracker_server=192.168.74.129:22122
測試Java代碼:
public class FastdfsTest {
@Test
public void testUpload() throws IOException, MyException {
ClientGlobal.init("E:\\Intelljidea\\taotao\\taotao-manager\\taotao-manager-web\\src\\main\\resources\\properties\\client.conf");
TrackerClient trackerClient = new TrackerClient();
TrackerServer trackerServer = trackerClient.getConnection();
StorageServer storageServer = null;
StorageClient storageClient = new StorageClient(trackerServer, storageServer);
String[] strings = storageClient.upload_file("C:\\Users\\os\\Pictures\\十分妹子.jpg", "jpg", null);
for (String string : strings) {
System.out.println(string);
}
}
}
測試結(jié)果:


FastDFS工具類:FastDFSClient.java
import org.csource.common.NameValuePair;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.StorageClient1;
import org.csource.fastdfs.StorageServer;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer;
public class FastDFSClient {
private TrackerClient trackerClient = null;
private TrackerServer trackerServer = null;
private StorageServer storageServer = null;
private StorageClient1 storageClient = null;
public FastDFSClient(String conf) throws Exception {
if (conf.contains("classpath:")) {
conf = conf.replace("classpath:", this.getClass().getResource("/").getPath());
}
ClientGlobal.init(conf);
trackerClient = new TrackerClient();
trackerServer = trackerClient.getConnection();
storageServer = null;
storageClient = new StorageClient1(trackerServer, storageServer);
}
/**
* 上傳文件方法
* <p>Title: uploadFile</p>
* <p>Description: </p>
* @param fileName 文件全路徑
* @param extName 文件擴(kuò)展名,不包含(.)
* @param metas 文件擴(kuò)展信息
* @return
* @throws Exception
*/
public String uploadFile(String fileName, String extName, NameValuePair[] metas) throws Exception {
String result = storageClient.upload_file1(fileName, extName, metas);
return result;
}
public String uploadFile(String fileName) throws Exception {
return uploadFile(fileName, null, null);
}
public String uploadFile(String fileName, String extName) throws Exception {
return uploadFile(fileName, extName, null);
}
/**
* 上傳文件方法
* <p>Title: uploadFile</p>
* <p>Description: </p>
* @param fileContent 文件的內(nèi)容,字節(jié)數(shù)組
* @param extName 文件擴(kuò)展名
* @param metas 文件擴(kuò)展信息
* @return
* @throws Exception
*/
public String uploadFile(byte[] fileContent, String extName, NameValuePair[] metas) throws Exception {
String result = storageClient.upload_file1(fileContent, extName, metas);
return result;
}
public String uploadFile(byte[] fileContent) throws Exception {
return uploadFile(fileContent, null, null);
}
public String uploadFile(byte[] fileContent, String extName) throws Exception {
return uploadFile(fileContent, extName, null);
}
}






