按照使用的資源類型劃分,我們可以把系統(tǒng)分為三大類型:IO密集型、計(jì)算密集型,數(shù)據(jù)密集型。系統(tǒng)的類型反映了系統(tǒng)的主要瓶頸。現(xiàn)實(shí)情況中,大部分系統(tǒng)在由小變大的過程中,最先出現(xiàn)瓶頸的是IO。IO問題體現(xiàn)在兩個(gè)方面:高并發(fā),存儲(chǔ)介質(zhì)的讀寫(例如數(shù)據(jù)庫,磁盤等)。隨著業(yè)務(wù)邏輯的復(fù)雜化,接下來出現(xiàn)瓶頸的是計(jì)算,也就是常說的CPU idle不足。出現(xiàn)計(jì)算瓶頸的時(shí)候,一般會(huì)使用水平擴(kuò)展(加機(jī)器)和垂直擴(kuò)張(服務(wù)拆分)兩個(gè)方法。隨著數(shù)據(jù)量(用戶數(shù)量,客戶數(shù)量)的增長,再接下來出現(xiàn)瓶頸的是內(nèi)存。
如今,內(nèi)存的合理使用比以往更加重要。一方面,大數(shù)據(jù)理論已經(jīng)非常普及,用數(shù)據(jù)驅(qū)動(dòng)產(chǎn)品也已經(jīng)被普遍接受并落地,同時(shí)數(shù)據(jù)分析也促使產(chǎn)品設(shè)計(jì)的更加精細(xì),因此系統(tǒng)承載的數(shù)量比以前有了很大的變化,系統(tǒng)遇到內(nèi)存瓶頸的時(shí)間也比以前大大縮短了。另一方面,內(nèi)存依然是相對(duì)昂貴的硬件,不能無限制的使用。即使在Amazon等云服務(wù)上,大內(nèi)存的實(shí)例也是很昂貴的,并且大內(nèi)存的實(shí)例往往伴隨著高性能型CPU,這對(duì)一些數(shù)據(jù)密集型系統(tǒng)是一個(gè)浪費(fèi)。因此,本文重點(diǎn)探討數(shù)據(jù)密集系統(tǒng)如何應(yīng)對(duì)出現(xiàn)的瓶頸。
1. 拆庫
任何工程上的問題最基本的思路都是“分而治之”。因此,當(dāng)內(nèi)存不夠時(shí),很自然的想法是將數(shù)據(jù)拆分到多臺(tái)機(jī)器中,俗稱拆庫。沿用數(shù)據(jù)庫拆分的術(shù)語,拆庫又分為“水平拆分”和“垂直拆分”兩個(gè)派別。
1.1 水平拆分
水平拆分是指將同一種數(shù)據(jù)的不同記錄進(jìn)行拆分。
例如我們有一億條商品數(shù)據(jù)供查詢。如果單機(jī)無法存儲(chǔ),可以使用四臺(tái)機(jī)器,每臺(tái)機(jī)器存儲(chǔ)2500萬條商品數(shù)據(jù)。其中,每臺(tái)機(jī)器稱為一個(gè)“分片”,同一個(gè)分片的多臺(tái)機(jī)器組成一個(gè)“分組”,從四個(gè)分組各選出一臺(tái)機(jī)器組成一個(gè)完整的服務(wù)。當(dāng)上游服務(wù)進(jìn)行查詢時(shí),同時(shí)查詢四臺(tái)機(jī)器,并對(duì)返回結(jié)果做合并。
在使用水平拆分的方案時(shí),需要重點(diǎn)考慮以下問題:
索引服務(wù)
如前幾篇文章所述,任何大數(shù)據(jù)量系統(tǒng)中,在啟動(dòng)之前都需要加載索引數(shù)據(jù)。索引數(shù)據(jù)一般是預(yù)先計(jì)算好的,并且以二進(jìn)制格式持久化的文件。因?yàn)榉⻊?wù)進(jìn)行了拆分,每一臺(tái)機(jī)器只需要加載一部分?jǐn)?shù)據(jù),因此需要為每個(gè)分組的機(jī)器單獨(dú)計(jì)算索引數(shù)據(jù),這樣減少了系統(tǒng)啟動(dòng)時(shí)處理的數(shù)據(jù)量,加快啟動(dòng)速度。
數(shù)據(jù)更新
同樣,由于每臺(tái)機(jī)器只需要加載一部分?jǐn)?shù)據(jù),那么也只需要處理這部分?jǐn)?shù)據(jù)的更新。目前主流的更新數(shù)據(jù)流都是使用 Mesage Queue 作為傳輸和持久化系統(tǒng)個(gè),在服務(wù)端接收 Message Queue 的數(shù)據(jù)并持久化到本地,供在線服務(wù)定期讀取。一般同一類的數(shù)據(jù)使用一個(gè) Topic 傳輸,同時(shí) Message Queue 一般都支持 Partition 的機(jī)制。即在向 MQ 中發(fā)送一條數(shù)據(jù)時(shí),可以指定將該條數(shù)據(jù)發(fā)送到哪個(gè) Partition;在從 MQ 中讀取數(shù)據(jù)時(shí),可以指定只讀取哪些 Partition 的數(shù)據(jù)。例如上文的例子,存儲(chǔ)商品數(shù)據(jù)的服務(wù)器分了四個(gè)組,因此可以將傳輸商品更新數(shù)據(jù)的 Topic 劃分為四個(gè) Partition,每個(gè)分組的機(jī)器只需要訂閱其需要的 Partition 即可。在實(shí)際操作中,為了保持未來的擴(kuò)展性,一般 Partition 的數(shù)量都會(huì)設(shè)置為分組數(shù)量的若干倍,例如八個(gè)或者十六個(gè),這樣在未來數(shù)據(jù)量進(jìn)一步增長導(dǎo)致分組個(gè)數(shù)進(jìn)一步增加時(shí),不需要修改 MQ 的 Partition 配置。
利用 MQ 這個(gè)機(jī)制,可以使每臺(tái)機(jī)器只訂閱自己需要處理的數(shù)據(jù),減少帶寬,也減少更新時(shí)處理的數(shù)據(jù)量,避免浪費(fèi)資源。
服務(wù)管理的復(fù)雜性
在我們管理上下游機(jī)器時(shí),一般會(huì)使用以 ZooKeeper 為核心的服務(wù)管理系統(tǒng)。即每個(gè)服務(wù)都注冊(cè)在 ZooKeeper 中,當(dāng)上游服務(wù)需要訪問下游服務(wù)時(shí),去 ZooKeeper 中查詢可用的下游服務(wù)列表,并同時(shí)考慮負(fù)載均衡等因素,選擇最合適的一個(gè)下游服務(wù)實(shí)例。
當(dāng)一個(gè)服務(wù)出現(xiàn)分組時(shí),管理的難度會(huì)增大。服務(wù)管理系統(tǒng)需要確保一個(gè)服務(wù)的每個(gè)分組的實(shí)例同樣多,并且負(fù)載基本保持平衡。另外,當(dāng)任何一臺(tái)機(jī)器出現(xiàn) 故障導(dǎo)致的宕時(shí),需要啟動(dòng)備用機(jī)器。這時(shí),需要判斷是哪個(gè)分組的機(jī)器發(fā)生了故障,并啟動(dòng)相關(guān)分組的機(jī)器實(shí)例,重新注冊(cè)到 ZK 中。
無法拆分的數(shù)據(jù)
有很多數(shù)據(jù)是無法拆分的。一方面有些數(shù)據(jù)是天然不可拆分的,例如各種策略使用的詞典;另一方面,有些數(shù)據(jù)即使可以拆分,但和系統(tǒng)中其他數(shù)據(jù)的拆分規(guī)則不同,那么系統(tǒng)也無法保證所有數(shù)據(jù)都能被拆分,只能優(yōu)先拆分主要數(shù)據(jù)。
1.2 垂直拆分
在傳統(tǒng)關(guān)系型數(shù)據(jù)庫的設(shè)計(jì)上,垂直拆分是指將一種數(shù)據(jù)的不同列進(jìn)行拆分;在對(duì)系統(tǒng)架構(gòu)的設(shè)計(jì)上,垂直拆分是只將一個(gè)服務(wù)的不同計(jì)算邏輯拆分為多個(gè)服務(wù)。在使用垂直拆分的方案時(shí),需要重點(diǎn)考慮以下問題:
增加網(wǎng)絡(luò)請(qǐng)求次數(shù),增加系統(tǒng)響應(yīng)時(shí)間
如果是對(duì)響應(yīng)時(shí)間要求很高的系統(tǒng),一定會(huì)盡可能地避免垂直拆分,例如搜索。而有一些對(duì)邏輯確實(shí)很復(fù)雜,對(duì)時(shí)間又不太敏感的系統(tǒng),一般都會(huì)優(yōu)先選擇垂直拆分,例如支付。
增加系統(tǒng)復(fù)雜度
將服務(wù)進(jìn)行了分層,更加了開發(fā)成本,對(duì)運(yùn)維的要求也更高。
數(shù)據(jù)冗余
有一些數(shù)據(jù)會(huì)被拆分過的多個(gè)服務(wù)使用,會(huì)出現(xiàn)在上下游多個(gè)服務(wù)中,那么數(shù)據(jù)的分發(fā)、更新都會(huì)更加復(fù)雜,即浪費(fèi)資源,又進(jìn)一步增加了系統(tǒng)的復(fù)雜度。因此,在垂直拆分的過程中,一定要盡可能將服務(wù)的功能做良好的劃分,避免一種數(shù)據(jù)被多個(gè)服務(wù)使用的情況。
垂直拆分的方案中,有一種情況可以大幅減少機(jī)器數(shù)量,即:一部分?jǐn)?shù)據(jù)的存在并不是在處理請(qǐng)求的時(shí)候被直接使用,其存在是為了維護(hù)被處理請(qǐng)求的邏輯直接使用的數(shù)據(jù)。
一個(gè)典型的例子是檢索服務(wù)中的正排索引。檢索服務(wù)在查詢時(shí),直接使用的是倒排索引,而倒排索引是根據(jù)正排索引生成的。正排索引往往有多種數(shù)據(jù),當(dāng)一條數(shù)據(jù)發(fā)生更新時(shí),會(huì)影響其他類別的數(shù)據(jù)。因此,一條數(shù)據(jù)的更新信息無法被單獨(dú)處理,在系統(tǒng)的內(nèi)存中往往同時(shí)維護(hù)正排索引和倒排索引,導(dǎo)致內(nèi)存翻倍。這種情況下,如果我們把正排索引獨(dú)立到一臺(tái)離線機(jī)器中,這臺(tái)機(jī)器維護(hù)正排索引的全部數(shù)據(jù),當(dāng)正排索引發(fā)生更新時(shí),倒排索引的更新信息,并分發(fā)給所有在線機(jī)器。那么,在線服務(wù)就不需要維護(hù)正排索引,能夠大幅度減少內(nèi)存的使用。
1.3 綜述
實(shí)際情況中,大型系統(tǒng)往往同時(shí)使用水平拆分和垂直拆分兩種方案。一方面,水平拆分雖然服務(wù)內(nèi)部進(jìn)行了分組,但對(duì)外仍然是單一的服務(wù),因此從業(yè)務(wù)邏輯上來講更加簡單。另一方面,垂直拆分可以將非常復(fù)雜、計(jì)算資源有不同需求的業(yè)務(wù)邏輯進(jìn)行很好的隔離,方便系統(tǒng)中各業(yè)務(wù)邏輯可以針對(duì)自己的特點(diǎn)進(jìn)行開發(fā)和部署。因此,在選擇拆分方案時(shí),要結(jié)合系統(tǒng)的主要矛盾以及目前團(tuán)隊(duì)成員的技術(shù)特點(diǎn),綜合考慮做出選擇。
2. 多級(jí)存儲(chǔ)
俗話說,當(dāng)上帝為你關(guān)上了一扇門,必(可)定(能)為你打開了一扇窗。如果說大數(shù)據(jù)是上帝為架構(gòu)師關(guān)上的一扇門,那么熱點(diǎn)數(shù)據(jù)就是打開的那扇窗。雖然在現(xiàn)實(shí)世界中的數(shù)據(jù)是海量難以估算的,但幸運(yùn)的是,有價(jià)值或者說值得關(guān)注的數(shù)據(jù)總是少數(shù)的。在大型系統(tǒng)中,請(qǐng)永遠(yuǎn)把二八法則的重要性放在第一位。
一般來說,計(jì)算機(jī)的存儲(chǔ)系統(tǒng)分為三級(jí):CPU Cache,內(nèi)存,磁盤。這三者的訪問速度依次降低(并且是數(shù)量級(jí)的降低),單位存儲(chǔ)的成本也依次降低(也是數(shù)量級(jí)的降低)。多級(jí)存儲(chǔ)的基本思想是,按照被訪問頻率的不同給數(shù)據(jù)分類,訪問頻率越高的數(shù)據(jù)應(yīng)當(dāng)放在訪問速度越快的存儲(chǔ)介質(zhì)中。
三種系統(tǒng)都使用頁式存儲(chǔ)的結(jié)構(gòu),頁也是其處理數(shù)據(jù)的最小單位。由于這個(gè)特性,我們一般在編寫程序時(shí),盡可能地將連續(xù)訪問的數(shù)據(jù)放在內(nèi)存的相鄰位置,以提高CPU Cache的命中率,也就是常說的 locality principle。
隨著SSD的出現(xiàn),對(duì)磁盤的使用已經(jīng)出現(xiàn)了新的方法論。機(jī)械磁盤的隨機(jī)讀寫速度在10ms左右,不太可能供實(shí)時(shí)系統(tǒng)使用。而SSD磁盤的隨機(jī)讀寫速度在100us左右,對(duì)于有些秒級(jí)響應(yīng)的系統(tǒng)來說,已經(jīng)可以作為實(shí)時(shí)系統(tǒng)的存儲(chǔ)介質(zhì)。一種典型的情況是系統(tǒng)存在相當(dāng)數(shù)量的冷門數(shù)據(jù)。系統(tǒng)對(duì)于熱點(diǎn)數(shù)據(jù)可以快速地反饋,對(duì)于很少被訪問的冷門數(shù)據(jù)可以存儲(chǔ)在SSD磁盤中。當(dāng)冷門數(shù)據(jù)被訪問時(shí),只要latency仍然可以控制在秒級(jí),就可以在保證用戶體驗(yàn)只有很少的損害的情況下,大幅減少系統(tǒng)成本。
一種典型的場(chǎng)景是電商的商品信息。經(jīng)常被訪問的商品可能不到商品總量的1%。像淘寶這樣規(guī)模的電商系統(tǒng),實(shí)際可能比1%還低。
另一種典型的場(chǎng)景是用戶評(píng)論。無論按評(píng)論發(fā)表的先后順序,還是按某種規(guī)則計(jì)算出的評(píng)論的質(zhì)量度排序,總是前100個(gè)左右的評(píng)論被經(jīng)常訪問,后面的評(píng)論幾乎不會(huì)被訪問到。
另外,回想上文提到的檢索服務(wù)的案例。正排索引除了可以拆分為單獨(dú)的服務(wù)之外,還可以存儲(chǔ)在磁盤中。更新正排索引的時(shí)候直接從磁盤讀取數(shù)據(jù),修改后寫會(huì)磁盤,同時(shí)更新內(nèi)存的倒排索引。如果使用SSD磁盤,雖然更新的延遲會(huì)增長,但也會(huì)控制在毫秒級(jí),對(duì)于系統(tǒng)完全是可以接受的。要知道,在一條數(shù)據(jù)到達(dá)檢索服務(wù)之前,都會(huì)經(jīng)過若干次網(wǎng)絡(luò)傳輸,由磁盤引起的延遲并不是主要因素。
在使用磁盤作為可以提供實(shí)時(shí)查詢功能的存儲(chǔ)介質(zhì)時(shí),很常見的方案是將磁盤作為二級(jí)緩存,將最近訪問的數(shù)據(jù)保存在內(nèi)存中,當(dāng)訪問的數(shù)據(jù)不在內(nèi)存中時(shí),從磁盤讀取,并放入內(nèi)存中。這個(gè)方案的假設(shè)是,最近被訪問的數(shù)據(jù)很可能在接下來仍然被訪問。采用這種方案需要重點(diǎn)注意,防止爬蟲或者外部的惡意請(qǐng)求短期內(nèi)訪問大量冷門數(shù)據(jù),造成實(shí)際的熱點(diǎn)數(shù)據(jù)被換出緩存,導(dǎo)致處理真實(shí)請(qǐng)求時(shí)有大量的緩存失效。
大數(shù)據(jù)技術(shù)對(duì)商業(yè)效果的提升已經(jīng)在越來越多的行業(yè)中被證明,未來的服務(wù),無論是在線還是離線,處理的數(shù)據(jù)都會(huì)有數(shù)量級(jí)甚至幾個(gè)數(shù)量級(jí)的增長。同時(shí),我們看到內(nèi)存除了訪問速度越來越快,在存儲(chǔ)的數(shù)據(jù)量和成本上并沒有太大的變化。因此,未來越來越多的系統(tǒng)的主要瓶頸會(huì)從計(jì)算、IO轉(zhuǎn)移到數(shù)據(jù)量上,內(nèi)存密集型系統(tǒng)會(huì)變得越來越重要,相信其架構(gòu)在未來幾年也會(huì)有很多新的方式出現(xiàn)。
核心關(guān)注:拓步ERP系統(tǒng)平臺(tái)是覆蓋了眾多的業(yè)務(wù)領(lǐng)域、行業(yè)應(yīng)用,蘊(yùn)涵了豐富的ERP管理思想,集成了ERP軟件業(yè)務(wù)管理理念,功能涉及供應(yīng)鏈、成本、制造、CRM、HR等眾多業(yè)務(wù)領(lǐng)域的管理,全面涵蓋了企業(yè)關(guān)注ERP管理系統(tǒng)的核心領(lǐng)域,是眾多中小企業(yè)信息化建設(shè)首選的ERP管理軟件信賴品牌。
轉(zhuǎn)載請(qǐng)注明出處:拓步ERP資訊網(wǎng)http://www.guhuozai8.cn/
本文標(biāo)題:數(shù)據(jù)密集型系統(tǒng)架構(gòu)設(shè)計(jì)
本文網(wǎng)址:http://www.guhuozai8.cn/html/support/11121519332.html