## 1.簡介
FastDFS是一款開源的、分布式文件系統(Distributed File System),由淘寶開發平臺部資深架構師余慶開發。
github源碼:https://github.com/happyfish100/fastdfs
### 1.1適用場景
FastDFS是一個開源的分布式文件系統,她對文件進行管理,功能包括:文件存儲、文件同步、文件訪問(文件上傳、文件下載)等,解決了大容量存儲和負載均衡的問題。特別適合以文件為載體的在線服務,如相冊網站、視頻網站等等。
### 1.2架構
FastDFS服務端有兩個角色:跟蹤器(tracker)和存儲節點(storage)。跟蹤器主要做調度工作,在訪問上起負載均衡的作用。
FastDFS系統結構如下圖所示:

跟蹤器和存儲節點都可以由一臺多臺服務器構成。跟蹤器和存儲節點中的服務器均可以隨時增加或下線而不會影響線上服務。其中跟蹤器中的所有服務器都是對等的,可以根據服務器的壓力情況隨時增加或減少。
為了支持大容量,存儲節點(服務器)采用了分卷(或分組)的組織方式。存儲系統由一個或多個卷組成,卷與卷之間的文件是相互獨立的,所有卷 的文件容量累加就是整個存儲系統中的文件容量。一個卷可以由一臺或多臺存儲服務器組成,一個卷下的存儲服務器中的文件都是相同的,卷中的多臺存儲服務器起 到了冗余備份和負載均衡的作用。
在卷中增加服務器時,同步已有的文件由系統自動完成,同步完成后,系統自動將新增服務器切換到線上提供服務。
當存儲空間不足或即將耗盡時,可以動態添加卷。只需要增加一臺或多臺服務器,并將它們配置為一個新的卷,這樣就擴大了存儲系統的容量。
FastDFS中的文件標識分為兩個部分:**卷名和文件名,二者缺一不可**。

FastDFS file upload
上傳文件交互過程:
1. client詢問tracker上傳到的storage,不需要附加參數;
2. tracker返回一臺可用的storage;
3. client直接和storage通訊完成文件上傳。

FastDFS file download
下載文件交互過程:
1. client詢問tracker下載文件的storage,參數為文件標識(卷名和文件名);
2. tracker返回一臺可用的storage;
3. client直接和storage通訊完成文件下載。
## 2.安裝
### 2.1 安裝腳本說明
Github地址:
```
wget https://github.com/hanxt/fastdfs_fastsetup/archive/master.zip
```
* common_setup.sh,通用安裝腳本,主要用于安裝libfastcommon,fastdfs以及與其相關的依賴.
* tracker_setup.sh,tracker節點配置腳本
* storage_setup.sh,storage節點配置腳本
* startup.sh 啟動腳本,tracker和storage的啟動.
* fastdfs-5.05 fastdfs安裝包
* fastdfs-nginx-module-master 安裝包
* libfastcommon-1.0.7 安裝包
### 2.2安裝libfastcommon和Fastdfs
* libfastcommon是FastDFS項目的通用函數庫。其中的方法包括:string,logger,chain,hash,socket,ini file reader,base64 encode / decode,url encode / decode,fasttimer等。
**每一個節點都需要執行,這個安裝腳本,安裝過程中需要輸入sudo密碼**
```
common_setup.sh
```
可以看到libfastcommon.so安裝到了“/usr/lib64”目錄。
腳本中執行了如下的創建軟鏈接操作,以下文件都存在libfastcommon,就成功了:
```
ls /usr/lib64/libfastcommon.so /usr/local/lib/libfastcommon.so;
ls /usr/lib64/libfastcommon.so /usr/lib/libfastcommon.so;
ls /usr/lib64/libfdfsclient.so /usr/local/lib/libfdfsclient.so;
ls /usr/lib64/libfdfsclient.so /usr/lib/libfdfsclient.so;
```
fastdfs安裝完成后,所有可執行文件在目錄“/usr/bin”下,以fdfs_開頭:
```
aixin@DC-server1:~/fastdfs-5.05$ ls /usr/bin/fdfs_*
/usr/bin/fdfs_append_file /usr/bin/fdfs_appender_test1
/usr/bin/fdfs_delete_file /usr/bin/fdfs_file_info
/usr/bin/fdfs_storaged /usr/bin/fdfs_test1
/usr/bin/fdfs_upload_appender /usr/bin/fdfs_appender_test
/usr/bin/fdfs_crc32 /usr/bin/fdfs_download_file
/usr/bin/fdfs_monitor /usr/bin/fdfs_test
/usr/bin/fdfs_trackerd /usr/bin/fdfs_upload_file
```
另外可以看到,配置文件存儲在目錄“/etc/fdfs”下,證明安裝成功!
## 2.3配置FastDFS
* client.conf 客戶端上傳配置文件
* storage.conf 文件存儲服務器配置文件
* tracker.conf 負責均衡調度服務器配置文件
* mod_fastdfs.conf fastdfs的nginx模塊配置文件
在本例中,使用的是ubuntu14.04的服務器,三臺.部署結構如下:
|ip|負載均衡(nginx或ha)|tracker|storage+nginx|
|---|---|---|
|192.168.1.158|是|是||
|192.168.1.60|||是|
|192.168.1.24|||是|
### 2.3.1配置及啟動Tracker Server
**自動配置執行腳本**
```bash
tracker_setup.sh
```
此腳本主要做了兩件事
* /etc/fdfs/tracker.conf參數配置
* /etc/fdfs/client.conf參數配置
主要配置了以下參數
```
# tracker數據存儲位置
DATA_DIR=/home/aixin/data/fastdfs/tracker
# storage圖片http訪問端口
HTTP_SERVERPORT=8987
# 客戶端數據存儲位置,用于測試
CLIENT_DATA_DIR=/home/aixin/data/fastdfs/client
# tracker服務器的ip
TRACKER_SERVER=192.168.1.158
```
**啟動Tracker Server的腳本**
```
startup.sh tracker
```
trackerd.log查看tracker的啟動日志,如果看到類似
```
aixin@DC-server1:~/data/fastdfs/tracker/logs$ more trackerd.log
[2016-07-28 14:31:09] INFO - FastDFS v5.05, base_path=/home/aixin/data/fastdfs/tracker, run_by_group=, run_by_user=, connect_timeout=30s, network_timeout=60s, port=22122, bind_addr=, max_connections=256, a
ccept_threads=1, work_threads=4, store_lookup=2, store_group=, store_server=0, store_path=0, reserved_storage_space=10.00%, download_server=0, allow_ip_count=-1, sync_log_buff_interval=10s, check_active_in
terval=120s, thread_stack_size=64 KB, storage_ip_changed_auto_adjust=1, storage_sync_file_max_delay=86400s, storage_sync_file_max_time=300s, use_trunk_file=0, slot_min_size=256, slot_max_size=16 MB, trunk_
file_size=64 MB, trunk_create_file_advance=0, trunk_create_file_time_base=02:00, trunk_create_file_interval=86400, trunk_create_file_space_threshold=20 GB, trunk_init_check_occupying=0, trunk_init_reload_f
rom_binlog=0, trunk_compress_binlog_min_interval=0, use_storage_id=0, id_type_in_filename=ip, storage_id_count=0, rotate_error_log=0, error_log_rotate_time=00:00, rotate_error_log_size=0, log_file_keep_day
s=0, store_slave_file_use_link=0, use_connection_pool=0, g_connection_pool_max_idle_time=3600s
[2016-07-28 14:31:09] INFO - local_host_ip_count: 5, 127.0.0.1 192.168.1.158 10.0.3.1 172.19.0.1 172.17.0.1
```
恭喜你,tracker server已經啟動成功!
### 2.3.2配置及啟動Storage Server
**自動配置執行腳本**
```
storage_setup.sh
```
此腳本中做了以下幾件事情:
* /etc/fdfs/storage.conf的文件參數設置
* 編譯nginx + fastdfs-nginx-module
* /etc/fdfs/mod_fastdfs.conf參數配置
另外,需要手工做一件事情,修改/etc/nginx/nginx.conf,修改以下部分.
```
server {
listen 8987; #這里改成和http.serverport一致的
server_name localhost;
#這里注釋掉
# location / {
# root html;
# index index.html index.htm;
# }
location /group1/M00 {
root /home/aixin/data/fastdfs/storage/data; #這里是storage的data存儲路徑
ngx_fastdfs_module;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
```
**啟動Storage Server的腳本**
```
startup.sh storage
```
storage.log查看storage服務器啟動日志,如果看到類似
```
mkdir data path: FE ...
mkdir data path: FF ...
data path: /home/aixin/data/fastdfs/storage/data, mkdir sub dir done.
[2016-07-30 13:33:50] INFO - file: storage_param_getter.c, line: 191, use_storage_id=0, id_type_in_filename=ip, storage_ip_changed_auto_adjust=1, store_path=0, reserved_storage_space=10.00%, use_trunk_file=0, slot_min_size=256, slot_max_size=16 MB, trunk_file_size=64 MB, trunk_create_file_advance=0, trunk_create_file_time_base=02:00, trunk_create_file_interval=86400, trunk_create_file_space_threshold=20 GB, trunk_init_check_occupying=0, trunk_init_reload_from_binlog=0, trunk_compress_binlog_min_interval=0, store_slave_file_use_link=0
[2016-07-30 13:33:50] INFO - file: storage_func.c, line: 254, tracker_client_ip: 192.168.1.60, my_server_id_str: 192.168.1.60, g_server_id_in_filename: 1006741696
[2016-07-30 13:33:51] INFO - local_host_ip_count: 4, 127.0.0.1 192.168.1.60 172.18.0.1 172.17.0.1
[2016-07-30 13:33:51] INFO - file: tracker_client_thread.c, line: 310, successfully connect to tracker server 192.168.1.158:22122, as a tracker client, my ip is 192.168.1.60
[2016-07-30 13:34:21] INFO - file: tracker_client_thread.c, line: 1235, tracker server 192.168.1.158:22122, set tracker leader: 192.168.1.158:22122
[2016-07-30 13:53:51] INFO - file: storage_sync.c, line: 2698, successfully connect to storage server 192.168.1.24:23000
[2016-07-30 13:54:21] INFO - file: storage_sync.c, line: 2698, successfully connect to storage server 192.168.1.24:23000
```
恭喜你,storage server已經啟動成功!
## 多tracker配置
如果需要啟動多個tracker,可以在下面的文件,配置tracker_server,多行
./client.conf:tracker_server=192.168.2.26:22122
./mod_fastdfs.conf:tracker_server=192.168.2.26:22122
./storage.conf:tracker_server=192.168.2.26:22122
## 3.使用命令行操作文件
FastDFS安裝包中,自帶了客戶端程序,通過程序可以進行文件上傳。在使用這個客戶端程序之前,首先需要配置client.conf,然后再進行文件上傳及下載。
> 前提,上傳下載測試,需要在tracker節點上執行。因為在tracker_setup.sh腳本里面自動化做了client的配置.
### 3.1上傳文件
```
# fdfs_upload_file /etc/fdfs/client.conf <被上傳的文件>
$ fdfs_upload_file /etc/fdfs/client.conf ./nohup.out
group1/M00/00/00/wKgBGFecR5uAMDDeAAAAAAAAAAA698.out
```
### 3.2 查看fastdfs文件系統信息
```
$ fdfs_file_info /etc/fdfs/client.conf group1/M00/00/00/wKgBGFecR5uAMDDeAAAAAAAAAAA698.out
source storage id: 0
source ip address: 192.168.1.24
file create timestamp: 2016-07-30 14:22:19
file size: 0
file crc32: 0 (0x00000000)
```
### 3.3 下載文件
```
# fdfs_download_file /etc/fdfs/client.conf <要下載的文件>
$ fdfs_download_file /etc/fdfs/client.conf group1/M00/00/00/wKgBGFecR5uAMDDeAAAAAAAAAAA698.out
```
### 3.4 查看集群狀態
```
fdfs_monitor %FastDFS%/storage.conf
```
通過這個命令可以看到,如果有多個tracker,會發生變化!
## 4.使用JAVAAPI
### 調用API的上傳接口
通過Servlet得到InputStream、文件名稱和文件長度,然后通過調用FastDFS提供的Java API把文件上傳到FastDFS服務器。下段代碼中的getFileBuffer可參考本博客上一篇博文。(by Poechant)
```
/**
* Upload File to DFS.
* @param fileBuff, file to be uploaded.
* @param uploadFileName, the name of the file.
* @param fileLength, the length of the file.
* @return the file ID in DFS.
* @throws IOException
*/
public String uploadFile(InputStream inStream, String uploadFileName, long fileLength) throws IOException {
byte[] fileBuff = getFileBuffer(inStream, fileLength);
String fileId = "";
String fileExtName = "";
if (uploadFileName.contains(".")) {
fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
} else {
logger.warn("Fail to upload file, because the format of filename is illegal.");
return fileId;
}
//建立連接
TrackerClient tracker = new TrackerClient();
TrackerServer trackerServer = tracker.getConnection();
StorageServer storageServer = null;
StorageClient1 client = new StorageClient1(trackerServer, storageServer);
//設置元信息
NameValuePair[] metaList = new NameValuePair[3];
metaList[0] = new NameValuePair("fileName", uploadFileName);
metaList[1] = new NameValuePair("fileExtName", fileExtName);
metaList[2] = new NameValuePair("fileLength", String.valueOf(fileLength));
//上傳文件
try {
fileId = client.upload_file1(fileBuff, fileExtName, metaList);
} catch (Exception e) {
logger.warn("Upload file \"" + uploadFileName + "\"fails");
}
trackerServer.close();
return fileId;
}
```
## Ngnix的安裝與操作,這部分已經集成到腳本里面,只做了解即可。
在storage的節點上部署nginx相關組件,主要目的是提供http的訪問服務.
```
$sudo apt-get install nginx
```
### ubuntu安裝Nginx之后的文件結構大致為:
所有的配置文件都在/etc/nginx下,并且每個虛擬主機已經安排在了/etc/nginx/sites-available下
啟動程序文件在/usr/sbin/nginx
日志放在了/var/log/nginx中,分別是access.log和error.log
并已經在/etc/init.d/下創建了啟動腳本nginx
默認的虛擬主機的目錄設置在了/usr/share/nginx/www
### 配置Nginx反向代理(這一步通過haproxy也可以實現,通常我喜歡用haproxy來做)
```
user www-data;
worker_processes 4;
pid /run/nginx.pid;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
##
# nginx-naxsi config
##
# Uncomment it if you installed nginx-naxsi
##
#include /etc/nginx/naxsi_core.rules;
##
# nginx-passenger config
##
# Uncomment it if you installed nginx-passenger
##
#passenger_root /usr;
#passenger_ruby /usr/bin/ruby;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
#設置 group1 的服務器
upstream fdfs_group1 {
server 192.168.1.60:8987 weight=1 max_fails=2 fail_timeout=30s;
server 192.168.1.24:8987 weight=1 max_fails=2 fail_timeout=30s;
}
server {
#設置 group1 的反向代理參數
location /group1/M00 {
proxy_pass http://fdfs_group1;
}
}
}
```
### 測試nginx配置的正確性
```
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
```
如果出現如下錯誤,執行`sudo mkdir /var/run/nginx`
```
$ sudo nginx -t
ngx_http_fastdfs_set pid=8581
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: [emerg] open() "/var/run/nginx/nginx.pid" failed (2: No such file or directory)
nginx: configuration file /etc/nginx/nginx.conf test failed
```
### 啟動Nginx
```
$sudo /etc/init.d/nginx start
# 檢查是否啟動成功
$ sudo netstat -antp | grep nginx
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 29444/nginx
tcp6 0 0 :::80 :::* LISTEN 29444/nginx
```
### 單臺機器啟動多個storage
http://blog.csdn.net/zglwy/article/details/52783244
- 版權
- 博客主題
- 如何不去做運行3.5G-docker鏡像的工程師
- 預備主題
- FastDFS快速入門
- mysql定時創建月表
- SpringMVC-Restful
- Docker生態系統
- The Docker Ecosystem: An Introduction to Common Components
- docker監控指標
- 基于etcd服務發現的overlay跨多宿主機容器網絡
- etcd:從應用場景到實現原理的全方位解讀
- docker存儲驅動詳解
- 使用docker/engine-api操作docker
- 提升Docker安全性
- docker安全之用戶資源隔離
- marathon
- 開始
- 安裝mararhon
- 高可用模式
- 使用marathon
- 應用的部署
- 架構組件
- Dubbo與Zookeeper、SpringMVC整合和使用(負載均衡、容錯)
- Openstack架構解析
- haproxy
- Ubuntu系統安裝截圖
- mesos官方文檔
- 關于譯者
- mesos基礎
- Mesos架構
- 視頻與ppt
- 讓mesos跑起來
- 快速入門
- 配置
- Containerizer
- Docker Containerizer
- 監控
- 博客文章集
- 煮餃子與mesos之間妙不可言的關系
- linux運維
- 基礎篇
- 進階篇
- mysql
- Ubuntu14.04安裝mysql5.6
- MySQL 5.6 replicate原理與實踐
- mysql性能
- redis
- redis安裝及基礎知識
- redis數據結構
- redis命令
- redis數據持久化
- Redis主從復制
- redis集群
- 其他