“打敗”CAP定理
分享 2011.12.08 瀏覽次數(shù):7570次
“打敗”CAP定理
標(biāo)簽:網(wǎng)站建設(shè) 網(wǎng)站制作 杭州網(wǎng)站制作 CAP定理
CAP定理是數(shù)據(jù)系統(tǒng)設(shè)計(jì)的基本理論,目前幾乎所有的數(shù)據(jù)系統(tǒng)的設(shè)計(jì)都遵循了這個(gè)定理。但CAP定理給目前的數(shù)據(jù)系統(tǒng)帶來了許多復(fù)雜的、不可控的問題,使得數(shù)據(jù)系統(tǒng)的設(shè)計(jì)越來越復(fù)雜。Twitter首席工程師、Storm的作者Nathan Marz在本文中通過避開CAP定理帶來的諸多復(fù)雜問題,展示了一個(gè)不同于以往的數(shù)據(jù)系統(tǒng)設(shè)計(jì)方案,給我們的數(shù)據(jù)系統(tǒng)設(shè)計(jì)帶來了全新的思路。
CAP定理指出,一個(gè)數(shù)據(jù)庫不可能同時(shí)滿足一致性(Consistency)、可用性(Availability)和分區(qū)容錯(cuò)性(Partition-Tolerance)。
一致性(Consistency)是指執(zhí)行了一次成功的寫操作之后,未來的讀操作一定可以讀到這個(gè)寫入的值??捎眯裕ˋvailability)是指系統(tǒng)總是可讀可寫的。Yammer的Coda Hale和Cloudera的Henry Robinson都闡述過,分區(qū)容錯(cuò)性是不能犧牲的,因此只能在一致性和可用性上做取舍,如何處理這種取舍正是目前NoSQL數(shù)據(jù)庫的核心焦點(diǎn)。
選擇一致性而不是可用性的系統(tǒng)將面臨一些尷尬的問題,當(dāng)系統(tǒng)不可用時(shí)怎么辦?你可以對寫操作進(jìn)行緩沖處理,但如果存儲緩沖數(shù)據(jù)的機(jī)器出現(xiàn)故障,客戶端將丟失寫入的值。同樣地,緩沖寫也可以被認(rèn)為是一種非一致性的操作,因?yàn)榭蛻舳苏J(rèn)為成功的寫入實(shí)際上并沒有寫入到實(shí)際的數(shù)據(jù)庫中。當(dāng)然,系統(tǒng)可以在機(jī)器不可用時(shí)向客戶端返回錯(cuò)誤,但可以想象,一個(gè)經(jīng)常告訴客戶端“請重試”的產(chǎn)品是多么令人討厭。
另一個(gè)方案是選擇可用性放棄一致性。這種情況下最好的一致性保障是“最終一致性”(Eventually Consistency)。當(dāng)使用最終一致性的系統(tǒng)時(shí),客戶端有時(shí)會讀到與剛剛寫入數(shù)據(jù)不同的數(shù)據(jù)。有時(shí)候,同一時(shí)間同一個(gè)key的多個(gè)請求有可能返回不同的結(jié)果。數(shù)據(jù)更新并不能及時(shí)在所有的復(fù)制節(jié)點(diǎn)上生效,所以不同的復(fù)制節(jié)點(diǎn)上可能讀取到的是不同的值。當(dāng)你檢測到數(shù)據(jù)不一致性時(shí),你需要進(jìn)行修復(fù)(Repair)操作,這就需要使用矢量時(shí)鐘(vector clock)記錄數(shù)據(jù)的版本歷史并合并不同的數(shù)據(jù)更新(這稱為讀取修復(fù),read repair)。
我相信在應(yīng)用層維護(hù)最終一致性對開發(fā)人員負(fù)擔(dān)太重,開發(fā)人員極易弄錯(cuò)讀取修復(fù)的代碼,而一旦開發(fā)人員犯錯(cuò),有問題的讀取修復(fù)將對數(shù)據(jù)庫系統(tǒng)造成不可逆的損壞。
所以犧牲可用性時(shí)問題會很多,犧牲一致性時(shí)構(gòu)建和維護(hù)系統(tǒng)的復(fù)雜度又很高,但這里又只有兩個(gè)選擇,不管怎樣做都會不完美。CAP定理是改不了的,那么還有什么其他可能的選擇嗎?
實(shí)際上,還有一個(gè)辦法:你并不能避開CAP定理,但可以把復(fù)雜的問題獨(dú)立出來,免得你喪失對整個(gè)系統(tǒng)的掌控能力。CAP定理帶來的復(fù)雜性,其實(shí)是我們?nèi)绾螛?gòu)建數(shù)據(jù)系統(tǒng)這一根本問題的體現(xiàn)。其中有兩點(diǎn)特別重要:數(shù)據(jù)庫中可變狀態(tài)和更新狀態(tài)的增量算法。復(fù)雜性正是這兩點(diǎn)和CAP定理之間的相互作用導(dǎo)致的。
本文將通過一個(gè)數(shù)據(jù)庫系統(tǒng)的設(shè)計(jì),來說明如何解決CAP定理通常會造成的復(fù)雜性問題。但我要做的不僅僅如此,CAP定理是一個(gè)針對機(jī)器發(fā)生錯(cuò)誤時(shí)系統(tǒng)容錯(cuò)性的一個(gè)定理,而這里有比機(jī)器容錯(cuò)性更加重要的容錯(cuò)性——人為操作容錯(cuò)性。在軟件開發(fā)中一個(gè)確定的事實(shí)是,開發(fā)人員都并非完人,產(chǎn)品中難免有一些Bug,我們的系統(tǒng)必須對有Bug的程序?qū)懭氲腻e(cuò)誤數(shù)據(jù)有足夠的適應(yīng)能力,我要展示的系統(tǒng)將是這樣一個(gè)可以容忍人為錯(cuò)誤的系統(tǒng)。
本文將挑戰(zhàn)你對數(shù)據(jù)系統(tǒng)如何構(gòu)建這一問題的假設(shè),通過顛覆傳統(tǒng)數(shù)據(jù)系統(tǒng)構(gòu)建方法,我會讓大家看到一個(gè)前所未見的優(yōu)雅、擴(kuò)展性強(qiáng)、健壯的數(shù)據(jù)系統(tǒng)。
什么是數(shù)據(jù)系統(tǒng)?
在開始介紹系統(tǒng)設(shè)計(jì)之前,讓我們先來看看我們要解決的問題:數(shù)據(jù)系統(tǒng)的目的在于什么? 什么是數(shù)據(jù)? 在我們考慮CAP定理之前,我們必須給出一個(gè)可以適用于所有數(shù)據(jù)應(yīng)用程序的定義來回答上述問題。
數(shù)據(jù)應(yīng)用程序種類很多,包括存入和提取數(shù)據(jù)對象、連接、聚合、流處理、機(jī)器學(xué)習(xí)等。似乎并不存在一個(gè)對數(shù)據(jù)系統(tǒng)的明確定義,數(shù)據(jù)處理的多樣性使得我們很難用一個(gè)定義來描述。
事實(shí)卻并非如此,下面這個(gè)簡單的定義:
Query = Function(All Data)
概括了數(shù)據(jù)庫和數(shù)據(jù)系統(tǒng)的所有領(lǐng)域。每一個(gè)領(lǐng)域——有50年歷史的RDBMS、索引、OLAP、OLTP、MapReduce、EFL、分布式文件系統(tǒng)、流處理器、NoSQL等——都可以被概括進(jìn)這個(gè)方程。
所謂數(shù)據(jù)系統(tǒng)就是要回答數(shù)據(jù)集問題的系統(tǒng),這些問題我們稱之為“查詢”。上面的方程表明,查詢就是數(shù)據(jù)上的一個(gè)函數(shù)。
上述方程對于實(shí)際使用來說太過于籠統(tǒng),幾乎對復(fù)雜的數(shù)據(jù)系統(tǒng)設(shè)計(jì)不起什么作用。但如果所有的數(shù)據(jù)系統(tǒng)都遵循這個(gè)方程又會怎樣呢?這個(gè)方程是探索我們數(shù)據(jù)系統(tǒng)的第一步,而它最終將引導(dǎo)我們找到“打敗”CAP定理的方法。
這個(gè)方程里面有兩個(gè)關(guān)鍵概念:數(shù)據(jù)、查詢。這兩個(gè)完全不同的概念經(jīng)常被混為一談,所以下面來看看這兩個(gè)概念究竟是什么意思。
數(shù)據(jù)
我們先從“數(shù)據(jù)”開始。所謂數(shù)據(jù)就是一個(gè)不可分割的單位,它肯定存在,就跟數(shù)學(xué)里面的公理一樣。
關(guān)于“數(shù)據(jù)”有兩個(gè)關(guān)鍵的性質(zhì)。首先,數(shù)據(jù)是跟時(shí)間相關(guān)的,一個(gè)真實(shí)的數(shù)據(jù)一定是在某個(gè)時(shí)間點(diǎn)存在于那兒。比如,假如Sally在她的社交網(wǎng)絡(luò)個(gè)人資料中寫她住在芝加哥,你拿到的這個(gè)數(shù)據(jù)肯定是她某個(gè)時(shí)間在芝加哥填寫的。假如某天Sally把她資料里面居住地點(diǎn)更新為亞特蘭大,那么她肯定在這個(gè)時(shí)候是住在亞特蘭大的,但她住在亞特蘭大的事實(shí)無法改變她曾經(jīng)住在芝加哥這個(gè)事實(shí)——這兩個(gè)數(shù)據(jù)都是真實(shí)的。
其次,數(shù)據(jù)無法改變。由于數(shù)據(jù)跟某個(gè)時(shí)間點(diǎn)相關(guān),所以數(shù)據(jù)的真實(shí)性是無法改變的。沒有人可以回到那個(gè)時(shí)間去改變數(shù)據(jù)的真實(shí)性,這說明了對數(shù)據(jù)操作只有兩種:讀取已存在的數(shù)據(jù)和添加更多的新數(shù)據(jù)。那么CRUD就變成了CR【譯者注:CRUD是指Create Read Update Delete,即數(shù)據(jù)的創(chuàng)建、讀取、更新和刪除】。
我去掉了“更新”操作,因?yàn)楦聦τ诓豢筛淖兊臄?shù)據(jù)沒有任何作用。例如,更新Sally的位置信息本質(zhì)上就是在她住的地方數(shù)據(jù)中新加一條最近的位置信息而已。
我同樣去掉了“刪除”操作,因?yàn)榻^大部分刪除操作可以更好地表述為新加一條數(shù)據(jù)。比如Bob在Twitter上不再關(guān)注Mary了,這并不能改變他曾經(jīng)關(guān)注過Mary這個(gè)事實(shí)。所以與其刪除Bob關(guān)注Mary這個(gè)數(shù)據(jù),還不如新加一條Bob在某個(gè)時(shí)間點(diǎn)不再關(guān)注Mary這個(gè)數(shù)據(jù)。
這里只有很少數(shù)的情況需要永久“刪除”數(shù)據(jù),例如規(guī)則要求你每隔一段時(shí)間清掉數(shù)據(jù),這個(gè)情況在我將要展示的系統(tǒng)中有很好的解決方案,所以為了簡潔,我們暫不考慮這些情況。
查詢
查詢是一個(gè)針對數(shù)據(jù)集的推導(dǎo),就像是一個(gè)數(shù)學(xué)里面的定理。例如,你可以通過計(jì)算“Sally現(xiàn)在的位置在哪里”這個(gè)查詢來得到Sally最新的位置數(shù)據(jù)。查詢是整個(gè)數(shù)據(jù)集合上的函數(shù),可以做一切事情:聚合、連接不同類型的數(shù)據(jù)等。因此,你可以查詢系統(tǒng)中女性用戶的數(shù)量,可以查詢最近幾小時(shí)熱門的 Twitter內(nèi)容。
前面我已經(jīng)定義查詢是整個(gè)數(shù)據(jù)集上的函數(shù),當(dāng)然,不是所有的查詢都需要整個(gè)數(shù)據(jù)集,它們只需要數(shù)據(jù)集的一個(gè)子集。但我的定義是涵蓋了所有的查詢類型,如果想要“打敗”CAP定理,我們需要能夠處理所有的查詢。
打敗CAP定理
計(jì)算查詢最簡單的辦法就是按照查詢語義在整個(gè)數(shù)據(jù)集上運(yùn)行一個(gè)函數(shù)。如果這可以滿足你對延遲的要求,那么就沒有其他需要構(gòu)建的了。
可想而知,我們不能指望在整個(gè)數(shù)據(jù)集上的查詢能夠很快完成,特別是那些服務(wù)大型網(wǎng)站、需要每秒處理幾百萬次請求的系統(tǒng)。但假如這種查詢可以很快完成,讓我們來看看像這樣的系統(tǒng)和CAP定理的PK結(jié)果:你將會看到,這個(gè)系統(tǒng)不僅打敗了CAP定理,而且還消滅了它。
CAP定理仍然適用,所以你需要在可用性和一致性上做出選擇,這里的漂亮之處在于,一旦你權(quán)衡之后做出了選擇,你就做完了所有的事情。通常的那些因?yàn)镃AP定理帶來的問題,都可以通過不可改變的數(shù)據(jù)和從原始數(shù)據(jù)中計(jì)算查詢來規(guī)避。
如果你選擇一致性而不是可用性,那么跟以前并沒有多大的區(qū)別,因?yàn)槟惴艞壛丝捎眯?,所以一些時(shí)候你將無法讀取或者寫入數(shù)據(jù)。當(dāng)然這只是針對對強(qiáng)一致性有要求的系統(tǒng)。
如果你選擇可用性而不是一致性,在這種情況下,系統(tǒng)可以達(dá)到最終一致性而且規(guī)避了所有最終一致性帶來的復(fù)雜問題。由于系統(tǒng)總是可用的,所以你總可以寫入新數(shù)據(jù)或者進(jìn)行查詢。在出錯(cuò)情況下,查詢可能返回的不是最近寫入的數(shù)據(jù),但根據(jù)最終一致性,這個(gè)數(shù)據(jù)最終會一致,而查詢函數(shù)最終會把這個(gè)數(shù)據(jù)計(jì)算進(jìn)去。
這里的關(guān)鍵在于數(shù)據(jù)是不可變的。不可變數(shù)據(jù)意味著這里沒有更新操作,所以不可能出現(xiàn)數(shù)據(jù)復(fù)制不同這種不一致的情況,也意味著不需要版本化的數(shù)據(jù)、矢量時(shí)鐘或者讀取修復(fù)。在一個(gè)查詢場景中,一個(gè)數(shù)據(jù)只有存在或者不存在兩種情況。這里只有數(shù)據(jù)和在數(shù)據(jù)之上的函數(shù)。這里沒有需要你為確保最終一致性額外做的事情,最終一致性也不會因此使你的系統(tǒng)變得復(fù)雜。
之前的復(fù)雜度主要來自增量更新操作和CAP定理之間的矛盾,在最終一致性系統(tǒng)中可變的值需要通過讀取修復(fù)來保證最終一致性。通過使用不可變數(shù)據(jù),去掉增量更新,使用不可變數(shù)據(jù),每次從原始數(shù)據(jù)計(jì)算查詢,你可以規(guī)避那些復(fù)雜的問題。CAP定理就被打敗了。
當(dāng)然,現(xiàn)在講的只不過是想法而已,而且每次從原始數(shù)據(jù)計(jì)算查詢基本上不可能。但我們從中可以學(xué)到一些在實(shí)際解決方案中的關(guān)鍵點(diǎn)。
- 數(shù)據(jù)系統(tǒng)因?yàn)椴豢勺償?shù)據(jù)和不斷增長的數(shù)據(jù)集變得簡單了。
- 基本的寫入操作就是寫入一條新的不可變數(shù)據(jù)。
- 數(shù)據(jù)系統(tǒng)通過重新從原始數(shù)據(jù)計(jì)算查詢規(guī)避了CAP定理帶來的復(fù)雜度。
- 數(shù)據(jù)系統(tǒng)利用增量算法使得查詢的返回延遲降低到一個(gè)可以接受的程度。
讓我們開始探索這個(gè)數(shù)據(jù)系統(tǒng)應(yīng)該如何設(shè)計(jì)。請注意從這里開始我們所描述都是針對系統(tǒng)優(yōu)化、數(shù)據(jù)庫、索引、EFL、批量計(jì)算、流處理——這些技術(shù)都是對查詢函數(shù)的優(yōu)化,讓查詢返回時(shí)間降低到一個(gè)可以接受的程度。這很簡單,但也是數(shù)據(jù)系統(tǒng)所面對的現(xiàn)實(shí)。數(shù)據(jù)庫通常是數(shù)據(jù)管理的核心,但它們是更大藍(lán)圖中的一部分。
批量計(jì)算
“如何讓任意一個(gè)函數(shù)可以在任意一個(gè)數(shù)據(jù)集上快速執(zhí)行完成”這個(gè)問題太過于復(fù)雜,所以我們先放寬了一下這個(gè)問題依賴條件。首先假設(shè),可以允許數(shù)據(jù)滯后幾小時(shí)。放寬這個(gè)條件之后,我們可以得到一個(gè)簡單、優(yōu)雅、通用的數(shù)據(jù)系統(tǒng)構(gòu)建解決方案。之后,我們會通過擴(kuò)展這個(gè)解決方案使得它可以不用放寬條件來解決問題。
由于查詢是所有數(shù)據(jù)的一個(gè)函數(shù),讓查詢變快的最簡單的方法就是預(yù)先計(jì)算好這些查詢。只要這里有新的數(shù)據(jù),你就重新計(jì)算這些查詢。這是可能的,因?yàn)槲覀兎艑捔藯l件使得我們的數(shù)據(jù)可以滯后幾個(gè)小時(shí)。圖1展示了這個(gè)工作流程。
圖1 預(yù)計(jì)算工作流程
為了實(shí)現(xiàn)這個(gè),你的系統(tǒng)需要:
- 能很容易存儲大的、不斷增長的數(shù)據(jù)集;
- 能在數(shù)據(jù)集上可擴(kuò)展地計(jì)算查詢函數(shù)。
這樣的系統(tǒng)是存在的,即Hadoop。它是一個(gè)成熟的、經(jīng)歷了無數(shù)團(tuán)隊(duì)實(shí)戰(zhàn)檢驗(yàn)過的系統(tǒng),同時(shí)擁有一個(gè)巨大的工具生態(tài)系統(tǒng)。它雖不完美,但是這里用來做批量處理的最好的一個(gè)工具。
許多人也許會告訴你,Hadoop只適用于那些“非結(jié)構(gòu)化”的數(shù)據(jù),這是完全錯(cuò)誤的看法。Hadoop處理“結(jié)構(gòu)化”的數(shù)據(jù)也很不錯(cuò),通過使用像Thrift或者Protocol Buffers這樣的工具,你可以使用豐富的數(shù)據(jù)結(jié)構(gòu)存儲你的數(shù)據(jù)。
Hadoop由分布式文件系統(tǒng)HDFS和批處理框架MapReduce兩部分構(gòu)成。HDFS可以通過文件存儲大量數(shù)據(jù),MapReduce可以在這樣數(shù)據(jù)上進(jìn)行可擴(kuò)展計(jì)算。這個(gè)系統(tǒng)完全符合我們的要求。
我們將數(shù)據(jù)以文件形式存儲到HDFS中去。文件可以包括一個(gè)數(shù)據(jù)記錄序列。新增數(shù)據(jù)時(shí),我們只需要在包括所有數(shù)據(jù)的文件夾中新增一個(gè)包含這條新記錄的文件即可。像這樣在HDFS存儲數(shù)據(jù)滿足了“能夠很容易存儲大的、不斷增長的數(shù)據(jù)集”這個(gè)要求。
預(yù)計(jì)算數(shù)據(jù)集上的查詢也很直觀,MapReduce是一個(gè)足夠復(fù)雜的框架,使得幾乎所有的函數(shù)都可以按照多個(gè)MapReduce任務(wù)這種方式實(shí)現(xiàn)。像Cascalog、Cascading和Pig這樣的工具使實(shí)現(xiàn)這些函數(shù)變得十分簡單。
最后,為了可以快速訪問這些預(yù)計(jì)算查詢結(jié)果,你需要對查詢結(jié)果進(jìn)行索引,這里有許多數(shù)據(jù)庫可以完成這個(gè)工作。ElephantDB和Voldemort read-only可以通過從Hadoop中導(dǎo)出key/value數(shù)據(jù)來加快查詢速度。這些數(shù)據(jù)庫支持批量寫和隨機(jī)讀,同時(shí)不支持隨機(jī)寫。隨機(jī)寫使得數(shù)據(jù)庫變得復(fù)雜,所以通過不支持隨機(jī)寫,這些數(shù)據(jù)庫設(shè)計(jì)得特別簡潔,也就幾千行代碼而已。簡潔使得這些數(shù)據(jù)庫魯棒性變得非常好。
下面來看批量處理系統(tǒng)整體上是如何配合工作的。假設(shè)寫一個(gè)網(wǎng)站分析程序來跟蹤頁面訪問量,你需要能夠查詢到任意時(shí)間段的頁面訪問量,數(shù)據(jù)是以小時(shí)方式提供的。如圖2所示。
圖2 批處理工程流程示例(timestamp代表時(shí)間戳,count代表個(gè)數(shù))
實(shí)現(xiàn)這個(gè)很簡單,每一個(gè)數(shù)據(jù)記錄包括一個(gè)單一頁面的訪問量。這些數(shù)據(jù)通過文件形式存儲到HDFS中,一個(gè)函數(shù)通過實(shí)現(xiàn)MapReduce計(jì)算任務(wù),來計(jì)算一個(gè)URL下頁面每小時(shí)的訪問量。這個(gè)函數(shù)產(chǎn)生的是key/value對,其中[URL, hour]是key,value是頁面的訪問量。這些key/value對被導(dǎo)出到ElephantDB中去,使得應(yīng)用程序可以快速得到任意[URL, hour]對對應(yīng)的值。如果應(yīng)用程序想要知道某個(gè)時(shí)間范圍內(nèi)某個(gè)頁面的訪問量,它可以查詢ElephantDB中那段時(shí)間內(nèi)的數(shù)據(jù),然后把這些數(shù)據(jù)相加就可以得到這個(gè)訪問量數(shù)據(jù)了。
在數(shù)據(jù)滯后幾小時(shí)這個(gè)缺陷下,批量處理可以計(jì)算任意數(shù)據(jù)集上的任意函數(shù)。系統(tǒng)中的“任意性”是指這個(gè)系統(tǒng)可以處理任何問題。更重要的是,它很簡單,容易理解和完全可擴(kuò)展,你需要考慮的只是數(shù)據(jù)和查詢函數(shù),Hadoop會幫你處理并行的事情。
批處理系統(tǒng)、CAP定理和容忍人為錯(cuò)誤
截至目前,我們的系統(tǒng)都很不錯(cuò),這個(gè)批處理系統(tǒng)是不是可以達(dá)到容忍人為錯(cuò)誤的目標(biāo)呢?
讓我們從CAP定理開始。這個(gè)批處理系統(tǒng)總是最終一致的:寫入的數(shù)據(jù)總可以在幾小時(shí)后被查詢到。這個(gè)系統(tǒng)是一個(gè)很容易掌控的最終一致性系統(tǒng),使得你可以只用關(guān)注你的數(shù)據(jù)和針對數(shù)據(jù)的查詢函數(shù)。這里沒有涉及讀取修復(fù)、并發(fā)和其他一些需要考慮的復(fù)雜問題。
接下來看看這個(gè)系統(tǒng)對人為錯(cuò)誤的容忍性。在這個(gè)系統(tǒng)中人們可能會犯兩個(gè)錯(cuò)誤:部署了一個(gè)有Bug的查詢函數(shù)或者寫入了錯(cuò)誤的數(shù)據(jù)。
如果部署了一個(gè)有Bug的查詢函數(shù),需要做的所有事情就是修正那個(gè)Bug,重新部署這個(gè)查詢函數(shù),然后在主數(shù)據(jù)集上重新計(jì)算它。這之所以能起作用是因?yàn)椴樵冎皇且粋€(gè)函數(shù)而已。
另外,錯(cuò)誤的數(shù)據(jù)有明確的辦法可以恢復(fù):刪除錯(cuò)誤數(shù)據(jù),然后重新計(jì)算查詢。由于數(shù)據(jù)是不可變的,而且數(shù)據(jù)集只是往后添加新數(shù)據(jù),寫入錯(cuò)誤的數(shù)據(jù)不會覆蓋或者刪除正確的數(shù)據(jù),這與傳統(tǒng)數(shù)據(jù)庫更新一個(gè)數(shù)據(jù)就丟掉舊的數(shù)據(jù)形成了鮮明的對比。
注意到MVCC和HBase類似的行版本管理并不能達(dá)到上面人為錯(cuò)誤容忍級別。MVCC和HBase行版本管理不能永久保存數(shù)據(jù),一旦數(shù)據(jù)庫合并了這些版本,舊的數(shù)據(jù)就會丟失。只有不可變數(shù)據(jù)系統(tǒng)能夠保證你在寫入錯(cuò)誤數(shù)據(jù)時(shí)可以找到一個(gè)恢復(fù)數(shù)據(jù)的方法。
實(shí)時(shí)層
上面的批量處理系統(tǒng)幾乎完全解決了在任意數(shù)據(jù)集上運(yùn)行任意函數(shù)的實(shí)時(shí)性需求。任何超過幾個(gè)小時(shí)的數(shù)據(jù)已經(jīng)被計(jì)算進(jìn)入了批處理視圖中,所以剩下來要做的就是處理最近幾個(gè)小時(shí)的數(shù)據(jù)。我們知道在最近幾小時(shí)數(shù)據(jù)上進(jìn)行查詢比在整個(gè)數(shù)據(jù)集上查詢要容易,這是關(guān)鍵點(diǎn)。
為了處理最近幾個(gè)小時(shí)的數(shù)據(jù),需要一個(gè)實(shí)時(shí)系統(tǒng)和批處理系統(tǒng)同時(shí)運(yùn)行。這個(gè)實(shí)時(shí)系統(tǒng)在最近幾個(gè)小時(shí)數(shù)據(jù)上預(yù)計(jì)算查詢函數(shù)。要計(jì)算一個(gè)查詢函數(shù),需要查詢批處理視圖和實(shí)時(shí)視圖,并把它們合并起來以得到最終的數(shù)據(jù)。
圖3 計(jì)算一個(gè)查詢
在實(shí)時(shí)層,可以使用Riak或者Cassandra這種讀寫數(shù)據(jù)庫,而且實(shí)時(shí)層依賴那些數(shù)據(jù)庫中對狀態(tài)更新的增量算法。
讓Hadoop模擬實(shí)時(shí)計(jì)算的工具是Storm。我寫Storm的目的是讓Hadoop可以健壯、可擴(kuò)展地處理大量的實(shí)時(shí)數(shù)據(jù)。Storm在數(shù)據(jù)流上運(yùn)行無限的計(jì)算,并且對這些數(shù)據(jù)處理提供了強(qiáng)有力的保障。
讓我們回到剛才那個(gè)根據(jù)某個(gè)URL查詢某個(gè)頁面在某個(gè)時(shí)間段內(nèi)頁面訪問量的例子,通過這個(gè)例子我將展示實(shí)時(shí)層是如何工作的。
批處理系統(tǒng)還是跟之前一樣:一個(gè)基于Hadoop和ElephantDB的批處理工作流,在幾個(gè)小時(shí)之前的數(shù)據(jù)上預(yù)計(jì)算查詢函數(shù)。剩下就是讓實(shí)時(shí)系統(tǒng)去處理最近幾小時(shí)數(shù)據(jù)了。
我們將最近幾小時(shí)的數(shù)據(jù)狀態(tài)存入Cassandra中,用Storm去處理頁面訪問量數(shù)據(jù)流并并行更新到數(shù)據(jù)庫中,針對每一個(gè)頁面訪問量,在[URL, hour]所代表的key下,有一個(gè)計(jì)數(shù)器,這個(gè)計(jì)數(shù)器在Cassandra中實(shí)現(xiàn)。這就是所有的事情,Storm讓事情變得非常簡單。
圖4 批處理/實(shí)時(shí)架構(gòu)示例
批處理層+實(shí)時(shí)層、CAP定理和人為錯(cuò)誤容忍性
貌似又回到一開始提出的問題上去了,訪問實(shí)時(shí)數(shù)據(jù)需要使用NoSQL數(shù)據(jù)庫和增量算法。這就說明回到了版本化數(shù)據(jù)、矢量時(shí)鐘和讀取修復(fù)這些復(fù)雜問題中來。但這是有本質(zhì)區(qū)別的。由于實(shí)時(shí)層只處理最近幾小時(shí)的數(shù)據(jù),所有實(shí)時(shí)層的計(jì)算都會被最終批處理層重新計(jì)算。所以如果犯了什么錯(cuò)誤或者實(shí)時(shí)層出了問題,最終都會被批處理層更正過來,所有復(fù)雜的問題都是暫時(shí)的。
這并不意味著不需要關(guān)心實(shí)時(shí)層的讀取修復(fù)和最終一致性,你仍然需要實(shí)時(shí)層盡可能的一致。但當(dāng)犯了一個(gè)錯(cuò)誤時(shí),不會永久性地破壞數(shù)據(jù)。這便移除了許多你所需要面對的復(fù)雜問題。
在批處理層僅需要考慮數(shù)據(jù)和數(shù)據(jù)上的查詢函數(shù),批處理層因此很好掌控。在實(shí)時(shí)層,需要使用增量算法和復(fù)雜的NoSQL數(shù)據(jù)庫。把所有的復(fù)雜問題獨(dú)立到實(shí)時(shí)層中,對系統(tǒng)的魯棒性、可靠性做出了重大貢獻(xiàn)。
同樣的,實(shí)時(shí)層并沒有影響系統(tǒng)的人為錯(cuò)誤容忍性,這個(gè)數(shù)據(jù)不可變和只追加的批處理系統(tǒng),仍然是整個(gè)系統(tǒng)的核心,所以所有的都可以像上面說的一樣被糾正過來。
我有一個(gè)類似的系統(tǒng):Hadoop和ElephantDB組成批處理系統(tǒng),Storm和Cassandra組成實(shí)時(shí)系統(tǒng)。由于缺乏監(jiān)控,某天當(dāng)我起床的時(shí)候發(fā)現(xiàn)Cassandra運(yùn)行滿負(fù)荷了,使得所有的數(shù)據(jù)請求都超時(shí)。這使得Storm計(jì)算失敗,一些數(shù)據(jù)又重新回到了等待隊(duì)列中,這個(gè)數(shù)據(jù)就一次次重復(fù)請求。
如果我沒有批處理層,那么我就需要擴(kuò)展和恢復(fù)Cassandra,這個(gè)很不容易。更糟的是,因?yàn)檎埱蟛粩嗟闹貜?fù),無法得到正確的數(shù)據(jù)。
幸運(yùn)的是,所有的復(fù)雜問題都被隔離到實(shí)時(shí)層中去了,我清空了所有的后臺請求隊(duì)列,把它們打到了批處理層上,同時(shí)重啟了Cassandra集群,過了幾個(gè)小時(shí)之后所有數(shù)據(jù)都恢復(fù)正常了。沒有錯(cuò)誤數(shù)據(jù),請求中也沒有不準(zhǔn)確的地方。
垃圾回收
上面描述的所有東西都是建立在一個(gè)不可變的、不斷增長的數(shù)據(jù)集上的。如果數(shù)據(jù)集已經(jīng)很大,使得不可能用水平擴(kuò)展儲存所有時(shí)間的所有數(shù)據(jù),該如何處理呢?這是不是就推翻了我說的一切呢?是不是需要回到可變數(shù)據(jù)的系統(tǒng)上呢?
不。我們可以很容易地用“垃圾回收”對基本模型進(jìn)行擴(kuò)展來解決上面的問題。垃圾回收是一個(gè)在主數(shù)據(jù)集上的簡單函數(shù),返回的是一個(gè)過濾版本的主數(shù)據(jù)集。垃圾回收掉了舊數(shù)據(jù),可以選擇任意的垃圾回收策略。可以在易變的系統(tǒng)中只保留數(shù)據(jù)最新的一個(gè)值或者保留每個(gè)數(shù)據(jù)的歷史。比如,如果要處理位置數(shù)據(jù),可以保留每人每年的一個(gè)地點(diǎn)??勺冃允且粋€(gè)不是很靈活的垃圾回收形式(它跟CAP定理交互得也很糟糕)。
垃圾回收可以被實(shí)現(xiàn)成批處理的一個(gè)任務(wù),隔段時(shí)間運(yùn)行一下。由于它是作為離線批處理任務(wù)執(zhí)行的,所以不影響我們與CAP定理的交互。
總結(jié)
讓可擴(kuò)展的數(shù)據(jù)系統(tǒng)復(fù)雜的原因不是CAP系統(tǒng),而是數(shù)據(jù)增量算法和數(shù)據(jù)的可變狀態(tài)。最近由于分布式數(shù)據(jù)庫的興起導(dǎo)致了復(fù)雜度越來越不可控。前面講過,我將挑戰(zhàn)對傳統(tǒng)數(shù)據(jù)系統(tǒng)構(gòu)建方法的假設(shè)。我把CRUD變成了CR,把持久化層分成了批處理和實(shí)時(shí)兩個(gè)層,并且得到對人為錯(cuò)誤容忍的能力。我花費(fèi)了多年來之不易的經(jīng)驗(yàn)打破我對傳統(tǒng)數(shù)據(jù)庫的假設(shè),并得到了這些結(jié)論。
批處理/實(shí)時(shí)架構(gòu)有許多有趣的能力我并沒有提到,下面我總結(jié)了一些。
算法的靈活性。隨著數(shù)據(jù)量的增長,一些算法會越來越難計(jì)算。比如計(jì)算標(biāo)識符的數(shù)量,當(dāng)標(biāo)識符集合越來越大時(shí),將會越來越難計(jì)算。批處理/實(shí)時(shí)分離系統(tǒng)給了你在批處理系統(tǒng)上使用精確算法和在實(shí)時(shí)系統(tǒng)上使用近似算法的靈活性。批處理系統(tǒng)計(jì)算結(jié)果會最終覆蓋實(shí)時(shí)系統(tǒng)的計(jì)算結(jié)果,所以最終近似值會被修正,而你的系統(tǒng)擁有了“最終精確性”。
數(shù)據(jù)結(jié)構(gòu)遷移變得很容易。數(shù)據(jù)結(jié)構(gòu)遷移的難題將一去不復(fù)返。由于批量計(jì)算是系統(tǒng)的核心,很容易在整個(gè)系統(tǒng)上運(yùn)行一個(gè)函數(shù),所以很容易更改你數(shù)據(jù)的結(jié)構(gòu)或者視圖。
簡單的Ad-Hoc網(wǎng)絡(luò)。由于批處理系統(tǒng)的任意性,使得你可以在數(shù)據(jù)上進(jìn)行任意查詢。由于所有的數(shù)據(jù)在一個(gè)點(diǎn)上都可以獲取,所以Ad-Hoc網(wǎng)絡(luò)變得簡單而且方便。
自我檢查。由于數(shù)據(jù)是不可變的,數(shù)據(jù)集就可以自我檢查。數(shù)據(jù)集記錄了它的數(shù)據(jù)歷史,對于人為錯(cuò)誤容忍性和數(shù)據(jù)分析很有用。
我并沒有說我已經(jīng)“解決”了數(shù)據(jù)量過大的問題,但我已經(jīng)為解決大數(shù)據(jù)問題制訂了一個(gè)框架。批處理/實(shí)時(shí)架構(gòu)可以應(yīng)用到任何一個(gè)數(shù)據(jù)系統(tǒng)中去,“授人以魚,不如授人以漁”,我已經(jīng)告訴你了如何去構(gòu)建這樣的系統(tǒng)。
為了提高系統(tǒng)整體能力來解決大數(shù)據(jù)的問題,我們還有許多工作需要做。
- 擴(kuò)展數(shù)據(jù)模型,支持批量寫和隨機(jī)讀。不是每一個(gè)應(yīng)用程序都支持key/value的數(shù)據(jù)庫,這也是我們團(tuán)隊(duì)對擴(kuò)展ElephantDB,使得可以支持搜索、文檔數(shù)據(jù)庫、區(qū)間查詢感興趣的原因。
- 更好的批處理原語。Hadoop并不是批處理的最終形態(tài),好多批處理計(jì)算Hadoop效率不高。Spark是一個(gè)有意思的擴(kuò)展MapReduce的項(xiàng)目。
- 提升后的讀寫NoSQL數(shù)據(jù)庫。這里不同類型數(shù)據(jù)的數(shù)據(jù)庫還有很大的提升空間,隨著這些數(shù)據(jù)庫的成熟,它們將收獲很多。
- 高層級的抽象。未來工作中最有意思的就是對批處理模塊和實(shí)時(shí)處理模塊的高層次抽象,在批處理和實(shí)時(shí)架構(gòu)下你沒有理由不擁有一個(gè)簡單的、描述性的、魯棒性好的語言。
許多人需要一個(gè)可擴(kuò)展的關(guān)系型數(shù)據(jù)庫,本文就是想讓你知道完全不需要那個(gè)。大數(shù)據(jù)量和NoSQL運(yùn)動使數(shù)據(jù)管理比RDBMS更加復(fù)雜。那僅僅是因?yàn)槲覍Υ髷?shù)據(jù)的處理采用了跟RDBMS同樣的方法:把數(shù)據(jù)和視圖混為一談,并且依賴增量算法。大數(shù)據(jù)量需要采用完全不同的方式構(gòu)建數(shù)據(jù)系統(tǒng)。通過存儲持續(xù)增長的不可變數(shù)據(jù),并且系統(tǒng)核心采用預(yù)計(jì)算,大數(shù)據(jù)系統(tǒng)就可以變得比關(guān)系型數(shù)據(jù)庫更易掌控,并且可擴(kuò)展性很強(qiáng)。
更多網(wǎng)站建設(shè)IT行業(yè)資訊:開發(fā)者需要Mac的理由是什么?
-
杭州網(wǎng)站設(shè)計(jì)公司:品牌網(wǎng)站開發(fā)助力企業(yè)成長
日期:2024-12-20瀏覽次數(shù):735次
-
杭州網(wǎng)站建設(shè)公司:商城網(wǎng)站建設(shè)的六大關(guān)鍵步驟
日期:2024-12-18瀏覽次數(shù):778次
-
杭州網(wǎng)站制作:醫(yī)院網(wǎng)站設(shè)計(jì)與域名備案的復(fù)雜性探討
日期:2024-12-18瀏覽次數(shù):772次
-
杭州網(wǎng)站制作公司:打造安全可靠的醫(yī)院網(wǎng)站
日期:2024-12-11瀏覽次數(shù):951次
-
杭州網(wǎng)站設(shè)計(jì)公司:數(shù)據(jù)庫在高端網(wǎng)站制作中的關(guān)鍵作用
日期:2024-12-11瀏覽次數(shù):915次
相關(guān)新聞
整合同類新聞,相關(guān)新聞一手掌握
-
論健康相關(guān)產(chǎn)業(yè)的儋州網(wǎng)站建設(shè)
日期:2020-10-26瀏覽次數(shù):2039次
-
儋州網(wǎng)站優(yōu)化:如何設(shè)計(jì)和更新seo文章
日期:2020-10-23瀏覽次數(shù):2135次
-
儋州判斷杭州網(wǎng)站制作公司的實(shí)力
日期:2020-09-09瀏覽次數(shù):2037次
-
儋州網(wǎng)站設(shè)計(jì)公司需要具備這些要素
日期:2020-09-09瀏覽次數(shù):2018次
最新新聞
與互聯(lián)網(wǎng)同行,實(shí)時(shí)掌握網(wǎng)建行業(yè)最新動態(tài)
-
日本風(fēng)格的網(wǎng)站設(shè)計(jì)鑒賞
日期:2016-12-22瀏覽次數(shù):5214次
-
互聯(lián)網(wǎng)行業(yè)程序員新聞
日期:2017-12-26瀏覽次數(shù):5006次
-
杭州網(wǎng)站建設(shè),我們需要了解的重要術(shù)語
日期:2020-12-04瀏覽次數(shù):4129次
-
杭州小程序開發(fā)到底有什么作用?
日期:2021-07-27瀏覽次數(shù):4042次
-
杭州app開發(fā)之小說app開發(fā)細(xì)節(jié)
日期:2023-07-20瀏覽次數(shù):2457次
隨機(jī)新聞
新聞新動態(tài),您需要的新聞管家
洞悉市場趨勢演變讓傳播回歸社會
免費(fèi)獲取網(wǎng)站建設(shè)與網(wǎng)絡(luò)推廣方案報(bào)價(jià)
-
關(guān)于我們
杭州帷拓科技有限公司,是一家新型的全案網(wǎng)絡(luò)開發(fā)公司,作為以互聯(lián)網(wǎng)高端網(wǎng)站建設(shè)、APP開發(fā)、小程序開發(fā)為核心的專業(yè)網(wǎng)絡(luò)技術(shù)服務(wù)供應(yīng)商,帷拓科技致力于全面分析市場環(huán)境、衡量與預(yù)測市場需求、整合區(qū)別于行業(yè)競爭對手的絕對優(yōu)勢,結(jié)合品牌理念深度挖掘項(xiàng)目優(yōu)勢和產(chǎn)品價(jià)值,提升客戶品牌認(rèn)知、認(rèn)可度。
-
我們的客戶
帷拓科技?xì)v經(jīng)十年沉淀,與國內(nèi)外上千家客戶達(dá)成合作關(guān)系,其中穩(wěn)定合作的公司有:浙江華為、浙江移動、浙江5G產(chǎn)業(yè)聯(lián)盟、浙江省社科院、綠城足球俱樂部、娃哈哈雙語學(xué)校、健康中國杭州峰會、科雷機(jī)電等,帷拓科技始終堅(jiān)持“帷有專業(yè),才能拓展無限”的服務(wù)理念,堅(jiān)持“認(rèn)真堅(jiān)持細(xì)節(jié)”的優(yōu)質(zhì)服務(wù)理念,不斷完善自身,成就企業(yè),最終實(shí)現(xiàn)共贏。
-
我們的業(yè)務(wù)
帷拓科技主營業(yè)務(wù)范圍包含互聯(lián)網(wǎng)高端網(wǎng)站建設(shè)、APP開發(fā)、小程序開發(fā)、商城網(wǎng)站建設(shè)、公眾號運(yùn)營以及數(shù)字營銷等,涵蓋了服務(wù)、房產(chǎn)、數(shù)碼、服裝、物流貿(mào)易等行業(yè),根據(jù)品牌現(xiàn)狀,為每個(gè)客戶量身定制項(xiàng)目整體服務(wù)方案,以敏銳的市場洞察力、創(chuàng)新的市場策劃能力,全面把握市場變化,為客戶實(shí)現(xiàn)從企業(yè)到消費(fèi)者的價(jià)值轉(zhuǎn)換。