FastDFS介紹(非原創(chuàng))

文章大綱

一尾膊、FastDFS介紹
二媳危、FastDFS安裝與啟動(Linux系統(tǒng))
三、Java客戶端上傳圖片
四冈敛、參考文章

一待笑、FastDFS介紹

1. 什么是FastDFS

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

2. FastDFS架構(gòu)

FastDFS架構(gòu)包括 Tracker server和Storage server
??Tracker server作用是對Storage server進行負載均衡和調(diào)度,在文件上傳時會直接請求Tracker server丐吓,然后Tracker server可以根據(jù)一些策略找到Storage server來提供文件上傳服務(wù)浅悉。所以可以將tracker稱為追蹤服務(wù)器或調(diào)度服務(wù)器。
??Storage server作用是文件存儲券犁,客戶端上傳的文件最終存儲在Storage服務(wù)器上术健,Storage server沒有實現(xiàn)自己的文件系統(tǒng)而是利用操作系統(tǒng)的文件系統(tǒng)來管理文件≌吵模可以將storage稱為存儲服務(wù)器荞估。
??具體架構(gòu)如下圖:

2.1 Tracker 集群
FastDFS集群中的Tracker server可以有多臺咳促,Tracker server之間是相互平等關(guān)系同時提供服務(wù),Tracker server不存在單點故障勘伺」蚋梗客戶端請求Tracker server采用輪詢方式,如果請求的tracker無法提供服務(wù)則換另一個tracker飞醉。

2.2 Storage集群
??Storage集群采用了分組存儲方式冲茸。storage集群由一個或多個組構(gòu)成,一個組由一臺或多臺存儲服務(wù)器組成缅帘,組內(nèi)的Storage server之間是平等關(guān)系轴术,不同組的Storage server之間不會相互通信,同組內(nèi)的Storage server之間會相互連接進行文件同步钦无,從而保證同組內(nèi)每個storage上的文件完全一致的逗栽。一個組的存儲容量為該組內(nèi)存儲服務(wù)器容量最小的那個,集群存儲總?cè)萘繛榧褐兴薪M的存儲容量之和铃诬,由此可見組內(nèi)存儲服務(wù)器的軟硬件配置最好是一致的祭陷。
??采用分組存儲方式的好處是靈活、可控性較強趣席。比如上傳文件時,可以由客戶端直接指定上傳到的組也可以由tracker進行調(diào)度選擇醇蝴。一個分組的存儲服務(wù)器訪問壓力較大時宣肚,可以在該組增加存儲服務(wù)器來擴充服務(wù)能力(縱向擴容)。當(dāng)系統(tǒng)容量不足時悠栓,可以增加組來擴充存儲容量(橫向擴容)霉涨。

2.3 文件上傳流程

客戶端上傳文件后存儲服務(wù)器將文件ID返回給客戶端,此文件ID用于以后訪問該文件的索引信息惭适。文件索引信息包括:組名笙瑟,虛擬磁盤路徑,數(shù)據(jù)兩級目錄癞志,文件名往枷。

上傳說明
(1)組名:文件上傳后所在的storage組名稱,在文件上傳成功后有storage服務(wù)器返回凄杯,需要客戶端自行保存错洁。
(2)虛擬磁盤路徑:storage配置的虛擬路徑,與磁盤選項store_path*對應(yīng)戒突。如果配置了store_path0則是M00屯碴,如果配置了store_path1則是M01,以此類推膊存。
(3)數(shù)據(jù)兩級目錄:storage服務(wù)器在每個虛擬磁盤路徑下創(chuàng)建的兩級目錄导而,用于存儲數(shù)據(jù)文件忱叭。
(4)文件名:與文件上傳時不同。是由存儲服務(wù)器根據(jù)特定信息生成今艺,文件名包含:源存儲服務(wù)器IP地址窑多、文件創(chuàng)建時間戳、文件大小洼滚、隨機數(shù)和文件拓展名等信息埂息。

2.4 文件下載流程

tracker根據(jù)請求的文件路徑即文件ID 來快速定義文件。
比如請求下邊的文件:

下載說明
(1)通過組名tracker能夠很快的定位到客戶端需要訪問的存儲服務(wù)器組是group1遥巴,并選擇合適的存儲服務(wù)器提供客戶端訪問千康。
(2)存儲服務(wù)器根據(jù)“文件存儲虛擬磁盤路徑”和“數(shù)據(jù)文件兩級目錄”可以很快定位到文件所在目錄,并根據(jù)文件名找到客戶端需要訪問的文件铲掐。

二拾弃、FastDFS安裝與啟動(Linux系統(tǒng))

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)執(zhí)行編譯:./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)執(zhí)行編譯:./make.sh
(5)安裝:./make.sh install

(6)查看可執(zhí)行命令:ls -la /usr/bin/fdfs*

3. 配置Tracker服務(wù)

(1)進入/etc/fdfs目錄,有三個.sample后綴的文件(自動生成的fdfs模板配置文件)摆霉,通過cp命令拷貝tracker.conf.sample豪椿,刪除.sample后綴作為正式文件:

(2)編輯tracker.conf:vi tracker.conf,修改相關(guān)參數(shù)

base_path=/home/mm/fastdfs/tracker  #tracker存儲data和log的跟路徑携栋,必須提前創(chuàng)建好
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服務(wù)

(1)進入/etc/fdfs目錄婉支,有cp命令拷貝storage.conf.sample鸯隅,刪除.sample后綴作為正式文件;
(2)編輯storage.conf:vi storage.conf,修改相關(guān)參數(shù):

base_path=/home/mm/fastdfs/storage   #storage存儲data和log的跟路徑向挖,必須提前創(chuàng)建好
port=23000  #storge默認23000蝌以,同一個組的storage端口號必須一致
group_name=group1  #默認組名,根據(jù)實際情況修改
store_path_count=1  #存儲路徑個數(shù)何之,需要和store_path個數(shù)匹配
store_path0=/home/mm/fastdfs/storage  #如果為空跟畅,則使用base_path
tracker_server=10.122.149.211:22122 #配置該storage監(jiān)聽的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日志:發(fā)現(xiàn)已經(jīng)開始選舉溶推,并且作為唯一的一個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

  1. 啟動悼潭、停止:
cd /usr/local/nginx/sbin/
./nginx 
./nginx -s stop #此方式相當(dāng)于先查出nginx進程id再使用kill命令強制殺掉進程
./nginx -s quit #此方式停止步驟是待nginx進程處理任務(wù)完畢進行停止
./nginx -s reload

(11)驗證啟動狀態(tài):wget "http://127.0.0.1"

(12)查看此時的nginx版本:發(fā)現(xiàn)fastdfs模塊已經(jīng)安裝好了

(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  #存儲路徑個數(shù)舰褪,需要和store_path個數(shù)匹配
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相關(guān)配置:

base_path=/home/mm/fastdfs/tracker //tracker服務(wù)器文件路徑
tracker_server=10.122.149.211:22122 //tracker服務(wù)器IP地址和端口號
http.tracker_server_port=80 # tracker服務(wù)器的http端口號略就,必須和tracker的設(shè)置對應(yīng)起來

(3)新建一個測試文檔1.txt捎迫,內(nèi)容為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)查看結(jié)果,進入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)查看結(jié)果

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)查看結(jié)果表牢,進入storage的data目錄文件不存在窄绒,通過wget再次獲取404:

溫馨提示:現(xiàn)在FastDFS的安裝好像不支持Windows

三、Java客戶端上傳圖片

1. 新建maven項目

2. pom.xml文件添加相關(guān)依賴

<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. 添加配置文件內(nèi)容

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服務(wù)器地址
tracker_server = 192.168.105.133:22122
tracker_server = 192.168.105.134:22122

4. 創(chuàng)建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;
    // 聲明跟蹤器服務(wù)對象
    TrackerServer trackerServer = null;
    // 聲明存儲器服務(wù)對象
    StorageServer storageServer = null;

    // 文件上傳
    @Test
    public void testUpload() {
        try {
            // 初始化配置文件
            ClientGlobal.init("fdfs_client.conf");
            // 創(chuàng)建跟蹤器客戶端對象
            trackerClient = new TrackerClient();
            // 獲取跟蹤器連接
            trackerServer = trackerClient.getConnection();
            // 獲取存儲器客戶端對象
            storageClient1 = new StorageClient1(trackerServer, storageServer);
            // 上傳文件彰导,返回文件標(biāo)識
            String index = storageClient1.upload_file1(local, null, null);
            // 查看標(biāo)識
            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);
            // 根據(jù)文件標(biāo)識下載文件
            byte[] by = storageClient1.download_file1("group1/M00/00/00/wKhphVrxnTeAPEznAANfM1yHJic535.txt");
            // 將數(shù)據(jù)寫入輸出流
            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);
            // 根據(jù)文件標(biāo)識刪除文件,返回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);
            // 根據(jù)文件標(biāo)識獲取文件信息
            FileInfo fileInfo = storageClient1.get_file_info1("group1/M00/00/00/wKhphVry2QmAXgH2AANfM1yHJic724.txt");
            // 文件IP地址
            System.out.println(fileInfo.getSourceIpAddr());
            // 文件大小
            System.out.println(fileInfo.getFileSize());
            // 創(chuàng)建時間
            System.out.println(fileInfo.getCreateTimestamp());
            // 錯誤校驗碼
            System.out.println(fileInfo.getCrc32());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (MyException e) {
            e.printStackTrace();
        }
    }
}

四敲茄、參考文章

  1. https://www.cnblogs.com/handsomeye/p/9451568.html
  2. https://blog.csdn.net/xy_2017chasedream/article/details/80258526
  3. http://yun.itheima.com/course?hm
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末位谋,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子堰燎,更是在濱河造成了極大的恐慌掏父,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件秆剪,死亡現(xiàn)場離奇詭異赊淑,居然都是意外死亡,警方通過查閱死者的電腦和手機仅讽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門陶缺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人何什,你說我怎么就攤上這事组哩。” “怎么了处渣?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蛛砰。 經(jīng)常有香客問我罐栈,道長,這世上最難降的妖魔是什么泥畅? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任荠诬,我火速辦了婚禮,結(jié)果婚禮上位仁,老公的妹妹穿的比我還像新娘柑贞。我一直安慰自己,他們只是感情好聂抢,可當(dāng)我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布钧嘶。 她就那樣靜靜地躺著,像睡著了一般琳疏。 火紅的嫁衣襯著肌膚如雪有决。 梳的紋絲不亂的頭發(fā)上闸拿,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天,我揣著相機與錄音书幕,去河邊找鬼新荤。 笑死,一個胖子當(dāng)著我的面吹牛台汇,可吹牛的內(nèi)容都是我干的苛骨。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼苟呐,長吁一口氣:“原來是場噩夢啊……” “哼痒芝!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起掠抬,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤吼野,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后两波,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瞳步,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年腰奋,在試婚紗的時候發(fā)現(xiàn)自己被綠了单起。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡劣坊,死狀恐怖嘀倒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情局冰,我是刑警寧澤测蘑,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站康二,受9級特大地震影響碳胳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜沫勿,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一挨约、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧产雹,春花似錦诫惭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至时甚,卻和暖如春隘弊,著一層夾襖步出監(jiān)牢的瞬間哈踱,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工梨熙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留开镣,地道東北人。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓咽扇,卻偏偏與公主長得像邪财,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子质欲,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容