為什么要使用分布式文件系統(tǒng)呢纠亚?
嗯,這個問題問的好筋夏,使用了它對我們有哪些好處蒂胞?帶著這個問題我們來往下看:
單機時代
初創(chuàng)時期由于時間緊迫,在各種資源有限的情況下条篷,通常就直接在項目目錄下建立靜態(tài)文件夾啤誊,用于用戶存放項目中的文件資源岳瞭。如果按不同類型再細分,可以在項目目錄下再建立不同的子目錄來區(qū)分蚊锹。例如: resources\static\file瞳筏、 resources\static\img等。
優(yōu)點:這樣做比較便利牡昆,項目直接引用就行姚炕,實現(xiàn)起來也簡單,無需任何復(fù)雜技術(shù)丢烘,保存數(shù)據(jù)庫記錄和訪問起來也很方便柱宦。
缺點:如果只是后臺系統(tǒng)的使用一般也不會有什么問題,但是作為一個前端網(wǎng)站使用的話就會存在弊端播瞳。一方面掸刊,文件和代碼耦合在一起,文件越多存放越混亂赢乓;另一方面忧侧,如果流量比較大,靜態(tài)文件訪問會占據(jù)一定的資源牌芋,影響正常業(yè)務(wù)進行蚓炬,不利于網(wǎng)站快速發(fā)展。
獨立文件服務(wù)器
隨著公司業(yè)務(wù)不斷發(fā)展躺屁,將代碼和文件放在同一服務(wù)器的弊端就會越來越明顯肯夏。為了解決上面的問題引入獨立圖片服務(wù)器,工作流程如下:項目上傳文件時犀暑,首先通過ftp或者ssh將文件上傳到圖片服務(wù)器的某個目錄下驯击,再通過ngnix或者apache來訪問此目錄下的文件,返回一個獨立域名的圖片URL地址耐亏,前端使用文件時就通過這個URL地址讀取徊都。
優(yōu)點:圖片訪問是很消耗服務(wù)器資源的(因為會涉及到操作系統(tǒng)的上下文切換和磁盤I/O操作),分離出來后苹熏,Web/App服務(wù)器可以更專注發(fā)揮動態(tài)處理的能力碟贾;獨立存儲币喧,更方便做擴容轨域、容災(zāi)和數(shù)據(jù)遷移;方便做圖片訪問請求的負載均衡杀餐,方便應(yīng)用各種緩存策略(HTTP Header干发、Proxy Cache等),也更加方便遷移到CDN史翘。
缺點:單機存在性能瓶頸枉长,容災(zāi)冀续、垂直擴展性稍差
分布式文件系統(tǒng)
通過獨立文件服務(wù)器可以解決一些問題,如果某天存儲文件的那臺服務(wù)突然down了怎么辦必峰?可能你會說洪唐,定時將文件系統(tǒng)備份,這臺down機的時候吼蚁,迅速切換到另一臺就OK了凭需,但是這樣處理需要人工來干預(yù)。另外肝匆,當存儲的文件超過100T的時候怎么辦粒蜈?單臺服務(wù)器的性能問題?這個時候我們就應(yīng)該考慮分布式文件系統(tǒng)了旗国。
業(yè)務(wù)繼續(xù)發(fā)展枯怖,單臺服務(wù)器存儲和響應(yīng)也很快到達了瓶頸,新的業(yè)務(wù)需要文件訪問具有高響應(yīng)性能曾、高可用性來支持系統(tǒng)度硝。分布式文件系統(tǒng),一般分為三塊內(nèi)容來配合借浊,服務(wù)的存儲塘淑、訪問的仲裁系統(tǒng),文件存儲系統(tǒng)蚂斤,文件的容災(zāi)系統(tǒng)來構(gòu)成存捺,仲裁系統(tǒng)相當于文件服務(wù)器的大腦,根據(jù)一定的算法來決定文件存儲的位置曙蒸,文件存儲系統(tǒng)負責保存文件捌治,容災(zāi)系統(tǒng)負責文件系統(tǒng)和自己的相互備份。
優(yōu)點:擴展能力: 毫無疑問纽窟,擴展能力是一個分布式文件系統(tǒng)最重要的特點肖油;高可用性: 在分布式文件系統(tǒng)中,高可用性包含兩層臂港,一是整個文件系統(tǒng)的可用性森枪,二是數(shù)據(jù)的完整和一致性;彈性存儲: 可以根據(jù)業(yè)務(wù)需要靈活地增加或縮減數(shù)據(jù)存儲以及增刪存儲池中的資源审孽,而不需要中斷系統(tǒng)運行
缺點:系統(tǒng)復(fù)雜度稍高县袱,需要更多服務(wù)器
FastDFS
毫無疑問FastDFS就屬于我們上面介紹的分布式文件系統(tǒng),下面我們來詳細了解一下:
什么是FastDFS
FastDFS是一個開源的輕量級分布式文件系統(tǒng)佑力。它解決了大數(shù)據(jù)量存儲和負載均衡等問題式散。特別適合以中小文件(建議范圍:4KB < file_size <500MB)為載體的在線服務(wù),如相冊網(wǎng)站打颤、視頻網(wǎng)站等等暴拄。在UC基于FastDFS開發(fā)向用戶提供了:網(wǎng)盤漓滔,社區(qū),廣告和應(yīng)用下載等業(yè)務(wù)的存儲服務(wù)乖篷。
FastDFS是一款開源的輕量級分布式文件系統(tǒng)純C實現(xiàn)响驴,支持Linux、FreeBSD等UNIX系統(tǒng)類google FS撕蔼,不是通用的文件系統(tǒng)踏施,只能通過專有API訪問,目前提供了C罕邀、Java和PHP API為互聯(lián)網(wǎng)應(yīng)用量身定做畅形,解決大容量文件存儲問題,追求高性能和高擴展性FastDFS可以看做是基于文件的key value pair存儲系統(tǒng)诉探,稱作分布式文件存儲服務(wù)更為合適日熬。
FastDFS相關(guān)概念
FastDFS服務(wù)端有三個角色:跟蹤服務(wù)器(tracker server)、存儲服務(wù)器(storage server)和客戶端(client)肾胯。
tracker server:跟蹤服務(wù)器竖席,主要做調(diào)度工作,起負載均衡的作用敬肚。在內(nèi)存中記錄集群中所有存儲組和存儲服務(wù)器的狀態(tài)信息毕荐,是客戶端和數(shù)據(jù)服務(wù)器交互的樞紐。相比GFS中的master更為精簡艳馒,不記錄文件索引信息憎亚,占用的內(nèi)存量很少。
Tracker是FastDFS的協(xié)調(diào)者弄慰,負責管理所有的storage server和group第美,每個storage在啟動后會連接Tracker,告知自己所屬的group等信息陆爽,并保持周期性的心跳什往,tracker根據(jù)storage的心跳信息,建立group==>[storage server list]的映射表慌闭。
Tracker需要管理的元信息很少别威,會全部存儲在內(nèi)存中驴剔;另外tracker上的元信息都是由storage匯報的信息生成的衫樊,本身不需要持久化任何數(shù)據(jù)飒赃,這樣使得tracker非常容易擴展臀栈,直接增加tracker機器即可擴展為tracker cluster來服務(wù),cluster里每個tracker之間是完全對等的盟蚣,所有的tracker都接受stroage的心跳信息马靠,生成元數(shù)據(jù)信息來提供讀寫服務(wù)。
storage server:存儲服務(wù)器(又稱:存儲節(jié)點或數(shù)據(jù)服務(wù)器)档泽,文件和文件屬性(meta data)都保存到存儲服務(wù)器上储笑。Storage server直接利用OS的文件系統(tǒng)調(diào)用管理文件。
Storage server(后簡稱storage)以組(卷焊虏,group或volume)為單位組織,一個group內(nèi)包含多臺storage機器瘟芝,數(shù)據(jù)互為備份敌呈,存儲空間以group內(nèi)容量最小的storage為準,所以建議group內(nèi)的多個storage盡量配置相同线脚,以免造成存儲空間的浪費晰绎。
以group為單位組織存儲能方便的進行應(yīng)用隔離、負載均衡、副本數(shù)定制(group內(nèi)storage server數(shù)量即為該group的副本數(shù)),比如將不同應(yīng)用數(shù)據(jù)存到不同的group就能隔離應(yīng)用數(shù)據(jù)河绽,同時還可根據(jù)應(yīng)用的訪問特性來將應(yīng)用分配到不同的group來做負載均衡苟跪;缺點是group的容量受單機存儲容量的限制,同時當group內(nèi)有機器壞掉時拨齐,數(shù)據(jù)恢復(fù)只能依賴group內(nèi)地其他機器,使得恢復(fù)時間會很長昨寞。
group內(nèi)每個storage的存儲依賴于本地文件系統(tǒng)瞻惋,storage可配置多個數(shù)據(jù)存儲目錄歼狼,比如有10塊磁盤羽峰,分別掛載在 /data/disk1-/data/disk10,則可將這10個目錄都配置為storage的數(shù)據(jù)存儲目錄咱筛。
storage接受到寫文件請求時溉愁,會根據(jù)配置好的規(guī)則(后面會介紹),選擇其中一個存儲目錄來存儲文件饲趋。為了避免單個目錄下的文件數(shù)太多投队,在storage第一次啟動時,會在每個數(shù)據(jù)存儲目錄里創(chuàng)建2級子目錄爵川,每級256個敷鸦,總共65536個文件,新寫的文件會以hash的方式被路由到其中某個子目錄下,然后將文件數(shù)據(jù)直接作為一個本地文件存儲到該目錄中扒披。
client:客戶端值依,作為業(yè)務(wù)請求的發(fā)起方,通過專有接口碟案,使用TCP/IP協(xié)議與跟蹤器服務(wù)器或存儲節(jié)點進行數(shù)據(jù)交互愿险。FastDFS向使用者提供基本文件訪問接口,比如upload价说、download辆亏、append、delete等鳖目,以客戶端庫的方式提供給用戶使用扮叨。
另外兩個概念:
group :組, 也可稱為卷领迈。 同組內(nèi)服務(wù)器上的文件是完全相同的 彻磁,同一組內(nèi)的storage server之間是對等的, 文件上傳狸捅、 刪除等操作可以在任意一臺storage server上進行 衷蜓。
meta data :文件相關(guān)屬性,鍵值對( Key Value Pair) 方式尘喝,如:width=1024,heigth=768 恍箭。
Tracker相當于FastDFS的大腦,不論是上傳還是下載都是通過tracker來分配資源瞧省;客戶端一般可以使用ngnix等靜態(tài)服務(wù)器來調(diào)用或者做一部分的緩存扯夭;存儲服務(wù)器內(nèi)部分為卷(或者叫做組),卷于卷之間是平行的關(guān)系鞍匾,可以根據(jù)資源的使用情況隨時增加交洗,卷內(nèi)服務(wù)器文件相互同步備份,以達到容災(zāi)的目的橡淑。
上傳機制
首先客戶端請求Tracker服務(wù)獲取到存儲服務(wù)器的ip地址和端口构拳,然后客戶端根據(jù)返回的IP地址和端口號請求上傳文件,存儲服務(wù)器接收到請求后生產(chǎn)文件梁棠,并且將文件內(nèi)容寫入磁盤并返回給客戶端file_id冕香、路徑信息坛善、文件名等信息,客戶端保存相關(guān)信息上傳完畢。
內(nèi)部機制如下:
1猫缭、選擇tracker server
當集群中不止一個tracker server時歼培,由于tracker之間是完全對等的關(guān)系毅往,客戶端在upload文件時可以任意選擇一個trakcer。 選擇存儲的group 當tracker接收到upload file的請求時漾稀,會為該文件分配一個可以存儲該文件的group,支持如下選擇group的規(guī)則:
Round robin建瘫,所有的group間輪詢
Specified group崭捍,指定某一個確定的group
Load balance,剩余存儲空間多多group優(yōu)先
2啰脚、選擇storage server
當選定group后殷蛇,tracker會在group內(nèi)選擇一個storage server給客戶端,支持如下選擇storage的規(guī)則:
Round robin橄浓,在group內(nèi)的所有storage間輪詢
First server ordered by ip粒梦,按ip排序
First server ordered by priority,按優(yōu)先級排序(優(yōu)先級在storage上配置)
3贮配、選擇storage path
當分配好storage server后谍倦,客戶端將向storage發(fā)送寫文件請求塞赂,storage將會為文件分配一個數(shù)據(jù)存儲目錄泪勒,支持如下規(guī)則:
Round robin,多個存儲目錄間輪詢
剩余存儲空間最多的優(yōu)先
4宴猾、生成Fileid
選定存儲目錄之后圆存,storage會為文件生一個Fileid,由storage server ip仇哆、文件創(chuàng)建時間沦辙、文件大小、文件crc32和一個隨機數(shù)拼接而成讹剔,然后將這個二進制串進行base64編碼油讯,轉(zhuǎn)換為可打印的字符串。 選擇兩級目錄 當選定存儲目錄之后延欠,storage會為文件分配一個fileid陌兑,每個存儲目錄下有兩級256*256的子目錄,storage會按文件fileid進行兩次hash(猜測)由捎,路由到其中一個子目錄兔综,然后將文件以fileid為文件名存儲到該子目錄下。
5狞玛、生成文件名
當文件存儲到某個子目錄后软驰,即認為該文件存儲成功,接下來會為該文件生成一個文件名心肪,文件名由group锭亏、存儲目錄、兩級子目錄硬鞍、fileid贰镣、文件后綴名(由客戶端指定呜象,主要用于區(qū)分文件類型)拼接而成。
下載機制
客戶端帶上文件名信息請求Tracker服務(wù)獲取到存儲服務(wù)器的ip地址和端口碑隆,然后客戶端根據(jù)返回的IP地址和端口號請求下載文件恭陡,存儲服務(wù)器接收到請求后返回文件給客戶端。
跟upload file一樣上煤,在download file時客戶端可以選擇任意tracker server休玩。tracker發(fā)送download請求給某個tracker,必須帶上文件名信息劫狠,tracke從文件名中解析出文件的group拴疤、大小、創(chuàng)建時間等信息独泞,然后為該請求選擇一個storage用來服務(wù)讀請求呐矾。由于group內(nèi)的文件同步時在后臺異步進行的,所以有可能出現(xiàn)在讀到時候懦砂,文件還沒有同步到某些storage server上蜒犯,為了盡量避免訪問到這樣的storage,tracker按照如下規(guī)則選擇group內(nèi)可讀的storage荞膘。
1罚随、該文件上傳到的源頭storage - 源頭storage只要存活著,肯定包含這個文件羽资,源頭的地址被編碼在文件名中淘菩。
2、文件創(chuàng)建時間戳==storage被同步到的時間戳 且(當前時間-文件創(chuàng)建時間戳) > 文件同步最大時間(如5分鐘) - 文件創(chuàng)建后屠升,認為經(jīng)過最大同步時間后潮改,肯定已經(jīng)同步到其他storage了。
3腹暖、文件創(chuàng)建時間戳 < storage被同步到的時間戳汇在。 - 同步時間戳之前的文件確定已經(jīng)同步了
4、(當前時間-文件創(chuàng)建時間戳) > 同步延遲閥值(如一天)微服。 - 經(jīng)過同步延遲閾值時間趾疚,認為文件肯定已經(jīng)同步了。
同步時間管理
當一個文件上傳成功后以蕴,客戶端馬上發(fā)起對該文件下載請求(或刪除請求)時糙麦,tracker是如何選定一個適用的存儲服務(wù)器呢? 其實每個存儲服務(wù)器都需要定時將自身的信息上報給tracker丛肮,這些信息就包括了本地同步時間(即赡磅,同步到的最新文件的時間戳)。而tracker根據(jù)各個存儲服務(wù)器的上報情況宝与,就能夠知道剛剛上傳的文件焚廊,在該存儲組中是否已完成了同步冶匹。同步信息上報如下圖:
寫文件時,客戶端將文件寫至group內(nèi)一個storage server即認為寫文件成功咆瘟,storage server寫完文件后嚼隘,會由后臺線程將文件同步至同group內(nèi)其他的storage server。
每個storage寫文件后袒餐,同時會寫一份binlog飞蛹,binlog里不包含文件數(shù)據(jù),只包含文件名等元信息灸眼,這份binlog用于后臺同步卧檐,storage會記錄向group內(nèi)其他storage同步的進度,以便重啟后能接上次的進度繼續(xù)同步焰宣;進度以時間戳的方式進行記錄霉囚,所以最好能保證集群內(nèi)所有server的時鐘保持同步。
storage的同步進度會作為元數(shù)據(jù)的一部分匯報到tracker上匕积,tracke在選擇讀storage的時候會以同步進度作為參考盈罐。 比如一個group內(nèi)有A、B闸天、C三個storage server暖呕,A向C同步到進度為T1 (T1以前寫的文件都已經(jīng)同步到B上了)斜做,B向C同步到時間戳為T2(T2 > T1)苞氮,tracker接收到這些同步進度信息時,就會進行整理瓤逼,將最小的那個做為C的同步時間戳笼吟,本例中T1即為C的同步時間戳為T1(即所有T1以前寫的數(shù)據(jù)都已經(jīng)同步到C上了);同理霸旗,根據(jù)上述規(guī)則贷帮,tracker會為A、B生成一個同步時間戳诱告。
精巧的文件ID-FID
說到下載就不得不提文件索引(又稱:FID)的精巧設(shè)計了撵枢。文件索引結(jié)構(gòu)如下圖,是客戶端上傳文件后存儲服務(wù)器返回給客戶端精居,用于以后訪問該文件的索引信息锄禽。文件索引信息包括:組名,虛擬磁盤路徑靴姿,數(shù)據(jù)兩級目錄沃但,文件名。
組名:文件上傳后所在的存儲組名稱佛吓,在文件上傳成功后有存儲服務(wù)器返回宵晚,需要客戶端自行保存垂攘。
虛擬磁盤路徑:存儲服務(wù)器配置的虛擬路徑,與磁盤選項store_path*對應(yīng)淤刃。
數(shù)據(jù)兩級目錄:存儲服務(wù)器在每個虛擬磁盤路徑下創(chuàng)建的兩級目錄晒他,用于存儲數(shù)據(jù)文件。
文件名:與文件上傳時不同逸贾。是由存儲服務(wù)器根據(jù)特定信息生成仪芒,文件名包含:源存儲服務(wù)器IP地址、文件創(chuàng)建時間戳耕陷、文件大小掂名、隨機數(shù)和文件拓展名等信息。
快速定位文件
知道FastDFS FID的組成后哟沫,我們來看看FastDFS是如何通過這個精巧的FID定位到需要訪問的文件饺蔑。
1、通過組名tracker能夠很快的定位到客戶端需要訪問的存儲服務(wù)器組嗜诀,并將選擇合適的存儲服務(wù)器提供客戶端訪問猾警;
2、存儲服務(wù)器根據(jù)“文件存儲虛擬磁盤路徑”和“數(shù)據(jù)文件兩級目錄”可以很快定位到文件所在目錄隆敢,并根據(jù)文件名找到客戶端需要訪問的文件发皿。
如何搭建FastDFS?參考我博客的這篇文章 (FastDFS 集群 安裝 配置:http:///fastdfs/2017/10/10/cluster-building-fastdfs.html)拂蝎,下圖為某用戶搭建的架構(gòu)示意圖