本發(fā)明涉及文件存儲(chǔ)及索引領(lǐng)域,具體而言,涉及一種文件存儲(chǔ)和索引方法、裝置及讀取文件的方法。
背景技術(shù):
當(dāng)今互聯(lián)網(wǎng),數(shù)據(jù)呈現(xiàn)爆炸式增長(zhǎng),社交網(wǎng)絡(luò)、移動(dòng)通信、網(wǎng)絡(luò)視頻、電子商務(wù)等各種應(yīng)用往往能產(chǎn)生億級(jí)甚至十億、百億級(jí)的海量小文件。由于在元數(shù)據(jù)管理、訪問性能、存儲(chǔ)效率等方面面臨巨大的挑戰(zhàn),海量小文件問題成為了業(yè)界公認(rèn)的難題。
業(yè)界的一些知名互聯(lián)網(wǎng)公司,也對(duì)海量小文件提出了解決方案,例如:著名的社交網(wǎng)站Facebook,存儲(chǔ)了超過600億張圖片,專門推出了Haystack系統(tǒng),針對(duì)海量小圖片進(jìn)行定制優(yōu)化的存儲(chǔ)。其他的小文件處理方案還有淘寶的TFS等,這些系統(tǒng)的核心思想都是將小文件追加到一個(gè)數(shù)據(jù)文件中,同時(shí)生成索引文件,通過索引文件來定位小文件的位置。
下面介紹Facebook采用的Haystack的解決方案:
Facebook的Haystack對(duì)小文件的解決辦法是,把小文件合起來。將一些小文件的數(shù)據(jù)依次追加到數(shù)據(jù)文件中,并且生成索引文件,通過索引來查找小文件在數(shù)據(jù)文件中的offset和size,對(duì)文件進(jìn)行讀取。
(1)Haystack的數(shù)據(jù)文件部分:Haystack的數(shù)據(jù)文件,將每個(gè)小文件封裝成一個(gè)needle,包含文件的key、size、data等數(shù)據(jù)信息。所有小文件按寫入的先后順序追加到數(shù)據(jù)文件中。
(2)Haystack的索引文件部分:Haystack的索引文件保存每個(gè)needle的key,以及該needle在數(shù)據(jù)文件中的offset、size等信息。程序啟動(dòng)時(shí)會(huì)將索引加載到內(nèi)存中,在內(nèi)存中通過查找索引,來定位在數(shù)據(jù)文件中的偏移量和大小。
(3)讀請(qǐng)求使用索引:將索引文件載入內(nèi)存,通過查找索引,來定位要讀取文件的offset、size,將數(shù)據(jù)讀取出來。
(4)寫請(qǐng)求使用索引:寫文件每次添加一個(gè)文件,將文件的數(shù)據(jù)添加到末尾的Needle n。生成索引添加到Needle n index record。
由上述的描述可以看出,F(xiàn)acebook的Haystack特點(diǎn)是將文件的完整key都加載到內(nèi)存中,進(jìn)行文件定位。機(jī)器內(nèi)存足夠大的情況下,F(xiàn)acebook完整的8字節(jié)key可以全部加載到內(nèi)存中。但是現(xiàn)實(shí)環(huán)境下存在兩個(gè)問題:
(1)存儲(chǔ)服務(wù)器內(nèi)存不會(huì)太大,一般為32G至64G;
(2)小文件對(duì)應(yīng)的key大小難控制,一般選擇文件內(nèi)容的MD5或SHA1作為該文件的key。
假設(shè)一臺(tái)存儲(chǔ)服務(wù)器有12塊4T磁盤,內(nèi)存為32GB左右。服務(wù)器上現(xiàn)需存儲(chǔ)大小約為4K的頭像、縮略圖等文件,約為10億個(gè)。文件的key使用MD5,加上offset和size字段,平均一個(gè)小文件對(duì)應(yīng)的索引信息占用28字節(jié)。在這種情況下,索引占用內(nèi)存接近30GB,磁盤僅占用4TB。內(nèi)存消耗近100%,磁盤消耗只有8%。
由此可見,Haystack系統(tǒng)采用的索引方案對(duì)內(nèi)存資源消耗巨大,并且內(nèi)存資源限制了磁盤資源的利用率,因此,想要獲得更大的磁盤資源的利用率需要額外增加內(nèi)存資源的大量投入。
技術(shù)實(shí)現(xiàn)要素:
本發(fā)明提供了一種文件存儲(chǔ)和索引方法、裝置及讀取文件的方法,以至少解決Haystack系統(tǒng)采用的索引方案對(duì)內(nèi)存資源消耗大的問題。
根據(jù)本發(fā)明的一個(gè)方面,提供了一種文件存儲(chǔ)和索引方法,包括:按照文件的實(shí)際key值的字母順序存儲(chǔ)各文件,得到數(shù)據(jù)文件;生成用于索引所述數(shù)據(jù)文件中各文件的索引文件,其中,所述索引文件中的索引使用各文件的實(shí)際key值的前N字節(jié)作為key值,每個(gè)索引指向所述數(shù)據(jù)文件中的一個(gè)或者多個(gè)文件,所述key值對(duì)應(yīng)的offset值為所述key值指向的一個(gè)或者多個(gè)文件中首個(gè)文件的offset值,所述key值對(duì)應(yīng)的size值為所述key值指向的一個(gè)或者多個(gè)文件中首個(gè)文件的size值,N為正整數(shù)。
可選地,所述索引文件中的offset字段和size字段是通過512字節(jié)對(duì)齊的。
可選地,生成用于索引所述數(shù)據(jù)文件中各文件的索引文件還包括:按照key值前綴分層存儲(chǔ)所述索引文件的索引,其中,所述key值前綴對(duì)應(yīng)的分層中存儲(chǔ)的索引的key值為截去所述key值前綴的簡(jiǎn)短key值,其中,所述key值前綴的字節(jié)長(zhǎng)度小于N。
可選地,所述索引文件的索引的offset值是以所述索引所在分層為偏移范圍的層內(nèi)offset值,所述層內(nèi)offset值的字節(jié)數(shù)是根據(jù)分層的最大層地址空間確定的。
可選地,所述方法還包括:將所述數(shù)據(jù)文件中的所有文件映射到bloomfilter中,以使讀取所述數(shù)據(jù)文件中的文件時(shí)通過快速搜索所述bloomfilter來判斷將要讀取的文件是否可能存在。
根據(jù)本發(fā)明的另一個(gè)方面,還提供了一種文件存儲(chǔ)和索引裝置,包括:數(shù)據(jù)文件存儲(chǔ)模塊,用于存儲(chǔ)數(shù)據(jù)文件,其中,所述數(shù)據(jù)文件是按照文件的實(shí)際key值的字母順序存儲(chǔ)各文件所得到的;索引文件生成模塊,用于生成用于索引所述數(shù)據(jù)文件中各文件的索引文件,其中,所述索引文件中的索引使用各文件的實(shí)際key值的前N字節(jié)作為key值,每個(gè)索引指向所述數(shù)據(jù)文件中的一個(gè)或者多個(gè)文件,所述key值對(duì)應(yīng)的offset值為所述key值指向的一個(gè)或者多個(gè)文件中首個(gè)文件的offset值,所述key值對(duì)應(yīng)的size值為所述key值指向的一個(gè)或者多個(gè)文件中首個(gè)文件的size值,N為正整數(shù)。
可選地,所述索引文件生成模塊,還用于按照key值前綴分層存儲(chǔ)所述索引文件的索引,其中,所述key值前綴對(duì)應(yīng)的分層中存儲(chǔ)的索引的key值為截去所述key值前綴的簡(jiǎn)短key值,其中,所述key值前綴的字節(jié)長(zhǎng)度小于N。
可選地,所述索引文件的索引的offset值是以所述索引所在分層為偏移范圍的層內(nèi)offset值,所述層內(nèi)offset值的字節(jié)數(shù)是根據(jù)分層的最大層地址空間確定的。
可選地,所述裝置還包括:映射模塊,用于將所述數(shù)據(jù)文件中的所有文件映射到bloom filter中,以使讀取所述數(shù)據(jù)文件中的文件時(shí)通過搜索所述bloom filter來判斷將要讀取的文件是否可能存在。
根據(jù)本發(fā)明的另一個(gè)方面,還提供了一種在上述的文件存儲(chǔ)和索引裝置中讀取文件的方法,包括:根據(jù)將要讀取的文件的實(shí)際key值的前N字節(jié)查詢所述索引文件中所述實(shí)際key值的前N字節(jié)對(duì)應(yīng)的索引;根據(jù)所述實(shí)際key值,在所述實(shí)際key值的前N字節(jié)對(duì)應(yīng)的索引指向的一個(gè)或者多個(gè)文件中匹配文件;在匹配到key值與所述實(shí)際key值一致的文件時(shí),讀取該文件。
可選地,根據(jù)將要讀取的文件的實(shí)際key值的前N字節(jié)查詢所述索引文件中所述實(shí)際key值的前N字節(jié)對(duì)應(yīng)的索引包括:根據(jù)所述bloom filter判斷將要讀取的文件是否可能存在;在判斷結(jié)果為可能存在的情況下,根據(jù)將要讀取的文件的實(shí)際key值的前N字節(jié)查詢所述索引文件中所述實(shí)際key值的前N字節(jié)對(duì)應(yīng)的索引,否則終止讀取文件。
通過本發(fā)明,采用按照文件的實(shí)際key值的字母順序存儲(chǔ)各文件,得到數(shù)據(jù)文件;生成用于索引數(shù)據(jù)文件中各文件的索引文件,其中,索引文件中的索引使用各文件的實(shí)際key值的前N字節(jié)作為key值,每個(gè)索引指向數(shù)據(jù)文件中的一個(gè)或者多個(gè)文件,key值對(duì)應(yīng)的offset值為key值指向的一個(gè)或者多個(gè)文件中首個(gè)文件的offset值,key值對(duì)應(yīng)的size值為key值指向的一個(gè)或者多個(gè)文件中首個(gè)文件的size值的方式,解決了Haystack系統(tǒng)采用的索引方案對(duì)內(nèi)存資源消耗大的問題,降低了索引系統(tǒng)對(duì)內(nèi)存資源的消耗。
附圖說明
此處所說明的附圖用來提供對(duì)本發(fā)明的進(jìn)一步理解,構(gòu)成本申請(qǐng)的一部分,本發(fā)明的示意性實(shí)施例及其說明用于解釋本發(fā)明,并不構(gòu)成對(duì)本發(fā)明的不當(dāng)限定。在附圖中:
圖1是根據(jù)本發(fā)明實(shí)施例的文件存儲(chǔ)和索引方法的流程圖;
圖2是根據(jù)本發(fā)明實(shí)施例的文件存儲(chǔ)和索引裝置的結(jié)構(gòu)框圖;
圖3是根據(jù)本發(fā)明實(shí)施例的在文件存儲(chǔ)和索引裝置中讀取文件的方法的流程圖;
圖4是根據(jù)本發(fā)明優(yōu)選實(shí)施例的文件存儲(chǔ)和索引結(jié)構(gòu)的示意圖;
圖5是根據(jù)本發(fā)明優(yōu)選實(shí)施例的讀取文件的方法的流程圖;
圖6、圖7和圖8是根據(jù)本發(fā)明優(yōu)選實(shí)施例的索引分層示意圖;
圖9和圖10是根據(jù)本發(fā)明優(yōu)選實(shí)施例與相關(guān)技術(shù)的索引方案的內(nèi)存消耗對(duì)比示意圖。
具體實(shí)施方式
下文中將參考附圖并結(jié)合實(shí)施例來詳細(xì)說明本發(fā)明。需要說明的是,在不沖突的情況下,本申請(qǐng)中的實(shí)施例及實(shí)施例中的特征可以相互組合。
需要說明的是,本發(fā)明的說明書和權(quán)利要求書及上述附圖中的術(shù)語(yǔ)“第一”、“第二”等是用于區(qū)別類似的對(duì)象,而不必用于描述特定的順序或先后次序。
實(shí)施例1
在本實(shí)施例中提供了一種文件存儲(chǔ)和索引方法,圖1是根據(jù)本發(fā)明實(shí)施例的文件存儲(chǔ)和索引方法的流程圖。如圖1所示,該流程包括如下步驟:
步驟S101,按照文件的實(shí)際key值的字母順序存儲(chǔ)各文件,得到數(shù)據(jù)文件;
步驟S102,生成用于索引數(shù)據(jù)文件中各文件的索引文件,其中,索引文件中的索引使用各文件的實(shí)際key值的前N字節(jié)作為key值,每個(gè)索引指向數(shù)據(jù)文件中的一個(gè)或者多個(gè)文件,key值對(duì)應(yīng)的offset值為key值指向的一個(gè)或者多個(gè)文件中首個(gè)文件的offset值,key值對(duì)應(yīng)的size值為key值指向的一個(gè)或者多個(gè)文件中首個(gè)文件的size值,N為正整數(shù)。
在上述步驟中,由于在索引中不再保存文件實(shí)際key值,而是僅保存實(shí)際key值的前N字節(jié),減少了索引文件的大??;同時(shí),這樣的索引不再指向一個(gè)文件,而會(huì)指向?qū)嶋Hkey值的前N字節(jié)相同的一個(gè)或者多個(gè)文件;為了能夠根據(jù)索引中的offset值定位到文件的位置,在存儲(chǔ)文件時(shí)把文件按照實(shí)際key值的字母順序依次存儲(chǔ)到數(shù)據(jù)文件中,使得實(shí)際key值的前N字節(jié)相同的一個(gè)或者多個(gè)文件集中存儲(chǔ)在一片連續(xù)的位置上,得以使用一個(gè)offset值來指示它們的存儲(chǔ)位置。可見,在將步驟S102中生成的索引文件加載到內(nèi)存中之后,相對(duì)于相關(guān)技術(shù)的Haystack系統(tǒng)而言,將會(huì)占用更少的內(nèi)存資源,解決了Haystack系統(tǒng)采用的索引方案對(duì)內(nèi)存資源消耗大的問題,降低了索引系統(tǒng)對(duì)內(nèi)存資源的消耗。
在采用步驟S102生成的索引文件索引某一個(gè)文件時(shí),根據(jù)索引不再能直接索引到某一個(gè)確定的文件,而將會(huì)索引到一個(gè)連續(xù)的文件集合;在需要精確讀取某一個(gè)文件時(shí),只要根據(jù)這個(gè)文件的實(shí)際key值,在文件集合中逐一匹配文件就可能讀取到想要的文件。
可選地,上述索引文件中的offset字段和size字段是通過512字節(jié)對(duì)齊的;即如果一個(gè)文件是1024字節(jié)大小,按照512字節(jié)對(duì)齊,1024/512=2,則文件大小可以用2表示,當(dāng)在索引中得到size是2,用2乘以512字節(jié)就可以得到文件的大小是1024字節(jié);之前需要保存的是1024,現(xiàn)在只需要保存2這個(gè)數(shù)字,至少節(jié)省一個(gè)字節(jié)。并且還可以根據(jù)整個(gè)數(shù)據(jù)文件的實(shí)際大小計(jì)算offset字段和size字段所需使用的字節(jié)數(shù),從而可以進(jìn)一步減小索引所占用的字節(jié)數(shù)。
為了能夠進(jìn)一步減小索引所占用的字節(jié)數(shù),考慮到索引文件中存儲(chǔ)的key值仍有key值前綴重復(fù)的可能行,因此,還可以考慮對(duì)索引文件中的索引按照key值前綴進(jìn)行分層存儲(chǔ),其中,key值前綴對(duì)應(yīng)的分層中存儲(chǔ)的索引的key值為截去key值前綴的簡(jiǎn)短key值,key值前綴的字節(jié)長(zhǎng)度小于N。在該分層中索引數(shù)量越多的情況下,分層后的索引文件占用的字節(jié)數(shù)相對(duì)于原來的索引文件將會(huì)更小。
在索引文件采用分層存儲(chǔ)之后,各分層內(nèi)的索引的offset值可以進(jìn)一步優(yōu)化以減少字節(jié)數(shù)。可選地,索引文件的索引的offset值是以索引所在分層為偏移范圍的層內(nèi)offset值,該層內(nèi)offset值的字節(jié)數(shù)是根據(jù)分層的最大層地址空間確定的。由于最大層地址空間必然小于整個(gè)數(shù)據(jù)文件的大小,因此,層內(nèi)offset值占用的字節(jié)數(shù)也將小于按照整個(gè)數(shù)據(jù)文件為偏移范圍的原始o(jì)ffset值占用的字節(jié)數(shù)。
bloom filter是一種二進(jìn)制向量數(shù)據(jù)結(jié)構(gòu),它具有很好的空間和時(shí)間效率,被用來檢測(cè)一個(gè)元素是不是集合中的一個(gè)成員。如果檢測(cè)結(jié)果為是,該元素不一定在集合中;但如果檢測(cè)結(jié)果為否,該元素一定不在集合中。Bloom filter優(yōu)點(diǎn)是它的插入和查詢時(shí)間都是常數(shù),另外它查詢?cè)貐s不保存元素本身,具有良好的安全性。在本發(fā)明中,由于一個(gè)索引指向多個(gè)文件,因此有必要利用bloom filter,以通過快速搜索文件是否可能存在來避免對(duì)不存在文件的查詢所造成的資源和時(shí)間浪費(fèi)。可選地,本實(shí)施例中還將數(shù)據(jù)文件中的所有文件映射到bloom filter中,以使讀取數(shù)據(jù)文件中的文件時(shí)通過快速搜索bloom filter來判斷將要讀取的文件是否可能存在。
本發(fā)明實(shí)施例中N的取值優(yōu)選為4。
通過以上的實(shí)施方式的描述,本領(lǐng)域的技術(shù)人員可以清楚地了解到根據(jù)上述實(shí)施例的方法可借助軟件加必需的通用硬件平臺(tái)的方式來實(shí)現(xiàn),當(dāng)然也可以通過硬件,但很多情況下前者是更佳的實(shí)施方式?;谶@樣的理解,本發(fā)明的技術(shù)方案本質(zhì)上或者說對(duì)現(xiàn)有技術(shù)做出貢獻(xiàn)的部分可以以軟件產(chǎn)品的形式體現(xiàn)出來,該計(jì)算機(jī)軟件產(chǎn)品存儲(chǔ)在一個(gè)存儲(chǔ)介質(zhì)(如ROM/RAM、磁碟、光盤)中,包括若干指令用以使得一臺(tái)終端設(shè)備(可以是手機(jī),計(jì)算機(jī),服務(wù)器,或者網(wǎng)絡(luò)設(shè)備等)執(zhí)行本發(fā)明各個(gè)實(shí)施例所述的方法。
實(shí)施例2
在本實(shí)施例中還提供了一種文件存儲(chǔ)和索引裝置,該裝置用于實(shí)現(xiàn)上述實(shí)施例及優(yōu)選實(shí)施方式,已經(jīng)進(jìn)行過說明的不再贅述。如以下所使用的,術(shù)語(yǔ)“模塊”可以實(shí)現(xiàn)預(yù)定功能的軟件和/或硬件的組合。盡管以下實(shí)施例所描述的裝置較佳地以軟件來實(shí)現(xiàn),但是硬件,或者軟件和硬件的組合的實(shí)現(xiàn)也是可能并被構(gòu)想的。
圖2是根據(jù)本發(fā)明實(shí)施例的文件存儲(chǔ)和索引裝置的結(jié)構(gòu)框圖,如圖2所示,該裝置包括:數(shù)據(jù)文件存儲(chǔ)模塊21和索引文件生成模塊22,其中,
數(shù)據(jù)文件存儲(chǔ)模塊21,用于存儲(chǔ)數(shù)據(jù)文件,其中,數(shù)據(jù)文件是按照文件的實(shí)際key值的字母順序存儲(chǔ)各文件所得到的;索引文件生成模塊22,耦合至數(shù)據(jù)文件存儲(chǔ)模塊21,用于生成用于索引數(shù)據(jù)文件中各文件的索引文件,其中,索引文件中的索引使用各文件的實(shí)際key值的前N字節(jié)作為key值,每個(gè)索引指向數(shù)據(jù)文件中的一個(gè)或者多個(gè)文件,key值對(duì)應(yīng)的offset值為key值指向的一個(gè)或者多個(gè)文件中首個(gè)文件的offset值,key值對(duì)應(yīng)的size值為key值指向的一個(gè)或者多個(gè)文件中首個(gè)文件的size值,N為正整數(shù)。
可選地,索引文件生成模塊還用于按照key值前綴分層存儲(chǔ)索引文件的索引,其中,key值前綴對(duì)應(yīng)的分層中存儲(chǔ)的索引的key值為截去key值前綴的簡(jiǎn)短key值,其中,key值前綴的字節(jié)長(zhǎng)度小于N。
可選地,索引文件的索引的offset值是以索引所在分層為偏移范圍的層內(nèi)offset值,層內(nèi)offset值的字節(jié)數(shù)是根據(jù)分層的最大層地址空間確定的。
可選地,上述文件存儲(chǔ)和索引裝置還包括:映射模塊,用于將數(shù)據(jù)文件中的所有文件映射到bloom filter中,以使讀取數(shù)據(jù)文件中的文件時(shí)通過搜索bloom filter來判斷將要讀取的文件是否可能存在。
需要說明的是,上述各個(gè)模塊是可以通過軟件或硬件來實(shí)現(xiàn)的,對(duì)于后者,可以通過以下方式實(shí)現(xiàn),但不限于此:上述模塊均位于同一處理器中;或者,上述模塊分別位于多個(gè)處理器中。
本發(fā)明實(shí)施例中N的取值優(yōu)選為4。
實(shí)施例3
在本實(shí)施例中提供了一種在上述的文件存儲(chǔ)和索引裝置中讀取文件的方法,圖3是根據(jù)本發(fā)明實(shí)施例的在文件存儲(chǔ)和索引裝置中讀取文件的方法的流程圖,如圖3所示,該流程包括如下步驟:
步驟S301,根據(jù)將要讀取的文件的實(shí)際key值的前N字節(jié)查詢索引文件中實(shí)際key值的前N字節(jié)對(duì)應(yīng)的索引;
步驟S302,根據(jù)實(shí)際key值,在實(shí)際key值的前N字節(jié)對(duì)應(yīng)的索引指向的一個(gè)或者多個(gè)文件中匹配文件;
步驟S303,在匹配到key值與實(shí)際key值一致的文件時(shí),讀取該文件。
可選地,在步驟S301中,在查詢索引之前,還可以根據(jù)bloom filter判斷將要讀取的文件是否可能存在;在判斷結(jié)果為可能存在的情況下,根據(jù)將要讀取的文件的實(shí)際key值的前N字節(jié)查詢索引文件中實(shí)際key值的前N字節(jié)對(duì)應(yīng)的索引,否則終止讀取文件。
本發(fā)明實(shí)施例中N的取值優(yōu)選為4。
實(shí)施例4
為了使本發(fā)明實(shí)施例的描述更加清楚,下面結(jié)合優(yōu)選實(shí)施例進(jìn)行描述和說明。
在本優(yōu)選實(shí)施例中提供了一種文件存儲(chǔ)和索引結(jié)構(gòu)和方法,圖4是根據(jù)本發(fā)明優(yōu)選實(shí)施例的文件存儲(chǔ)和索引結(jié)構(gòu)的示意圖,如圖4所示,其中,layer是分層文件,將相同的key前綴分為一層。Index是索引文件,對(duì)小文件進(jìn)行定位。data是數(shù)據(jù)文件,其中的每個(gè)needle都是一個(gè)小文件。
圖5是根據(jù)本發(fā)明優(yōu)選實(shí)施例的讀取文件的方法的流程圖,在圖5中示出了通過匹配索引前綴,定位小文件的具體位置,然后通過讀取完整的key,來查看文件的key是否匹配,如果不匹配再繼續(xù)順序查找下一個(gè)needle的詳細(xì)流程。
本優(yōu)選實(shí)施例提供的文件存儲(chǔ)和索引方案包括下列步驟:
步驟1:壓縮前綴優(yōu)化,減少key、offset、size占用空間;
(1)數(shù)據(jù)文件組織:
與Facebook的Haystack類似,該系統(tǒng)將多個(gè)小文件寫入到一個(gè)數(shù)據(jù)文件中,每個(gè)needle保存key、size、data等信息。
(2)索引文件組織:
1)索引文件只保存key的前四字節(jié),而非完整的key;
2)索引文件中的offset和size字段,通過512字節(jié)對(duì)齊,節(jié)省1個(gè)字節(jié);并根據(jù)整個(gè)數(shù)據(jù)文件實(shí)際大小計(jì)算offset和size使用的字節(jié)數(shù)。
步驟2:needle順序存放,定位小文件位置;
數(shù)據(jù)文件中的needle按照key的字母順序存放。
由于索引文件的key,只保存前四字節(jié),如果小文件key的前四字節(jié)相同,不順序存放needle,則無法根據(jù)一個(gè)offset找到分散存放的全部needle的具體位置。例如:用戶讀取的文件key是0x ab cd ef ac ee,但由于索引文件中的key只保存前四字節(jié),只能匹配0x ab cd ef ac這個(gè)前綴,此時(shí)無法定位到具體要讀取的offset。
在本優(yōu)選實(shí)施例中,通過needle順序存放,來解決上述問題:例如:用戶讀取文件的key是0x ab cd ef ac bb,匹配到0x ab cd ef ac這個(gè)前綴,此時(shí)offset指向0x ab cd ef ac aa這個(gè)needle,第一次匹配未命中。
通過存放在needle的header(文件頭)中的size,我們可以定位0x abcdef ac bb位置,匹配到正確needle,并將數(shù)據(jù)讀取給用戶。
步驟3:索引分層優(yōu)化;
(1)分層方案
參考圖6,可以將索引中key值前綴相同的索引分為一層。分層原則是每個(gè)分層中的needle數(shù)盡量控制在64個(gè)左右,并且根據(jù)分層要存放的needle數(shù)量,選擇分層級(jí)別。分層級(jí)別可以根據(jù)需要確定,例如下面給出了一種分層級(jí)別的示例:
0級(jí):不進(jìn)行分層;
1級(jí):選擇needle key第一字節(jié)進(jìn)行分層;
2級(jí):選擇needle key的前兩字節(jié)進(jìn)行分層;
分層所用的key值前綴的字節(jié)數(shù)小于索引中key值的字節(jié)長(zhǎng)度。
(2)分層減少Key的占用字節(jié)數(shù)
參考圖7,通過分層,只保存一份重復(fù)的前綴,節(jié)省key的字節(jié)數(shù)。
(3)分層減少offset的占用字節(jié)數(shù)
參考圖8,優(yōu)化前的offset,偏移范圍為整個(gè)數(shù)據(jù)文件的地址空間。優(yōu)化后,layer的offset在整個(gè)數(shù)據(jù)文件中進(jìn)行偏移,而分層下的索引的offset只需在數(shù)據(jù)文件中的層內(nèi)進(jìn)行偏移,根據(jù)最大的層地址空間可以計(jì)算所需字節(jié)數(shù)。
此外,在本優(yōu)選實(shí)施例中,還通過bloomfilter避免不存在文件的訪問。
在內(nèi)存中,將存在的文件映射到bloom filter中,只需要通過快速搜索,就可以排除掉不存在文件。時(shí)間復(fù)雜度為O(k),k為一個(gè)元素需要的bit位數(shù)。經(jīng)驗(yàn)表明,當(dāng)k為9.6時(shí),誤報(bào)率為1%,如果k再增加4.8,誤報(bào)率會(huì)降低到0.1%。
下面將以Haystack為參考說明本發(fā)明優(yōu)選實(shí)施例的有益效果。
(1)通過前綴壓縮,帶來的內(nèi)存節(jié)省對(duì)比
參考圖9,橫軸表示文件數(shù),縱軸表示索引文件需要的內(nèi)存大小,短虛線表示傳統(tǒng)的Haystack的內(nèi)存消耗量,長(zhǎng)虛線表示通過本發(fā)明實(shí)施例進(jìn)行前綴壓縮后的內(nèi)存消耗量。從圖9可以看出在文件數(shù)量為10億的情況下,使用facabook的Haystack消耗的內(nèi)存為26G多,使用本優(yōu)選實(shí)施例提供的壓縮前綴的索引方案消耗的內(nèi)存為9G多,內(nèi)存使用降低了2/3。
(2)再次通過索引分層,帶來的內(nèi)存節(jié)省對(duì)比
參考圖10,橫軸表示文件數(shù),縱軸表示索引文件需要的內(nèi)存大小,短虛線表示傳統(tǒng)的Haystack的內(nèi)存消耗量,長(zhǎng)虛線表示通過本發(fā)明實(shí)施例進(jìn)行前綴壓縮后的內(nèi)存消耗量,實(shí)線表示通過本發(fā)明實(shí)施例進(jìn)行前綴壓縮并索引分層后的內(nèi)存消耗量。從圖10可以看出,在進(jìn)行索引分層后,從優(yōu)化之前的9G多內(nèi)存消耗,進(jìn)一步降低到4G多,又節(jié)省了1半的內(nèi)存消耗。
在試驗(yàn)本優(yōu)選實(shí)施例提供的文件存儲(chǔ)和索引方案后,小文件的整體性能有顯著提高,每秒請(qǐng)求數(shù)(RequestPerSecond,簡(jiǎn)稱為RPS)提升一倍多,機(jī)器的輸入輸出(Input/Output,簡(jiǎn)稱為IO)使用率減少了將近一倍。同時(shí),因?yàn)閮?yōu)化了最小存儲(chǔ)單元,碎片降低80%。使用該系統(tǒng)我們可以為用戶提供更快速地讀寫服務(wù),并且節(jié)省了集群的資源消耗。
實(shí)施例5
在本實(shí)施例中提供了一種軟件,該軟件用于執(zhí)行上述實(shí)施例及優(yōu)選實(shí)施方式中描述的技術(shù)方案。
實(shí)施例6
本發(fā)明的實(shí)施例還提供了一種存儲(chǔ)介質(zhì)。在本實(shí)施例中,上述存儲(chǔ)介質(zhì)可以被設(shè)置為存儲(chǔ)用于執(zhí)行以下步驟的程序代碼:
步驟S101,按照文件的實(shí)際key值的字母順序存儲(chǔ)各文件,得到數(shù)據(jù)文件;
步驟S102,生成用于索引數(shù)據(jù)文件中各文件的索引文件,其中,索引文件中的索引使用各文件的實(shí)際key值的前N字節(jié)作為key值,每個(gè)索引指向數(shù)據(jù)文件中的一個(gè)或者多個(gè)文件,key值對(duì)應(yīng)的offset值為key值指向的一個(gè)或者多個(gè)文件中首個(gè)文件的offset值,key值對(duì)應(yīng)的size值為key值指向的一個(gè)或者多個(gè)文件中首個(gè)文件的size值,N為正整數(shù)。
可選地,在本實(shí)施例中,上述存儲(chǔ)介質(zhì)可以包括但不限于:U盤、只讀存儲(chǔ)器(Read-Only Memory,簡(jiǎn)稱為ROM)、隨機(jī)存取存儲(chǔ)器(Random Access Memory,簡(jiǎn)稱為RAM)、移動(dòng)硬盤、磁碟或者光盤等各種可以存儲(chǔ)程序代碼的介質(zhì)。
可選地,本實(shí)施例中的具體示例可以參考上述實(shí)施例及可選實(shí)施方式中所描述的示例,本實(shí)施例在此不再贅述。
實(shí)施例7
本發(fā)明的實(shí)施例還提供了一種存儲(chǔ)介質(zhì)。在本實(shí)施例中,上述存儲(chǔ)介質(zhì)可以被設(shè)置為存儲(chǔ)用于執(zhí)行以下步驟的程序代碼:
步驟S301,根據(jù)將要讀取的文件的實(shí)際key值的前N字節(jié)查詢索引文件中實(shí)際key值的前N字節(jié)對(duì)應(yīng)的索引;
步驟S302,根據(jù)實(shí)際key值,在實(shí)際key值的前N字節(jié)對(duì)應(yīng)的索引指向的一個(gè)或者多個(gè)文件中匹配文件;
步驟S303,在匹配到key值與實(shí)際key值一致的文件時(shí),讀取該文件。
可選地,在本實(shí)施例中,上述存儲(chǔ)介質(zhì)可以包括但不限于:U盤、只讀存儲(chǔ)器(Read-Only Memory,簡(jiǎn)稱為ROM)、隨機(jī)存取存儲(chǔ)器(Random Access Memory,簡(jiǎn)稱為RAM)、移動(dòng)硬盤、磁碟或者光盤等各種可以存儲(chǔ)程序代碼的介質(zhì)。
可選地,本實(shí)施例中的具體示例可以參考上述實(shí)施例及可選實(shí)施方式中所描述的示例,本實(shí)施例在此不再贅述。
顯然,本領(lǐng)域的技術(shù)人員應(yīng)該明白,上述的本發(fā)明的各模塊或各步驟可以用通用的計(jì)算裝置來實(shí)現(xiàn),它們可以集中在單個(gè)的計(jì)算裝置上,或者分布在多個(gè)計(jì)算裝置所組成的網(wǎng)絡(luò)上,可選地,它們可以用計(jì)算裝置可執(zhí)行的程序代碼來實(shí)現(xiàn),從而,可以將它們存儲(chǔ)在存儲(chǔ)裝置中由計(jì)算裝置來執(zhí)行,并且在某些情況下,可以以不同于此處的順序執(zhí)行所示出或描述的步驟,或者將它們分別制作成各個(gè)集成電路模塊,或者將它們中的多個(gè)模塊或步驟制作成單個(gè)集成電路模塊來實(shí)現(xiàn)。這樣,本發(fā)明不限制于任何特定的硬件和軟件結(jié)合。
以上所述僅為本發(fā)明的優(yōu)選實(shí)施例而已,并不用于限制本發(fā)明,對(duì)于本領(lǐng)域的技術(shù)人員來說,本發(fā)明可以有各種更改和變化。凡在本發(fā)明的精神和原則之內(nèi),所作的任何修改、等同替換、改進(jìn)等,均應(yīng)包含在本發(fā)明的保護(hù)范圍之內(nèi)。