為什么要使用分布式文件系統(tǒng)呢?
嗯佳晶,這個(gè)問(wèn)題問(wèn)的好桅狠,使用了它對(duì)我們有哪些好處?帶著這個(gè)問(wèn)題我們來(lái)往下看:
單機(jī)時(shí)代
初創(chuàng)時(shí)期由于時(shí)間緊迫轿秧,在各種資源有限的情況下中跌,通常就直接在項(xiàng)目目錄下建立靜態(tài)文件夾,用于用戶存放項(xiàng)目中的文件資源菇篡。如果按不同類型再細(xì)分漩符,可以在項(xiàng)目目錄下再建立不同的子目錄來(lái)區(qū)分。例如: resources\static\file驱还、 resources\static\img等嗜暴。
優(yōu)點(diǎn):這樣做比較便利凸克,項(xiàng)目直接引用就行,實(shí)現(xiàn)起來(lái)也簡(jiǎn)單闷沥,無(wú)需任何復(fù)雜技術(shù)萎战,保存數(shù)據(jù)庫(kù)記錄和訪問(wèn)起來(lái)也很方便。
缺點(diǎn):如果只是后臺(tái)系統(tǒng)的使用一般也不會(huì)有什么問(wèn)題狐赡,但是作為一個(gè)前端網(wǎng)站使用的話就會(huì)存在弊端撞鹉。一方面,文件和代碼耦合在一起颖侄,文件越多存放越混亂鸟雏;另一方面,如果流量比較大览祖,靜態(tài)文件訪問(wèn)會(huì)占據(jù)一定的資源孝鹊,影響正常業(yè)務(wù)進(jìn)行,不利于網(wǎng)站快速發(fā)展展蒂。
獨(dú)立文件服務(wù)器
隨著公司業(yè)務(wù)不斷發(fā)展又活,將代碼和文件放在同一服務(wù)器的弊端就會(huì)越來(lái)越明顯。為了解決上面的問(wèn)題引入獨(dú)立圖片服務(wù)器锰悼,工作流程如下:項(xiàng)目上傳文件時(shí)柳骄,首先通過(guò)ftp或者ssh將文件上傳到圖片服務(wù)器的某個(gè)目錄下,再通過(guò)ngnix或者apache來(lái)訪問(wèn)此目錄下的文件箕般,返回一個(gè)獨(dú)立域名的圖片URL地址耐薯,前端使用文件時(shí)就通過(guò)這個(gè)URL地址讀取。
優(yōu)點(diǎn):圖片訪問(wèn)是很消耗服務(wù)器資源的(因?yàn)闀?huì)涉及到操作系統(tǒng)的上下文切換和磁盤I/O操作)丝里,分離出來(lái)后曲初,Web/App服務(wù)器可以更專注發(fā)揮動(dòng)態(tài)處理的能力;獨(dú)立存儲(chǔ)杯聚,更方便做擴(kuò)容臼婆、容災(zāi)和數(shù)據(jù)遷移;方便做圖片訪問(wèn)請(qǐng)求的負(fù)載均衡幌绍,方便應(yīng)用各種緩存策略(HTTP Header颁褂、Proxy Cache等),也更加方便遷移到CDN傀广。
缺點(diǎn):?jiǎn)螜C(jī)存在性能瓶頸痢虹,容災(zāi)、垂直擴(kuò)展性稍差
分布式文件系統(tǒng)
通過(guò)獨(dú)立文件服務(wù)器可以解決一些問(wèn)題主儡,如果某天存儲(chǔ)文件的那臺(tái)服務(wù)突然down了怎么辦奖唯?可能你會(huì)說(shuō),定時(shí)將文件系統(tǒng)備份糜值,這臺(tái)down機(jī)的時(shí)候丰捷,迅速切換到另一臺(tái)就OK了坯墨,但是這樣處理需要人工來(lái)干預(yù)。另外病往,當(dāng)存儲(chǔ)的文件超過(guò)100T的時(shí)候怎么辦捣染?單臺(tái)服務(wù)器的性能問(wèn)題?這個(gè)時(shí)候我們就應(yīng)該考慮分布式文件系統(tǒng)了停巷。
業(yè)務(wù)繼續(xù)發(fā)展耍攘,單臺(tái)服務(wù)器存儲(chǔ)和響應(yīng)也很快到達(dá)了瓶頸,新的業(yè)務(wù)需要文件訪問(wèn)具有高響應(yīng)性畔勤、高可用性來(lái)支持系統(tǒng)蕾各。分布式文件系統(tǒng),一般分為三塊內(nèi)容來(lái)配合庆揪,服務(wù)的存儲(chǔ)式曲、訪問(wèn)的仲裁系統(tǒng),文件存儲(chǔ)系統(tǒng)缸榛,文件的容災(zāi)系統(tǒng)來(lái)構(gòu)成吝羞,仲裁系統(tǒng)相當(dāng)于文件服務(wù)器的大腦,根據(jù)一定的算法來(lái)決定文件存儲(chǔ)的位置内颗,文件存儲(chǔ)系統(tǒng)負(fù)責(zé)保存文件钧排,容災(zāi)系統(tǒng)負(fù)責(zé)文件系統(tǒng)和自己的相互備份。
優(yōu)點(diǎn):擴(kuò)展能力: 毫無(wú)疑問(wèn)均澳,擴(kuò)展能力是一個(gè)分布式文件系統(tǒng)最重要的特點(diǎn)恨溜;高可用性: 在分布式文件系統(tǒng)中,高可用性包含兩層负懦,一是整個(gè)文件系統(tǒng)的可用性筒捺,二是數(shù)據(jù)的完整和一致性柏腻;彈性存儲(chǔ): 可以根據(jù)業(yè)務(wù)需要靈活地增加或縮減數(shù)據(jù)存儲(chǔ)以及增刪存儲(chǔ)池中的資源纸厉,而不需要中斷系統(tǒng)運(yùn)行
缺點(diǎn):系統(tǒng)復(fù)雜度稍高,需要更多服務(wù)器
FastDFS
毫無(wú)疑問(wèn)FastDFS就屬于我們上面介紹的分布式文件系統(tǒng)五嫂,下面我們來(lái)詳細(xì)了解一下:
什么是FastDFS
FastDFS是一個(gè)開(kāi)源的輕量級(jí)分布式文件系統(tǒng)颗品。它解決了大數(shù)據(jù)量存儲(chǔ)和負(fù)載均衡等問(wèn)題。特別適合以中小文件(建議范圍:4KB < file_size <500MB)為載體的在線服務(wù)沃缘,如相冊(cè)網(wǎng)站躯枢、視頻網(wǎng)站等等。在UC基于FastDFS開(kāi)發(fā)向用戶提供了:網(wǎng)盤槐臀,社區(qū)锄蹂,廣告和應(yīng)用下載等業(yè)務(wù)的存儲(chǔ)服務(wù)。
FastDFS是一款開(kāi)源的輕量級(jí)分布式文件系統(tǒng)純C實(shí)現(xiàn)水慨,支持Linux得糜、FreeBSD等UNIX系統(tǒng)類google FS敬扛,不是通用的文件系統(tǒng),只能通過(guò)專有API訪問(wèn)朝抖,目前提供了C啥箭、Java和PHP API為互聯(lián)網(wǎng)應(yīng)用量身定做,解決大容量文件存儲(chǔ)問(wèn)題治宣,追求高性能和高擴(kuò)展性FastDFS可以看做是基于文件的key value pair存儲(chǔ)系統(tǒng)急侥,稱作分布式文件存儲(chǔ)服務(wù)更為合適。
FastDFS相關(guān)概念
FastDFS服務(wù)端有三個(gè)角色:跟蹤服務(wù)器(tracker server)侮邀、存儲(chǔ)服務(wù)器(storage server)和客戶端(client)坏怪。
tracker server:跟蹤服務(wù)器,主要做調(diào)度工作豌拙,起負(fù)載均衡的作用陕悬。在內(nèi)存中記錄集群中所有存儲(chǔ)組和存儲(chǔ)服務(wù)器的狀態(tài)信息,是客戶端和數(shù)據(jù)服務(wù)器交互的樞紐按傅。相比GFS中的master更為精簡(jiǎn)捉超,不記錄文件索引信息,占用的內(nèi)存量很少唯绍。
Tracker是FastDFS的協(xié)調(diào)者拼岳,負(fù)責(zé)管理所有的storage server和group,每個(gè)storage在啟動(dòng)后會(huì)連接Tracker况芒,告知自己所屬的group等信息惜纸,并保持周期性的心跳,tracker根據(jù)storage的心跳信息绝骚,建立group==>[storage server list]的映射表耐版。
Tracker需要管理的元信息很少,會(huì)全部存儲(chǔ)在內(nèi)存中压汪;另外tracker上的元信息都是由storage匯報(bào)的信息生成的粪牲,本身不需要持久化任何數(shù)據(jù),這樣使得tracker非常容易擴(kuò)展止剖,直接增加tracker機(jī)器即可擴(kuò)展為tracker cluster來(lái)服務(wù)腺阳,cluster里每個(gè)tracker之間是完全對(duì)等的,所有的tracker都接受stroage的心跳信息穿香,生成元數(shù)據(jù)信息來(lái)提供讀寫(xiě)服務(wù)亭引。
storage server:存儲(chǔ)服務(wù)器(又稱:存儲(chǔ)節(jié)點(diǎn)或數(shù)據(jù)服務(wù)器),文件和文件屬性(meta data)都保存到存儲(chǔ)服務(wù)器上皮获。Storage server直接利用OS的文件系統(tǒng)調(diào)用管理文件焙蚓。
Storage server(后簡(jiǎn)稱storage)以組(卷,group或volume)為單位組織,一個(gè)group內(nèi)包含多臺(tái)storage機(jī)器购公,數(shù)據(jù)互為備份赵哲,存儲(chǔ)空間以group內(nèi)容量最小的storage為準(zhǔn),所以建議group內(nèi)的多個(gè)storage盡量配置相同君丁,以免造成存儲(chǔ)空間的浪費(fèi)枫夺。
以group為單位組織存儲(chǔ)能方便的進(jìn)行應(yīng)用隔離、負(fù)載均衡绘闷、副本數(shù)定制(group內(nèi)storage server數(shù)量即為該group的副本數(shù))橡庞,比如將不同應(yīng)用數(shù)據(jù)存到不同的group就能隔離應(yīng)用數(shù)據(jù),同時(shí)還可根據(jù)應(yīng)用的訪問(wèn)特性來(lái)將應(yīng)用分配到不同的group來(lái)做負(fù)載均衡印蔗;缺點(diǎn)是group的容量受單機(jī)存儲(chǔ)容量的限制扒最,同時(shí)當(dāng)group內(nèi)有機(jī)器壞掉時(shí),數(shù)據(jù)恢復(fù)只能依賴group內(nèi)地其他機(jī)器华嘹,使得恢復(fù)時(shí)間會(huì)很長(zhǎng)吧趣。
group內(nèi)每個(gè)storage的存儲(chǔ)依賴于本地文件系統(tǒng),storage可配置多個(gè)數(shù)據(jù)存儲(chǔ)目錄耙厚,比如有10塊磁盤强挫,分別掛載在 /data/disk1-/data/disk10,則可將這10個(gè)目錄都配置為storage的數(shù)據(jù)存儲(chǔ)目錄薛躬。
storage接受到寫(xiě)文件請(qǐng)求時(shí)俯渤,會(huì)根據(jù)配置好的規(guī)則(后面會(huì)介紹),選擇其中一個(gè)存儲(chǔ)目錄來(lái)存儲(chǔ)文件型宝。為了避免單個(gè)目錄下的文件數(shù)太多八匠,在storage第一次啟動(dòng)時(shí),會(huì)在每個(gè)數(shù)據(jù)存儲(chǔ)目錄里創(chuàng)建2級(jí)子目錄趴酣,每級(jí)256個(gè)梨树,總共65536個(gè)文件,新寫(xiě)的文件會(huì)以hash的方式被路由到其中某個(gè)子目錄下岖寞,然后將文件數(shù)據(jù)直接作為一個(gè)本地文件存儲(chǔ)到該目錄中抡四。
client:客戶端,作為業(yè)務(wù)請(qǐng)求的發(fā)起方慎璧,通過(guò)專有接口床嫌,使用TCP/IP協(xié)議與跟蹤器服務(wù)器或存儲(chǔ)節(jié)點(diǎn)進(jìn)行數(shù)據(jù)交互跨释。FastDFS向使用者提供基本文件訪問(wèn)接口胸私,比如upload、download鳖谈、append岁疼、delete等,以客戶端庫(kù)的方式提供給用戶使用。
另外兩個(gè)概念:
group?:組捷绒, 也可稱為卷瑰排。 同組內(nèi)服務(wù)器上的文件是完全相同的 ,同一組內(nèi)的storage server之間是對(duì)等的暖侨, 文件上傳椭住、 刪除等操作可以在任意一臺(tái)storage server上進(jìn)行 。
meta data?:文件相關(guān)屬性字逗,鍵值對(duì)( Key Value Pair) 方式京郑,如:width=1024,heigth=768 。
Tracker相當(dāng)于FastDFS的大腦葫掉,不論是上傳還是下載都是通過(guò)tracker來(lái)分配資源些举;客戶端一般可以使用ngnix等靜態(tài)服務(wù)器來(lái)調(diào)用或者做一部分的緩存;存儲(chǔ)服務(wù)器內(nèi)部分為卷(或者叫做組)俭厚,卷于卷之間是平行的關(guān)系户魏,可以根據(jù)資源的使用情況隨時(shí)增加,卷內(nèi)服務(wù)器文件相互同步備份挪挤,以達(dá)到容災(zāi)的目的叼丑。
上傳機(jī)制
首先客戶端請(qǐng)求Tracker服務(wù)獲取到存儲(chǔ)服務(wù)器的ip地址和端口,然后客戶端根據(jù)返回的IP地址和端口號(hào)請(qǐng)求上傳文件扛门,存儲(chǔ)服務(wù)器接收到請(qǐng)求后生產(chǎn)文件幢码,并且將文件內(nèi)容寫(xiě)入磁盤并返回給客戶端file_id、路徑信息尖飞、文件名等信息症副,客戶端保存相關(guān)信息上傳完畢。
內(nèi)部機(jī)制如下:
1政基、選擇tracker server
當(dāng)集群中不止一個(gè)tracker server時(shí)贞铣,由于tracker之間是完全對(duì)等的關(guān)系,客戶端在upload文件時(shí)可以任意選擇一個(gè)trakcer沮明。 選擇存儲(chǔ)的group 當(dāng)tracker接收到upload file的請(qǐng)求時(shí)辕坝,會(huì)為該文件分配一個(gè)可以存儲(chǔ)該文件的group,支持如下選擇group的規(guī)則:
1荐健、Round robin酱畅,所有的group間輪詢
2、Specified group江场,指定某一個(gè)確定的group
3纺酸、Load balance,剩余存儲(chǔ)空間多多group優(yōu)先
2址否、選擇storage server
當(dāng)選定group后餐蔬,tracker會(huì)在group內(nèi)選擇一個(gè)storage server給客戶端,支持如下選擇storage的規(guī)則:
1、Round robin樊诺,在group內(nèi)的所有storage間輪詢
2仗考、First server ordered by ip,按ip排序
3词爬、First server ordered by priority秃嗜,按優(yōu)先級(jí)排序(優(yōu)先級(jí)在storage上配置)
3、選擇storage path
當(dāng)分配好storage server后顿膨,客戶端將向storage發(fā)送寫(xiě)文件請(qǐng)求痪寻,storage將會(huì)為文件分配一個(gè)數(shù)據(jù)存儲(chǔ)目錄,支持如下規(guī)則:
1虽惭、Round robin橡类,多個(gè)存儲(chǔ)目錄間輪詢
2芽唇、剩余存儲(chǔ)空間最多的優(yōu)先
4顾画、生成Fileid
選定存儲(chǔ)目錄之后,storage會(huì)為文件生一個(gè)Fileid匆笤,由storage server ip研侣、文件創(chuàng)建時(shí)間、文件大小、文件crc32和一個(gè)隨機(jī)數(shù)拼接而成喇澡,然后將這個(gè)二進(jìn)制串進(jìn)行base64編碼晴玖,轉(zhuǎn)換為可打印的字符串。 選擇兩級(jí)目錄 當(dāng)選定存儲(chǔ)目錄之后秀睛,storage會(huì)為文件分配一個(gè)fileid静汤,每個(gè)存儲(chǔ)目錄下有兩級(jí)256*256的子目錄,storage會(huì)按文件fileid進(jìn)行兩次hash(猜測(cè)),路由到其中一個(gè)子目錄瓷式,然后將文件以fileid為文件名存儲(chǔ)到該子目錄下贸典。
5惋砂、生成文件名
當(dāng)文件存儲(chǔ)到某個(gè)子目錄后西饵,即認(rèn)為該文件存儲(chǔ)成功驯嘱,接下來(lái)會(huì)為該文件生成一個(gè)文件名,文件名由group谢澈、存儲(chǔ)目錄、兩級(jí)子目錄敬鬓、fileid础芍、文件后綴名(由客戶端指定歼捐,主要用于區(qū)分文件類型)拼接而成豹储。
下載機(jī)制
客戶端帶上文件名信息請(qǐng)求Tracker服務(wù)獲取到存儲(chǔ)服務(wù)器的ip地址和端口氧骤,然后客戶端根據(jù)返回的IP地址和端口號(hào)請(qǐng)求下載文件呻疹,存儲(chǔ)服務(wù)器接收到請(qǐng)求后返回文件給客戶端。
跟upload file一樣筹陵,在download file時(shí)客戶端可以選擇任意tracker server刽锤。tracker發(fā)送download請(qǐng)求給某個(gè)tracker,必須帶上文件名信息朦佩,tracke從文件名中解析出文件的group并思、大小、創(chuàng)建時(shí)間等信息语稠,然后為該請(qǐng)求選擇一個(gè)storage用來(lái)服務(wù)讀請(qǐng)求宋彼。由于group內(nèi)的文件同步時(shí)在后臺(tái)異步進(jìn)行的,所以有可能出現(xiàn)在讀到時(shí)候仙畦,文件還沒(méi)有同步到某些storage server上输涕,為了盡量避免訪問(wèn)到這樣的storage,tracker按照如下規(guī)則選擇group內(nèi)可讀的storage慨畸。
1莱坎、該文件上傳到的源頭storage - 源頭storage只要存活著,肯定包含這個(gè)文件寸士,源頭的地址被編碼在文件名中檐什。
2碴卧、文件創(chuàng)建時(shí)間戳==storage被同步到的時(shí)間戳 且(當(dāng)前時(shí)間-文件創(chuàng)建時(shí)間戳) > 文件同步最大時(shí)間(如5分鐘) - 文件創(chuàng)建后,認(rèn)為經(jīng)過(guò)最大同步時(shí)間后乃正,肯定已經(jīng)同步到其他storage了住册。
3、文件創(chuàng)建時(shí)間戳 < storage被同步到的時(shí)間戳烫葬。 - 同步時(shí)間戳之前的文件確定已經(jīng)同步了
4界弧、(當(dāng)前時(shí)間-文件創(chuàng)建時(shí)間戳) > 同步延遲閥值(如一天)凡蜻。 - 經(jīng)過(guò)同步延遲閾值時(shí)間搭综,認(rèn)為文件肯定已經(jīng)同步了。
同步時(shí)間管理
當(dāng)一個(gè)文件上傳成功后划栓,客戶端馬上發(fā)起對(duì)該文件下載請(qǐng)求(或刪除請(qǐng)求)時(shí)兑巾,tracker是如何選定一個(gè)適用的存儲(chǔ)服務(wù)器呢? 其實(shí)每個(gè)存儲(chǔ)服務(wù)器都需要定時(shí)將自身的信息上報(bào)給tracker忠荞,這些信息就包括了本地同步時(shí)間(即蒋歌,同步到的最新文件的時(shí)間戳)。而tracker根據(jù)各個(gè)存儲(chǔ)服務(wù)器的上報(bào)情況委煤,就能夠知道剛剛上傳的文件堂油,在該存儲(chǔ)組中是否已完成了同步。同步信息上報(bào)如下圖:
寫(xiě)文件時(shí),客戶端將文件寫(xiě)至group內(nèi)一個(gè)storage server即認(rèn)為寫(xiě)文件成功,storage server寫(xiě)完文件后杯道,會(huì)由后臺(tái)線程將文件同步至同group內(nèi)其他的storage server元旬。
每個(gè)storage寫(xiě)文件后,同時(shí)會(huì)寫(xiě)一份binlog自阱,binlog里不包含文件數(shù)據(jù),只包含文件名等元信息,這份binlog用于后臺(tái)同步系宜,storage會(huì)記錄向group內(nèi)其他storage同步的進(jìn)度,以便重啟后能接上次的進(jìn)度繼續(xù)同步发魄;進(jìn)度以時(shí)間戳的方式進(jìn)行記錄盹牧,所以最好能保證集群內(nèi)所有server的時(shí)鐘保持同步。
storage的同步進(jìn)度會(huì)作為元數(shù)據(jù)的一部分匯報(bào)到tracker上励幼,tracke在選擇讀storage的時(shí)候會(huì)以同步進(jìn)度作為參考欢策。 比如一個(gè)group內(nèi)有A、B赏淌、C三個(gè)storage server踩寇,A向C同步到進(jìn)度為T1 (T1以前寫(xiě)的文件都已經(jīng)同步到B上了),B向C同步到時(shí)間戳為T2(T2 > T1)六水,tracker接收到這些同步進(jìn)度信息時(shí)俺孙,就會(huì)進(jìn)行整理辣卒,將最小的那個(gè)做為C的同步時(shí)間戳,本例中T1即為C的同步時(shí)間戳為T1(即所有T1以前寫(xiě)的數(shù)據(jù)都已經(jīng)同步到C上了)睛榄;同理荣茫,根據(jù)上述規(guī)則,tracker會(huì)為A场靴、B生成一個(gè)同步時(shí)間戳啡莉。
精巧的文件ID-FID
說(shuō)到下載就不得不提文件索引(又稱:FID)的精巧設(shè)計(jì)了。文件索引結(jié)構(gòu)如下圖旨剥,是客戶端上傳文件后存儲(chǔ)服務(wù)器返回給客戶端咧欣,用于以后訪問(wèn)該文件的索引信息。文件索引信息包括:組名轨帜,虛擬磁盤路徑魄咕,數(shù)據(jù)兩級(jí)目錄,文件名蚌父。
組名:文件上傳后所在的存儲(chǔ)組名稱哮兰,在文件上傳成功后有存儲(chǔ)服務(wù)器返回,需要客戶端自行保存苟弛。
虛擬磁盤路徑:存儲(chǔ)服務(wù)器配置的虛擬路徑喝滞,與磁盤選項(xiàng)store_path*對(duì)應(yīng)。
數(shù)據(jù)兩級(jí)目錄:存儲(chǔ)服務(wù)器在每個(gè)虛擬磁盤路徑下創(chuàng)建的兩級(jí)目錄膏秫,用于存儲(chǔ)數(shù)據(jù)文件右遭。
文件名:與文件上傳時(shí)不同。是由存儲(chǔ)服務(wù)器根據(jù)特定信息生成荔睹,文件名包含:源存儲(chǔ)服務(wù)器IP地址狸演、文件創(chuàng)建時(shí)間戳、文件大小僻他、隨機(jī)數(shù)和文件拓展名等信息宵距。
快速定位文件
知道FastDFS FID的組成后,我們來(lái)看看FastDFS是如何通過(guò)這個(gè)精巧的FID定位到需要訪問(wèn)的文件吨拗。
1满哪、通過(guò)組名tracker能夠很快的定位到客戶端需要訪問(wèn)的存儲(chǔ)服務(wù)器組,并將選擇合適的存儲(chǔ)服務(wù)器提供客戶端訪問(wèn)劝篷;
2哨鸭、存儲(chǔ)服務(wù)器根據(jù)“文件存儲(chǔ)虛擬磁盤路徑”和“數(shù)據(jù)文件兩級(jí)目錄”可以很快定位到文件所在目錄,并根據(jù)文件名找到客戶端需要訪問(wèn)的文件娇妓。
如何搭建FastDFS像鸡?參考我博客的這篇文章?(FastDFS 集群 安裝 配置:http:///fastdfs/2017/10/10/cluster-building-fastdfs.html),下圖為某用戶搭建的架構(gòu)示意圖