摘要:?jiǎn)?dòng)后會(huì)連接到告知自己的信息,形成映射關(guān)聯(lián),并采用心跳機(jī)制保持狀態(tài)。存儲(chǔ)節(jié)點(diǎn)負(fù)責(zé)文件的存儲(chǔ),可以集群部署。一個(gè)卷組內(nèi)之間相互通信,文件進(jìn)行同步,保證卷內(nèi)完全一致,所以一個(gè)卷的容量以最小的服務(wù)器為準(zhǔn)。
簡(jiǎn)介
FastDFS是一個(gè)輕量級(jí)分布式文件系統(tǒng)。可以對(duì)文件進(jìn)行管理,功能包括:文件存儲(chǔ)、文件同步、文件訪問(文件上傳、文件下載)等,而且可以集群部署,有高可用保障。相應(yīng)的競(jìng)品有Ceph、TFS等。相比而言FastDFS對(duì)硬件的要求比較低,所以適合中小型公司。
概念FastDFS服務(wù)端由兩個(gè)重要部分組成:跟蹤器(Tracker)和存儲(chǔ)節(jié)點(diǎn)(Storage)。
Tracker主要做調(diào)度工作,在訪問上起負(fù)載均衡的作用。Tracker可以做集群部署,各個(gè)節(jié)點(diǎn)之間是平等的,客戶端請(qǐng)求時(shí)采用輪詢機(jī)制,某個(gè)Tracker不能提供服務(wù)時(shí)就換另一個(gè)。Storage啟動(dòng)后會(huì)連接到Tracker Server告知自己的Group信息,形成映射關(guān)聯(lián),并采用心跳機(jī)制保持狀態(tài)。
Storage存儲(chǔ)節(jié)點(diǎn)負(fù)責(zé)文件的存儲(chǔ),Storage可以集群部署。
Storage集群有以下特點(diǎn):
以組(Group)為單位(也有稱呼為卷 Volume的),集群的總?cè)萘繛樗薪M的集合。
一個(gè)卷(組)內(nèi)storage server之間相互通信,文件進(jìn)行同步,保證卷內(nèi)storage完全一致,所以一個(gè)卷的容量以最小的服務(wù)器為準(zhǔn)。不同的卷之間相互不通信。
當(dāng)某個(gè)卷的壓力較大時(shí)可以添加storage server(縱向擴(kuò)展),如果系統(tǒng)容量不夠可以添加卷(橫向擴(kuò)展)。
上傳流程此章節(jié)根據(jù)資料整理,可能隨著版本有所改變,這里只介紹大致的,以便了解整個(gè)運(yùn)作流程。如果需要深入研究,建議還是以官方文檔為標(biāo)準(zhǔn)。
一,客戶端請(qǐng)求會(huì)打到負(fù)載均衡層,到tracker server時(shí),由于每個(gè)server之間是對(duì)等的關(guān)系,所以可以任意選擇一個(gè)tracker server。
二,到storage層:tracker server接收到upload file請(qǐng)求時(shí),會(huì)為該請(qǐng)求分配一個(gè)可以存儲(chǔ)該文件的group。
分配group規(guī)則:
Round robin 輪詢
Specified group 指定一個(gè)group
Load balance 剩余存儲(chǔ)空間多的group優(yōu)先
三,確定group后,tracker會(huì)在group內(nèi)選擇一個(gè)storage server給客戶端。
在group內(nèi)選擇storage server時(shí)規(guī)則:
Round robin 輪詢
First server ordered by ip 按ip排序
First server ordered by priority,按優(yōu)先級(jí)排序(優(yōu)先級(jí)在storage上配置)
四,選擇storage path:當(dāng)分配好storage server后,客戶端向storage發(fā)送寫文件請(qǐng)求,storage將會(huì)為文件分配一個(gè)數(shù)據(jù)存儲(chǔ)目錄,支持規(guī)則如下:
round robin 輪詢
剩余存儲(chǔ)空間最多的優(yōu)先
五,生成File id:選定存儲(chǔ)目錄之后,storage會(huì)為文件生成一個(gè)File id。規(guī)則如下:
由storage server ip、文件創(chuàng)建時(shí)間、文件大小,文件crc32和一個(gè)隨機(jī)數(shù)拼接而成,然后將這個(gè)二進(jìn)制串進(jìn)程base64編碼,轉(zhuǎn)換為可打印的字符串。
六,選擇兩級(jí)目錄:每個(gè)存儲(chǔ)目錄下有兩級(jí)256 * 256的子目錄,storage會(huì)按文件Field進(jìn)行兩次hash,路由到其中的一個(gè)目錄,然后將文件以file id為文件名存儲(chǔ)到該子目錄下。
一個(gè)文件路徑最終由如下組成:組名/磁盤/目錄/文件名
七,客戶端upload file成功后,會(huì)拿到一個(gè)storage生成的文件名,接下來客戶端根據(jù)這個(gè)文件名即可訪問到該文件。
下載流程下載流程如下:
一,選擇tracker server:和upload file一樣,在download file時(shí)隨機(jī)選擇tracker server。
二,選擇group:tracker發(fā)送download請(qǐng)求給某個(gè)tracker,必須帶上文件名信息,tracker從文件名中解析出group、大小、創(chuàng)建時(shí)間等信息,根據(jù)group信息獲取對(duì)于的group。
三,選擇storage server:從group中選擇一個(gè)storage用來服務(wù)讀請(qǐng)求。由于group內(nèi)的文件同步時(shí)在后臺(tái)異步進(jìn)行的,所以有可能出現(xiàn)在讀到的時(shí)候,文件還沒有同步到某些storage server上,為了盡量避免反問道這樣的storage,tracker按照一定的規(guī)則選擇group內(nèi)可讀的storage。
文件HTTP預(yù)覽服務(wù)Storage還可以結(jié)合nginx的fastdfs-nginx-module提供http服務(wù),以實(shí)現(xiàn)圖片等預(yù)覽功能。
這個(gè)部分這里不做介紹,后續(xù)可能多帶帶寫篇文章,因?yàn)槲野l(fā)現(xiàn)對(duì)fastDFS集群提供http服務(wù)還是挺復(fù)雜,包括我下面找的docker鏡像都不完善,主要是規(guī)劃的問題,包括衍生的服務(wù),緩存,以及對(duì)圖片的處理(nginx+lua)這些,后續(xù)打算研究下,重新開源個(gè)docker構(gòu)建鏡像。
實(shí)戰(zhàn) 安裝、部署規(guī)劃FastDFS安裝方法網(wǎng)上有很多教程,這里不多講,我建議使用docker來運(yùn)行FastDFS,可以自己根據(jù)安裝步驟構(gòu)建自己的鏡像。然后在需要的機(jī)器直接運(yùn)行,后續(xù)擴(kuò)容也方便,再啟動(dòng)一個(gè)storage容器就可以了。
詳細(xì)版安裝推薦篇文章:https://segmentfault.com/a/11...
Docker集群搭建我這里從github上找的一個(gè)別人構(gòu)建好的鏡像,可以直接使用。地址:https://github.com/luhuiguo/f...
使用方法也很簡(jiǎn)單
# 啟動(dòng)一個(gè)tracker服務(wù)器 docker run -dti --network=host --name tracker -v /var/fdfs/tracker:/var/fdfs luhuiguo/fastdfs tracker # 啟動(dòng)storage0 docker run -dti --network=host --name storage0 -e TRACKER_SERVER=10.1.5.85:22122 -v /var/fdfs/storage0:/var/fdfs luhuiguo/fastdfs storage # 再啟動(dòng)一個(gè)storage1 docker run -dti --network=host --name storage1 -e TRACKER_SERVER=10.1.5.85:22122 -v /var/fdfs/storage1:/var/fdfs luhuiguo/fastdfs storage # 啟動(dòng)一個(gè)新組的storage docker run -dti --network=host --name storage2 -e TRACKER_SERVER=10.1.5.85:22122 -e GROUP_NAME=group2 -e PORT=22222 -v /var/fdfs/storage2:/var/fdfs luhuiguo/fastdfs storage部署注意點(diǎn)
1,原github地址上的usage介紹,啟動(dòng)storage0和storage1有一個(gè)參數(shù)錯(cuò)誤(多一個(gè)-e),以我上面發(fā)的命令為準(zhǔn)。
2,這里的TRACKER_SERVER注意改為你自己的,同一個(gè)網(wǎng)段內(nèi)網(wǎng)ip。
3,實(shí)際上這里docker容器之間還是同一個(gè)物理主機(jī)上部署的(根據(jù)network而言),雖然后續(xù)可以通過加硬盤,然后新建storage綁定到新加硬盤mount上,但是如果是大公司的生產(chǎn)環(huán)境還是推薦建立一個(gè)overlay網(wǎng)絡(luò),具體見:https://www.cnblogs.com/bigbe...,這樣可以直接擴(kuò)物理機(jī)集群了。另外這里也提供docker-compose方式啟動(dòng)服務(wù),實(shí)際也不推薦使用,因?yàn)閠racker和storage server以后必然是分開的,所以還是推薦單個(gè)docker容器保持靈活性。這里高級(jí)點(diǎn)可以用k8s進(jìn)行自動(dòng)擴(kuò)容(后續(xù)打算重新開源個(gè)鏡像)。
Java實(shí)踐 導(dǎo)入需要包這里使用官方的客戶端包:https://github.com/happyfish1...
# 下載源碼 git clone https://github.com/happyfish100/fastdfs-client-java.git cd fastdfs-client-java # 打jar包 mvn clean install # 輸出目錄 cd target # 導(dǎo)入到本地倉(cāng)庫(kù) 注意這里version根據(jù)實(shí)際生成的來 mvn install:install-file -DgroupId=org.csource -DartifactId=fastdfs-client-java -Dversion=1.27-SNAPSHOT -Dpackaging=jar -Dfile=fastdfs-client-java-1.27-SNAPSHOT.jar在pom.xml中引入依賴
添加Client配置org.csource fastdfs-client-java 1.27-SNAPSHOT commons-fileupload commons-fileupload 1.3.1 commons-io commons-io 2.2 org.apache.commons commons-lang3 3.1
在resource目錄下,添加conf/fdfs_client.conf配置文件
connect_timeout = 2 network_timeout = 30 charset = UTF-8 http.tracker_http_port = 80 http.anti_steal_token = no http.secret_key = FastDFS1234567890 tracker_server = 192.168.1.163:22122
測(cè)試時(shí)實(shí)際上只需關(guān)注tracker_server,并且改為你自己的tracker server
添加文件上傳beanapplicationContext.xml配置中添加文件上傳bean
建一個(gè)Client封裝
建一個(gè)簡(jiǎn)單的client封裝(勿作生產(chǎn)使用)
FastDFSClient.java
package com.rootrl.fastDFSDemo.utiles; import org.apache.commons.lang3.StringUtils; import org.csource.common.NameValuePair; import org.csource.fastdfs.*; import java.io.File; import java.io.IOException; import java.io.InputStream; public class FastDFSClient { private static StorageClient1 storageClient1 = null; static { try { // 獲取配置文件 String classPath = new File(FastDFSClient.class.getResource("/").getFile()).getCanonicalPath(); String CONF_FILENAME = classPath + File.separator + "conf" + File.separator + "fdfs_client.conf"; ClientGlobal.init(CONF_FILENAME); // 獲取觸發(fā)器 TrackerClient trackerClient = new TrackerClient(ClientGlobal.g_tracker_group); TrackerServer trackerServer = trackerClient.getConnection(); // 獲取存儲(chǔ)服務(wù)器 StorageServer storageServer = trackerClient.getStoreStorage(trackerServer); storageClient1 = new StorageClient1(trackerServer, storageServer); } catch (Exception e) { System.out.println(e); } } /** * 上傳文件 * @param fis 文件輸入流 * @param fileName 文件名稱 * @return */ public static String uploadFile(InputStream fis, String fileName) { try { NameValuePair[] meta_list = null; //將輸入流寫入file_buff數(shù)組 byte[] file_buff = null; if (fis != null) { int len = fis.available(); file_buff = new byte[len]; fis.read(file_buff); } String fileid = storageClient1.upload_file1(file_buff, getFileExt(fileName), meta_list); return fileid; } catch (Exception ex) { return null; } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { System.out.println(e); } } } } /** * 獲取文件后綴 * @param fileName * @return */ private static String getFileExt(String fileName) { if (StringUtils.isBlank(fileName) || !fileName.contains(".")) { return ""; } else { return fileName.substring(fileName.lastIndexOf(".") + 1); } } }建立控制器
然后建立一個(gè)File控制器,做測(cè)試用
FileController.java
package com.rootrl.fastDFSDemo.controller; import com.rootrl.fastDFSDemo.utiles.FastDFSClient; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; @Controller @RequestMapping("fastdfs") public class FileController { @RequestMapping(value = "upload") @ResponseBody public String uploadFileSample(@RequestParam MultipartFile file){ try { String fileId = FastDFSClient.uploadFile(file.getInputStream(), file.getOriginalFilename()); return fileId; } catch (Exception e) { System.out.println(e.getMessage()); return "error"; } } }
然后使用postman客戶端測(cè)試,url為:http://localhost:8080/fastdfs/upload.do(依據(jù)自己實(shí)際情況變更)
注意postman使用post請(qǐng)求,然后切換到body/form-data標(biāo)簽項(xiàng),添加一個(gè)Key為file,類型為file,然后value就可以上傳文件了。成功會(huì)返回文件id,類似:group1/M00/00/00/wKgBo1zjxnOAT-k1AAAoMlb3hzU996.png
參考https://blog.csdn.net/yxflove...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/27848.html
摘要:?jiǎn)?dòng)后會(huì)連接到告知自己的信息,形成映射關(guān)聯(lián),并采用心跳機(jī)制保持狀態(tài)。存儲(chǔ)節(jié)點(diǎn)負(fù)責(zé)文件的存儲(chǔ),可以集群部署。一個(gè)卷組內(nèi)之間相互通信,文件進(jìn)行同步,保證卷內(nèi)完全一致,所以一個(gè)卷的容量以最小的服務(wù)器為準(zhǔn)。 簡(jiǎn)介 FastDFS是一個(gè)輕量級(jí)分布式文件系統(tǒng)。可以對(duì)文件進(jìn)行管理,功能包括:文件存儲(chǔ)、文件同步、文件訪問(文件上傳、文件下載)等,而且可以集群部署,有高可用保障。相應(yīng)的競(jìng)品有Ceph、T...
摘要:而調(diào)用后端服務(wù)就應(yīng)用了的高級(jí)特分布式配置管理平臺(tái)后端掘金輕量的分布式配置管理平臺(tái)。關(guān)于網(wǎng)絡(luò)深度解讀后端掘金什么是網(wǎng)絡(luò)呢總的來說,網(wǎng)絡(luò)中的容器們可以相互通信,網(wǎng)絡(luò)外的又訪問不了這些容器。 在 Java 路上,我看過的一些書、源碼和框架(持續(xù)更新) - 后端 - 掘金簡(jiǎn)書 占小狼轉(zhuǎn)載請(qǐng)注明原創(chuàng)出處,謝謝!如果讀完覺得有收獲的話,歡迎點(diǎn)贊加關(guān)注 物有本末,事有終始,知所先后,則近道矣 ......
摘要:概述用久了,深受其約定大于配置的便利性毒害之后,我想回歸到時(shí)代,看看開發(fā)模式中用戶是如何參與的。備注當(dāng)然本文所使用的全是非注解的配置方法,即需要在中進(jìn)行配置并且需要遵循各種實(shí)現(xiàn)原則。而更加通用主流的基于注解的配置方法將在后續(xù)文章中詳述。 showImg(https://segmentfault.com/img/remote/1460000015244684); 概述 用久了Sprin...
摘要:多線程編程這篇文章分析了多線程的優(yōu)缺點(diǎn),如何創(chuàng)建多線程,分享了線程安全和線程通信線程池等等一些知識(shí)。 中間件技術(shù)入門教程 中間件技術(shù)入門教程,本博客介紹了 ESB、MQ、JMS 的一些知識(shí)... SpringBoot 多數(shù)據(jù)源 SpringBoot 使用主從數(shù)據(jù)源 簡(jiǎn)易的后臺(tái)管理權(quán)限設(shè)計(jì) 從零開始搭建自己權(quán)限管理框架 Docker 多步構(gòu)建更小的 Java 鏡像 Docker Jav...
摘要:概述約定大于配置的功力讓我們?nèi)玢宕猴L(fēng),在我之前寫的文章從到也對(duì)比過和這兩個(gè)框架,不過最終以超高的代碼信噪比和易上手性讓我們映像頗深。至于,我想在非時(shí)代大家應(yīng)該不陌生吧,作用是配置容器,也即形式的容器的配置類所使用。 showImg(https://segmentfault.com/img/remote/1460000015822144); 概 述 SpringBoot 約定大于配置...
閱讀 3228·2021-11-15 11:37
閱讀 2449·2021-09-29 09:48
閱讀 3813·2021-09-22 15:55
閱讀 3014·2021-09-22 10:02
閱讀 2636·2021-08-25 09:40
閱讀 3225·2021-08-03 14:03
閱讀 1691·2019-08-29 13:11
閱讀 1570·2019-08-29 12:49