上一篇書評(píng)向大家推薦了 Desinging Data-Intensive Applications 這本書屋吨。由這本書啟發(fā),我也想整理一下自己在大數(shù)據(jù)這一塊的知識(shí)體系被因。首先蝗蛙,我們要理解數(shù)據(jù)系統(tǒng)面對(duì)的場(chǎng)景和挑戰(zhàn),我們才能更好的理解其設(shè)計(jì)動(dòng)機(jī)和原理敲长。本文主要總結(jié)這些場(chǎng)景和挑戰(zhàn)郎嫁,會(huì)提到一些目前的相應(yīng)技術(shù),但不會(huì)展開講祈噪。后續(xù)系列文章會(huì)漸漸深入分析這些技術(shù)泽铛。本文的目的是描繪一個(gè)概括性的邏輯性的框架。
基本數(shù)據(jù)存取
我們從最簡(jiǎn)單的場(chǎng)景開始辑鲤,對(duì)于一個(gè)數(shù)據(jù)系統(tǒng)盔腔,最基本的需求就是數(shù)據(jù)的存取,在某個(gè)時(shí)間點(diǎn),把數(shù)據(jù)存起來弛随,下一個(gè)時(shí)間點(diǎn)再把數(shù)據(jù)取出來[1]瓢喉。
似乎一個(gè)簡(jiǎn)單的append only 文件就可以滿足這個(gè)需求,每次存數(shù)據(jù)就是寫文件舀透,取數(shù)據(jù)就從文件讀栓票。然而這樣的話,查找一個(gè)特定數(shù)據(jù)就需要全局掃描愕够,效率低下走贪。這里引出了第一個(gè)挑戰(zhàn):存取效率。一方面惑芭,我們有hash索引厉斟、Btree、LSM樹等技術(shù)來提高查找效率强衡。另一方面擦秽,我們針對(duì)數(shù)據(jù)訪問模式(OLAP),改變數(shù)據(jù)存儲(chǔ)方式(列式存儲(chǔ))漩勤,提高讀取效率感挥。
有的數(shù)據(jù)存取操作之間是綁定的,應(yīng)用會(huì)希望綁定的操作要么全部成功越败,要么都不成功触幼,也就是原子性。當(dāng)多個(gè)客戶端同時(shí)訪問數(shù)據(jù)時(shí)究飞,應(yīng)用希望這些訪問就像是順序發(fā)生的(Serializability)置谦,所有并發(fā)可能引起的問題都應(yīng)該避免掉,也就是隔離性亿傅。Transaction主要就是為了應(yīng)對(duì)這兩個(gè)挑戰(zhàn)媒峡。[2]
大規(guī)模數(shù)據(jù)存取
當(dāng)數(shù)據(jù)量和訪問規(guī)模大到一定程度,為了突破單機(jī)的性能瓶頸葵擎,我們會(huì)希望不同的用戶可以通過不同的節(jié)點(diǎn)訪問數(shù)據(jù)谅阿,提高吞吐量,同時(shí)部分節(jié)點(diǎn)故障不影響系統(tǒng)服務(wù)酬滤,提高可用性签餐。因此,我們會(huì)做Replication盯串,把同一份數(shù)據(jù)保存到多個(gè)不同的節(jié)點(diǎn)氯檐。我們會(huì)做Partitioning,把數(shù)據(jù)集按照一定策略劃分成一個(gè)個(gè)分區(qū)体捏,每個(gè)節(jié)點(diǎn)負(fù)責(zé)一個(gè)或幾個(gè)分區(qū)冠摄。
當(dāng)我們做了Replication糯崎,一份數(shù)據(jù)有多個(gè)副本,理想情況下耗拓,我們希望不同客戶端對(duì)數(shù)據(jù)的訪問不要出現(xiàn)不一致,仍然就像只有一個(gè)副本一樣(Linearizability/strong consistency)奏司。而當(dāng)從單機(jī)數(shù)據(jù)系統(tǒng)擴(kuò)展到集群之后乔询,我們會(huì)面臨分布式系統(tǒng)無法避免的三個(gè)問題。機(jī)器不可靠韵洋,單個(gè)節(jié)點(diǎn)故障的幾率不高竿刁,但是大規(guī)模集群中有節(jié)點(diǎn)故障概率就很高;網(wǎng)絡(luò)不可靠搪缨,通過網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)可能會(huì)延遲食拜,也可能會(huì)丟失;時(shí)間不可靠副编,機(jī)器時(shí)鐘的誤差會(huì)累積负甸,而通過網(wǎng)絡(luò)同步時(shí)間,網(wǎng)絡(luò)又有延遲痹届,所以全局時(shí)間無法一致呻待。為此,我們抽象出了共識(shí)問題(Consensus)队腐,提出了各種算法(Paxos蚕捉、Raft)來解決這個(gè)問題。因?yàn)榻鉀Q了這個(gè)問題柴淘,Linearizability就好實(shí)現(xiàn)了迫淹。
保證Linearizability有時(shí)候會(huì)損失可用性(CAP)。因此为严,我們會(huì)根據(jù)具體情況敛熬,適當(dāng)降低一致性要求,提供各種不同的一致性保證第股,即最終一致性荸型。
數(shù)據(jù)生態(tài)
同一份數(shù)據(jù)我們可以有不同的用途。例如在一個(gè)電商系統(tǒng)中炸茧,商品瑞妇、訂單、支付梭冠、物流等數(shù)據(jù)辕狰,支撐著整個(gè)業(yè)務(wù)流程,隨著業(yè)務(wù)進(jìn)行更新(OLTP)控漠。同時(shí)蔓倍,公司的決策層需要判斷電商行業(yè)的發(fā)展趨勢(shì)悬钳,例如需要查看不同年齡段消費(fèi)者購(gòu)買不同品類商品所占比例隨年份變化的情況。要滿足這類數(shù)據(jù)需求(OLAP)偶翅,需要對(duì)業(yè)務(wù)數(shù)據(jù)進(jìn)行連接默勾、過濾、聚合等計(jì)算操作聚谁。為了提高查詢效率母剥,我們不會(huì)每次OLAP查詢都重新從業(yè)務(wù)數(shù)據(jù)庫(kù)計(jì)算。而是事先把這些數(shù)據(jù)預(yù)處理形导,按照星型模型或雪花模型單獨(dú)存在一個(gè)數(shù)據(jù)庫(kù)中环疼。
現(xiàn)在,我們除了業(yè)務(wù)數(shù)據(jù)庫(kù)朵耕,還增加了一個(gè)數(shù)據(jù)冗余的OLAP數(shù)據(jù)倉(cāng)庫(kù)炫隶。一般數(shù)據(jù)倉(cāng)庫(kù)中的數(shù)據(jù)每天凌晨用很多較大的批處理任務(wù)更新。對(duì)于批處理作業(yè)我們優(yōu)先考慮的是吞吐量阎曹。批處理作業(yè)處理的數(shù)據(jù)量大伪阶,時(shí)間長(zhǎng),我們希望其有較好的容錯(cuò)性处嫌,不能由于某些局部錯(cuò)誤導(dǎo)致整個(gè)作業(yè)重跑望门。這些批處理任務(wù)一般是MR或Spark任務(wù),它們用不同的方法提供容錯(cuò)性锰霜,Spark效率更高筹误。Hive和SparkSQL使我們可以用簡(jiǎn)單的SQL語(yǔ)句創(chuàng)建這些任務(wù)。即使我們有了數(shù)據(jù)倉(cāng)庫(kù)癣缅,對(duì)于多數(shù)OLAP查詢的結(jié)果仍然要進(jìn)行計(jì)算才能得到厨剪,對(duì)于這種即時(shí)查詢,查詢速度更加重要友存,presto和kylin從不同的角度優(yōu)化這類查詢的效率祷膳。
數(shù)據(jù)倉(cāng)庫(kù)的數(shù)據(jù)每天更新一次,意味著我們的OLAP查詢無法反映實(shí)時(shí)的數(shù)據(jù)屡立。為了對(duì)實(shí)時(shí)的數(shù)據(jù)進(jìn)行計(jì)算直晨,我們需要不同于批處理的計(jì)算模式,也就是流式計(jì)算膨俐。對(duì)于流式計(jì)算勇皇,數(shù)據(jù)隨著時(shí)間不停的產(chǎn)生,沒有邊界焚刺。相對(duì)于固定輸入的批處理敛摘,這帶來一些新的挑戰(zhàn)。首先乳愉,要對(duì)數(shù)據(jù)的傳輸進(jìn)行負(fù)載均衡路由和限流兄淫,防止計(jì)算模塊處理不過來屯远。其次,數(shù)據(jù)可能會(huì)延遲捕虽,且沒有邊界慨丐,join之類的計(jì)算需要考慮的情況更多了。最后泄私,輸入數(shù)據(jù)不是固定的房揭,容錯(cuò)也不像批處理一樣重試即可。另外挖滤,我們還要考慮流式計(jì)算與批處理如何統(tǒng)一起來崩溪。
除了OLAP應(yīng)用浅役,我們可能還會(huì)有其它的數(shù)據(jù)應(yīng)用斩松,如推薦系統(tǒng)、搜索服務(wù)等觉既。這些都相應(yīng)的有更合適的數(shù)據(jù)模型和存儲(chǔ)惧盹,而其中部分?jǐn)?shù)據(jù)也可能來源于業(yè)務(wù)數(shù)據(jù)庫(kù)。一個(gè)完整的數(shù)據(jù)系統(tǒng)瞪讼,除了原始的數(shù)據(jù)庫(kù)钧椰,還有各種衍生的不同模型的冗余數(shù)據(jù)庫(kù)。因此符欠,要保證這整個(gè)數(shù)據(jù)系統(tǒng)的正確穩(wěn)定運(yùn)行嫡霞,不僅要提供單個(gè)數(shù)據(jù)庫(kù)的可靠性和容錯(cuò)性,還要考慮數(shù)據(jù)流動(dòng)的整個(gè)生命周期可能出現(xiàn)的各種問題希柿。
[1] 這里的數(shù)據(jù)指的是結(jié)構(gòu)化的數(shù)據(jù)诊沪,由數(shù)據(jù)單元(可以是一條記錄、一個(gè)事件)組成曾撤,每個(gè)數(shù)據(jù)單元至少可劃分成key和value端姚。如果是毫無結(jié)構(gòu)化的數(shù)據(jù)存儲(chǔ),那單純就是文件系統(tǒng)做的事了挤悉。
[2] Transaction除了原子性和隔離性渐裸,還有一致性和持久性兩個(gè)特性。其中一致性其實(shí)是針對(duì)應(yīng)用來說的装悲,且相對(duì)來說昏鹃,前兩個(gè)特性的實(shí)現(xiàn)比較有挑戰(zhàn)性。