前言
傳統web站點部署大部分都是基於動靜分離的方式,靜態圖片存放於一台nfs存儲。但是這種架構有一個問題就是nfs存儲是單點,而且如果圖片量過大的時候,則nfs會成為性能短板。基於此可以采用分布式存儲的替代方案來替代nfs。
fastdfs不但可以存儲圖片,還可以存儲其他非結構化數據,其特性是可以存放海量的中小容量文件,而且性能和容量也不會成為瓶頸。
fastdfs架構
fastdfs基於如下兩個組件組成:
- tracker節點:存儲數據的元數據節點,此節點存放的是所有數據的元數據,如數據路徑,保存時間等信息。其信息是storage節點定時上傳到tracker節點的。
- storage節點:用於存放數據,storage節點的特點是兩個或多個節點為一組構成一個集群,類似於鏡像集群,數據只存放於兩台上任意一台,而另一台則自動從另一台同步數據,保證數據為雙份或多份。
架構圖:
fastdfs訪問步驟
上傳文件步驟
- 客戶端上傳文件請求,請求到到tracker節點;
- tracker節點基於內部算法選擇合適的storage節點發送給客戶端;
- 客戶端訪問指定的storage節點,然后保存到指定storage上;
訪問文件步驟 - 客戶端發起請求到tracker節點;
- tracker節點基於請求文件路徑可以得出文件存放在哪個storage節點上,因為請求文件名是包含路由信息的;
- tracker節點返回storage節點信息給client,client訪問storage節點拿到數據;
實驗配置
此處采用4台服務器進行配置,一台既為tracker節點,也為storage節點,其余3台都為storage節點。
下載源碼包制作成rpm包
安裝的話可以通過編譯安裝,不過此處因為要安裝4台服務器,所以我從github克隆下來源碼制作成源碼包進行分發安裝,提高效率。
- github克隆源碼包,因為fastdfs依賴於libevent,所以需要首先安裝libevent。
git clone https://github.com/happyfish100/libfastcommon.git
git clone https://github.com/happyfish100/fastdfs.git
- 修改下載先來的源碼包目錄名,加上版本號,版本號可以從目錄內的spec文件內查看到,並且制作成.tar.gz格式的包
mv libfastcommon libfastcommon-1.0.36
tar zcf libfastcommon libfastcommon-1.0.36.tar.gz libfastcommon libfastcommon-1.0.36/*
mv fastdfs fastdfs fastdfs fastdfs-5.0.11
tar zcf fastdfs-5.0.11.tar.gz fastdfs-5.0.11/*
- 安裝development tools編譯包,然后創建rpmbuild目錄,並把相應tar.gz包和spec文件拷貝到相應目錄進行rpm包制作
mkdir /root/rpmbuild/{SOURCES,SPECS}
mv libfastcommon libfastcommon-1.0.36.tar.gz /root/rpmbuild/SOURCES/
mv /root/libfastcommon-1.0.36/libfastcommon.spec /root/rpmbuild/SPECS/
mv fastdfs-5.0.11.tar.gz /root/rpmbuild/SOURCES/
mv /root/fastdfs-5.0.11/fastdfs.spec /rpm/rpmbuild/SPECS/
- 進入/root/rpmbuild/SPECS/目錄,進行rpm包制作
rpmbuild -bb libfastcommon.spec
rpmbuild -bb fastdfs.spec
-
制作完成之后會在rpmbuild目錄下生成一些目錄,如下:
其中RPMS目錄為制作好的源碼包
-
先安裝libfastcommon,因為fastdfs依賴它,然后再安裝fastdfs即可,然后拷貝到其他服務器進行安裝。
配置tracker節點
安裝完成之后會在/etc目錄下生成fdfs目錄,其中文件如下,其中為各種配置文件:
配置tracker.conf
base_path=/data/fastdfs #修改工作路徑為自己創建路徑
port=22122 #監聽端口為221222端口#
# the method of selecting group to upload files #指定文件上傳方式時上傳到哪個組#
# 0: round robin #輪詢選擇#
# 1: specify group #指定組#
# 2: load balance, select the max free space group to upload file #根據負載,哪個組剩余空間最大上傳到哪個組#
store_lookup=2
# which group to upload file #如果指定組,此處指定上傳到哪個組#
# when store_lookup set to 1, must set store_group to the group name
store_group=group2
# which storage server to upload file #上傳到組內哪個服務器#
# 0: round robin (default) #輪詢#
# 1: the first server order by ip address #ip小的服務器#
# 2: the first server order by priority (the minimal) #根據服務器優先級#
# Note: if use_trunk_file set to true, must set store_server to 1 or 2
store_server=0
# which path(means disk or mount point) of the storage server to upload file #上傳到服務器哪個硬盤#
# 0: round robin #輪詢#
# 2: load balance, select the max free space path to upload file #根據剩余空間#
store_path=0
# which storage server to download file #從組內哪個服務器請求數據#
# 0: round robin (default) #輪詢#
# 1: the source storage server which the current file uploaded to #最開始上傳到哪個服務器#
download_server=0
其他參數無需過多修改。
配置storage節點
- 四台服務器都需要配置storage節點,修改/etc/fdfs/storage.conf文件
group_name=group1 #指定組名,此處四台服務器,兩台為group1,兩台為group2,組成鏡像組#
port=23000 #指定工作端口#
store_path_count=1 #指定數據存儲路徑,如果有多個則按照實際數量寫,此處只有一個,則寫1#
store_path0=/data/storage #數據存儲路徑#
tracker_server=192.168.11.200:22122 #tracker節點ip和端口#
upload_priority=10 #數據上傳優先級#
- 配置完成啟動服務,tracker服務器需要啟動兩個服務,storage服務器只需要啟動storage服務:
service fdfs_storaged start
service fdfs_trackerd start
- storage服務器啟動之后會在指定存儲目錄創建多級文件夾,上傳的數據就是根據文件名hash值選擇相應文件夾進行存放的,如下:
上傳文件進行測試
- 上傳文件需要配置一個節點為client節點,此處配置tracker節點也為client節點,修改/etc/fdfs/client.conf配置文件,只需修改如下兩項即可:
base_path=/data/fastdfs #client日志存儲路徑#
tracker_server=192.168.11.200:22122 #tracker節點ip和端口#
- 上傳文件,下圖表示上傳成功,並顯示上傳之后的文件名:
- 可以通過fdfs_file_info命令查看文件存儲在哪里,下圖表示存儲在ip為203的節點上:
- 因為203和204服務器互為鏡像,所以204節點此時在相同的目錄下也會存在此文件。
編譯安裝nginx,通過http發布文件
- 在文件存在相應服務器編譯安裝nginx,需要給nginx打上fastdfs-nginx-module的補丁;
- 下載fastdfs-nginx-module,從https://github.com/happyfish100/fastdfs-nginx-module.git通過git clone即可克隆下來;
- 下載nginx源碼包進行編譯
./configure --prefix=/usr --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx/nginx.pid --lock-path=/var/lock/nginx.lock --user=nginx --group=nginx --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --http-client-body-temp-path=/var/tmp/nginx/client/ --http-proxy-temp-path=/var/tmp/nginx/proxy/ --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi --http-scgi-temp-path=/var/tmp/nginx/scgi --with-pcre --with-debug --add-module=../fastdfs-nginx-module/src/
- 在/usr/lib/systemd/system/路徑下創建nginx.service文件
[Unit]
Description=nginx server
after=network.target remote-fs.target nss-lookup.target
[service]
type=forking
pidfile=/run/nginx.pid
execstartpre=/usr/bin/rm -rf /run/nginx.pid
execstartpre=/usr/sbin/nginx -t
execstart=/usr/bin/nginx
execreload=/bin/kill -s HUP $MAINPID
killsignal=SIGQUIT
timeoutstopsec=5
killmode=process
privatetmp=true
[install]
wantedby=multi-user.target
- 把fastdfs-nginx-module中的mod_fastdfs.conf拷貝到/etc/fdfs/路徑下,並修改配置
base_path=/data/fastdfs #指定工作目錄#
tracker_server=192.168.11.200:22122 #指定tracker的ip地址#
group_name=group2 #指定當前服務器所屬組#
url_have_group_name = false #此項如果為true,則訪問文件需要在前面添加group信息,否則直接寫M00即可#
store_path0=/data/storage #指定存儲路徑#
log_filename=/data/fastdfs/logs/mod_fastdfs.log #指定log日志文件路徑#
- 編輯/etc/nginx/nginx.conf文件,添加如下內容
location /M00 {
alias /data/storage/data;
ngx_fastdfs_module;
}
- 啟動nginx,然后訪問指定文件,如group2/M00/00/00/wKgLy1ltrLCAZ4TOAA6q2wjnW8s371.jpg文件,可以看到訪問成功。
總結
現在文件只是能夠分布式上傳到不同的服務器節點了,但是如果要訪問的話還需要在本地安裝nginx,不過nginx需要打fastdfs-nginx-module補丁才能使用。編譯成功之后本地配置nginx的反向代理到指定的工作目錄即可通過nginx訪問到指定資源。不過生產環境中fastdfs中文件的上傳下載都是通過前端的程序來自動寫入和請求的。