當(dāng)系統(tǒng)要滿足每秒數(shù)萬次的讀寫請求的需求時碎紊,我們可以用分布式計算佑附、編寫優(yōu)良的程序代碼、對海量數(shù)據(jù)進行分區(qū)操作仗考、建立廣泛的索引音同、建立緩存機制、加大虛擬內(nèi)存秃嗜、分批處理权均、使用數(shù)據(jù)倉庫和多維數(shù)據(jù)庫存儲、使用負載均衡技術(shù)锅锨、將數(shù)據(jù)庫的讀寫分離等等來解決數(shù)據(jù)庫大數(shù)據(jù)訪問的問題叽赊。
隨著互聯(lián)網(wǎng)應(yīng)用的廣泛普及,海量數(shù)據(jù)的存儲和訪問成為了系統(tǒng)設(shè)計的瓶頸問題必搞。對于一個大型的互聯(lián)網(wǎng)應(yīng)用必指,每天百萬級甚至上億的PV(page view即頁面瀏覽量)無疑對數(shù)據(jù)庫造成了相當(dāng)高的負載。對于系統(tǒng)的穩(wěn)定性和擴展性造成了極大的問題恕洲。
一塔橡、那么數(shù)據(jù)庫如何處理海量數(shù)據(jù)呢?
1霜第、編寫優(yōu)良的程序代碼
處理數(shù)據(jù)離不開優(yōu)秀的程序代碼葛家,尤其在進行復(fù)雜數(shù)據(jù)處理時,必須使用程序泌类。好的程序代碼對數(shù)據(jù)的處理至關(guān)重要癞谒,這不僅僅是數(shù)據(jù)處理準確度的問題,更是數(shù)據(jù)處理效率的問題。良好的程序代碼應(yīng)該包含好的算法弹砚,包含好的處理流程双仍,包含好的效率,包含好的異常處理機制等迅栅。
2殊校、對海量數(shù)據(jù)進行分區(qū)操作
對海量數(shù)據(jù)進行分區(qū)操作十分必要,例如針對按年份存取的數(shù)據(jù)读存,我們可以按年進行分區(qū),不同的數(shù)據(jù)庫有不同的分區(qū)方式呕屎,不過處理機制大體相同让簿。例如SQL Server的數(shù)據(jù)庫分區(qū)是將不同的數(shù)據(jù)存于不同的文件組下,而不同的文件組存于不同的磁盤分區(qū)下秀睛,這樣將數(shù)據(jù)分散開尔当,減小磁盤I/O,減小了系統(tǒng)負荷蹂安,而且還可以將日志椭迎,索引等放于不同的分區(qū)下。
3田盈、建立廣泛的索引
對海量的數(shù)據(jù)處理畜号,對大表建立索引是必行的,建立索引要考慮到具體情況允瞧,例如針對大表的分組简软、排序等字段,都要建立相應(yīng)索引述暂,一般還可以建立復(fù)合索引痹升,對 經(jīng)常插入的表則建立索引時要小心,筆者在處理數(shù)據(jù)時畦韭,曾經(jīng)在一個ETL流程中疼蛾,當(dāng)插入表時,首先刪除索引艺配,然后插入完畢察郁,建立索引,并實施聚合操作妒挎,聚合 完成后绳锅,再次插入前還是刪除索引,所以索引要用到好的時機酝掩,索引的填充因子和聚集鳞芙、非聚集索引都要考慮。
注解:(數(shù)據(jù)倉庫技術(shù))
ETL,是英文 Extract-Transform-Load 的縮寫原朝,用來描述將數(shù)據(jù)從來源端經(jīng)過抽妊敝觥(extract)、轉(zhuǎn)換(transform)喳坠、加載(load)至目的端的過程鞠评。ETL一詞較常用在數(shù)據(jù)倉庫,但其對象并不限于數(shù)據(jù)倉庫壕鹉。
ETL是構(gòu)建數(shù)據(jù)倉庫的重要一環(huán)剃幌,用戶從數(shù)據(jù)源抽取出所需的數(shù)據(jù),經(jīng)過數(shù)據(jù)清洗,最終按照預(yù)先定義好的數(shù)據(jù)倉庫模型晾浴,將數(shù)據(jù)加載到數(shù)據(jù)倉庫中去负乡。
4、加大虛擬內(nèi)存
如果系統(tǒng)資源有限脊凰,內(nèi)存提示不足抖棘,則可以靠增加虛擬內(nèi)存來解決。筆者在實際項目中曾經(jīng)遇到針對18億條的數(shù)據(jù)進行處理狸涌,內(nèi)存為1GB切省,1個P4 2.4G的CPU,對這么大的數(shù)據(jù)量進行聚合操作是有問題的帕胆,提示內(nèi)存不足朝捆,那么采用了加大虛擬內(nèi)存的方法來解決,在6塊磁盤分區(qū)上分別建立了6個 4096M的磁盤分區(qū)惶楼,用于虛擬內(nèi)存右蹦,這樣虛擬的內(nèi)存則增加為 4096*6 + 1024 = 25600 M,解決了數(shù)據(jù)處理中的內(nèi)存不足問題歼捐。
5何陆、分批處理
海量數(shù)據(jù)處理難因為數(shù)據(jù)量大,那么解決海量數(shù)據(jù)處理難的問題其中一個技巧是減少數(shù)據(jù)量豹储〈ぃ可以對海量數(shù)據(jù)分批處理,然后處理后的數(shù)據(jù)再進行合并操作剥扣,這樣逐 個擊破巩剖,有利于小數(shù)據(jù)量的處理,不至于面對大數(shù)據(jù)量帶來的問題钠怯,不過這種方法也要因時因勢進行佳魔,如果不允許拆分數(shù)據(jù),還需要另想辦法晦炊。不過一般的數(shù)據(jù)按 天鞠鲜、按月宁脊、按年等存儲的,都可以采用先分后合的方法贤姆,對數(shù)據(jù)進行分開處理榆苞。
6、使用數(shù)據(jù)倉庫和多維數(shù)據(jù)庫存儲
數(shù)據(jù)量加大是一定要考慮OLAP的霞捡,傳統(tǒng)的報表可能5坐漏、6個小時出來結(jié)果,而基于Cube的查詢可能只需要幾分鐘碧信,因此處理海量數(shù)據(jù)的利器是OLAP多維分析赊琳,即建立數(shù)據(jù)倉庫,建立多維數(shù)據(jù)集音婶,基于多維數(shù)據(jù)集進行報表展現(xiàn)和數(shù)據(jù)挖掘等慨畸。
注解:當(dāng)今的數(shù)據(jù)處理大致可以分成兩大類:聯(lián)機事務(wù)處理OLTP(on-line transaction processing)、聯(lián)機分析處理OLAP(On-Line Analytical Processing)衣式。OLTP是傳統(tǒng)的關(guān)系型數(shù)據(jù)庫的主要應(yīng)用,主要是基本的檐什、日常的事務(wù)處理碴卧,例如銀行交易。OLAP是數(shù)據(jù)倉庫系統(tǒng)的主要應(yīng)用乃正,支持復(fù)雜的分析操作住册,側(cè)重決策支持,并且提供直觀易懂的查詢結(jié)果瓮具。下表列出了OLTP與OLAP之間的比較荧飞。
7、使用采樣數(shù)據(jù)名党,進行數(shù)據(jù)挖掘
基于海量數(shù)據(jù)的數(shù)據(jù)挖掘正在逐步興起叹阔,面對著超海量的數(shù)據(jù),一般的挖掘軟件或算法往往采用數(shù)據(jù)抽樣的方式進行處理传睹,這樣的誤差不會很高耳幢,大大提高了處理效率和處理的成功率。一般采樣時要注意數(shù)據(jù)的完整性和欧啤,防止過大的偏差睛藻。筆者曾經(jīng)對1億2千萬行的表數(shù)據(jù)進行采樣,抽取出400萬行邢隧,經(jīng)測試軟件測試處理的誤差為千分之五店印,客戶可以接受。
還有一些方法倒慧,需要在不同的情況和場合下運用按摘,例如使用代理鍵等操作包券,這樣的好處是加快了聚合時間,因為對數(shù)值型的聚合比對字符型的聚合快得多院峡。類似的情況需要針對不同的需求進行處理兴使。
海量數(shù)據(jù)是發(fā)展趨勢,對數(shù)據(jù)分析和挖掘也越來越重要照激,從海量數(shù)據(jù)中提取有用信息重要而緊迫发魄,這便要求處理要準確,精度要高俩垃,而且處理時間要短励幼,得到有價值信息要快,所以口柳,對海量數(shù)據(jù)的研究很有前途苹粟,也很值得進行廣泛深入的研究。
二跃闹、下面注意講解下負載均衡技術(shù)嵌削、數(shù)據(jù)庫的讀寫分離、數(shù)據(jù)庫拆分(分布式)
1望艺、負載均衡技術(shù)
負載均衡集群是由一組相互獨立的計算機系統(tǒng)構(gòu)成苛秕,通過常規(guī)網(wǎng)絡(luò)或?qū)S镁W(wǎng)絡(luò)進行連接,由路由器銜接在一起找默,各節(jié)點相互協(xié)作艇劫、共同負載、均衡壓力惩激,對客戶端來說店煞,整個群集可以視為一臺具有超高性能的獨立服務(wù)器。
實現(xiàn)原理
實現(xiàn)數(shù)據(jù)庫的負載均衡技術(shù)风钻,首先要有一個可以控制連接數(shù)據(jù)庫的控制端顷蟀。在這里,它截斷了數(shù)據(jù)庫和程序的直接連接魄咕,由所有的程序來訪問這個中間層衩椒,然后再由中間層來訪問數(shù)據(jù)庫。這樣哮兰,我們就可以具體控制訪問某個數(shù)據(jù)庫了毛萌,然后還可以根據(jù)數(shù)據(jù)庫的當(dāng)前負載采取有效的均衡策略,來調(diào)整每次連接到哪個數(shù)據(jù)庫喝滞。
實現(xiàn)多據(jù)庫數(shù)據(jù)同步
對于負載均衡阁将,最重要的就是所有服務(wù)器的數(shù)據(jù)都是實時同步的。這是一個集群所必需的右遭,因為做盅,如果數(shù)不據(jù)實時缤削、不同步,那么用戶從一臺服務(wù)器讀出的數(shù)據(jù)吹榴,就有別于從另一臺服務(wù)器讀出的數(shù)據(jù)亭敢,這是不能允許的。所以必須實現(xiàn)數(shù)據(jù)庫的數(shù)據(jù)同步图筹。這樣帅刀,在查詢的時候就可以有多個資源,實現(xiàn)均衡远剩。比較常用的方法是Moebius for SQL Server集群扣溺,Moebius for SQL Server集群采用將核心程序駐留在每個機器的數(shù)據(jù)庫中的辦法,這個核心程序稱為Moebius for SQL Server 中間件瓜晤,主要作用是監(jiān)測數(shù)據(jù)庫內(nèi)數(shù)據(jù)的變化并將變化的數(shù)據(jù)同步到其他數(shù)據(jù)庫中锥余。數(shù)據(jù)同步完成后客戶端才會得到響應(yīng),同步過程是并發(fā)完成的痢掠,所以同步到多個數(shù)據(jù)庫和同步到一個數(shù)據(jù)庫的時間基本相等驱犹;另外同步的過程是在事務(wù)的環(huán)境下完成的椭员,保證了多份數(shù)據(jù)在任何時刻數(shù)據(jù)的一致性代兵。正因為Moebius 中間件宿主在數(shù)據(jù)庫中的創(chuàng)新,讓中間件不但能知道數(shù)據(jù)的變化储矩,而且知道引起數(shù)據(jù)變化的SQL語句锌云,根據(jù)SQL語句的類型智能的采取不同的數(shù)據(jù)同步的策略以保證數(shù)據(jù)同步成本的最小化。
數(shù)據(jù)條數(shù)很少吁脱,數(shù)據(jù)內(nèi)容也不大桑涎,則直接同步數(shù)據(jù)
數(shù)據(jù)條數(shù)很少,但是里面包含大數(shù)據(jù)類型兼贡,比如文本攻冷,二進制數(shù)據(jù)等,則先對數(shù)據(jù)進行壓縮然后再同步遍希,從而減少網(wǎng)絡(luò)帶寬的占用和傳輸所用的時間等曼。
數(shù)據(jù)條數(shù)很多,此時中間件會拿到造成數(shù)據(jù)變化的SQL語句凿蒜, 然后對SQL語句進行解析禁谦,分析其執(zhí)行計劃和執(zhí)行成本,并選擇是同步數(shù)據(jù)還是同步SQL語句到其他的數(shù)據(jù)庫中废封。此種情況應(yīng)用在對表結(jié)構(gòu)進行調(diào)整或者批量更改數(shù)據(jù)的時候非常有用州泊。
優(yōu)缺點
(1) 擴展性強:當(dāng)系統(tǒng)要更高數(shù)據(jù)庫處理速度時,只要簡單地增加數(shù)據(jù)庫服務(wù)器就 可以得到擴展漂洋。
(2) 可維護性:當(dāng)某節(jié)點發(fā)生故障時遥皂,系統(tǒng)會自動檢測故障并轉(zhuǎn)移故障節(jié)點的應(yīng)用力喷,保證數(shù)據(jù)庫的持續(xù)工作。
(3) 安全性:因為數(shù)據(jù)會同步的多臺服務(wù)器上演训,可以實現(xiàn)數(shù)據(jù)集的冗余弟孟,通過多份數(shù)據(jù)來保證安全性。另外它成功地將數(shù)據(jù)庫放到了內(nèi)網(wǎng)之中样悟,更好地保護了數(shù)據(jù)庫的安全性拂募。
(4) 易用性:對應(yīng)用來說完全透明,集群暴露出來的就是一個IP
2乌奇、數(shù)據(jù)庫的讀寫分離
實現(xiàn)原理
讀寫分離簡單的說是把對數(shù)據(jù)庫讀和寫的操作分開對應(yīng)不同的數(shù)據(jù)庫服務(wù)器没讲,這樣能有效地減輕數(shù)據(jù)庫壓力,也能減輕io壓力礁苗。主數(shù)據(jù)庫提供寫操作爬凑,從數(shù)據(jù)庫提供讀操作,其實在很多系統(tǒng)中试伙,主要是讀的操作嘁信。當(dāng)主數(shù)據(jù)庫進行寫操作時,數(shù)據(jù)要同步到從的數(shù)據(jù)庫疏叨,這樣才能有效保證數(shù)據(jù)庫完整性潘靖。
(ebay的讀寫比率是260:1,ebay的讀寫分離)
(微軟數(shù)據(jù)庫分發(fā))
實現(xiàn)方法
在MS Sql server中可以使用發(fā)布定義的方式實現(xiàn)數(shù)據(jù)庫復(fù)制,實現(xiàn)讀寫分離蚤蔓,復(fù)制是將一組數(shù)據(jù)從一個數(shù)據(jù)源拷貝到多個數(shù)據(jù)源的技術(shù)卦溢,是將一份數(shù)據(jù)發(fā)布到多個存儲站點上的有效方式。使用復(fù)制技術(shù)秀又,用戶可以將一份數(shù)據(jù)發(fā)布到多臺服務(wù)器上单寂。復(fù)制技術(shù)可以確保分布在不同地點的數(shù)據(jù)自動同步更新,從而保證數(shù)據(jù)的一致性吐辙。SQL SERVER復(fù)制技術(shù)類型有三種宣决,分別是:快照復(fù)制、事務(wù)復(fù)制昏苏、合并復(fù)制尊沸。SQL SERVER 主要采用出版物、訂閱的方式來處理復(fù)制贤惯。源數(shù)據(jù)所在的服務(wù)器是出版服務(wù)器洼专,負責(zé)發(fā)表數(shù)據(jù)。出版服務(wù)器把要發(fā)表的數(shù)據(jù)的所有改變情況的拷貝復(fù)制到分發(fā)服務(wù)器救巷,分發(fā)服務(wù)器包含有一個分發(fā)數(shù)據(jù)庫壶熏,可接收數(shù)據(jù)的所有改變,并保存這些改變浦译,再把這些改變分發(fā)給訂閱服務(wù)器棒假。
優(yōu)缺點
(1)數(shù)據(jù)的實時性差:數(shù)據(jù)不是實時同步到自讀服務(wù)器上的溯职,當(dāng)數(shù)據(jù)寫入主服務(wù)器后,要在下次同步后才能查詢到帽哑。
(2)數(shù)據(jù)量大時同步效率差:單表數(shù)據(jù)量過大時插入和更新因索引,磁盤IO等問題谜酒,性能會變的很差。
(3)同時連接多個(至少兩個)數(shù)據(jù)庫:至少要連接到兩個數(shù)據(jù)數(shù)據(jù)庫妻枕,實際的讀寫操作是在程序代碼中完成的僻族,容易引起混亂
(4)讀具有高性能高可靠性和可伸縮:只讀服務(wù)器,因為沒有寫操作屡谐,會大大減輕磁盤IO等性能問題述么,大大提高效率;只讀服務(wù)器可以采用負載均衡愕掏,主數(shù)據(jù)庫發(fā)布到多個只讀服務(wù)器上實現(xiàn)讀操作的可伸縮性度秘。
3、數(shù)據(jù)庫拆分(分布式)
通過某種特定的條件饵撑,將存放在同一個數(shù)據(jù)庫中的數(shù)據(jù)分散存放到多個數(shù)據(jù)庫上剑梳,實現(xiàn)分布存儲,通過路由規(guī)則路由訪問特定的數(shù)據(jù)庫滑潘,這樣一來每次訪問面對的就不是單臺服務(wù)器了垢乙,而是N臺服務(wù)器,這樣就可以降低單臺機器的負載壓力语卤。
垂直(縱向)拆分:是指按功能模塊拆分追逮,比如分為訂單庫、商品庫粹舵、用戶庫...這種方式多個數(shù)據(jù)庫之間的表結(jié)構(gòu)不同羊壹。
水平(橫向)拆分:將同一個表的數(shù)據(jù)進行分塊保存到不同的數(shù)據(jù)庫中,這些數(shù)據(jù)庫中的表結(jié)構(gòu)完全相同齐婴。
(縱向拆分)
(橫向拆分)
實現(xiàn)原理
使用垂直拆分,主要要看應(yīng)用類型是否合適這種拆分方式稠茂,如系統(tǒng)可以分為柠偶,訂單系統(tǒng),商品管理系統(tǒng)睬关,用戶管理系統(tǒng)業(yè)務(wù)系統(tǒng)比較明的诱担,垂直拆分能很好的起到分散數(shù)據(jù)庫壓力的作用。業(yè)務(wù)模塊不明晰电爹,耦合(表關(guān)聯(lián))度比較高的系統(tǒng)不適合使用這種拆分方式蔫仙。但是垂直拆分方式并不能徹底解決所有壓力問題,例如 有一個5000w的訂單表丐箩,操作起來訂單庫的壓力仍然很大摇邦,如我們需要在這個表中增加(insert)一條新的數(shù)據(jù)恤煞,insert完畢后,數(shù)據(jù)庫會針對這張表重新建立索引施籍,5000w行數(shù)據(jù)建立索引的系統(tǒng)開銷還是不容忽視的居扒,反過來,假如我們將這個表分成100個table呢丑慎,從table_001一直到table_100喜喂,5000w行數(shù)據(jù)平均下來,每個子表里邊就只有50萬行數(shù)據(jù)竿裂,這時候我們向一張只有50w行數(shù)據(jù)的table中insert數(shù)據(jù)后建立索引的時間就會呈數(shù)量級的下降玉吁,極大了提高了DB的運行時效率,提高了DB的并發(fā)量腻异,這種拆分就是橫向拆分
實現(xiàn)方法
垂直拆分进副,拆分方式實現(xiàn)起來比較簡單,根據(jù)表名訪問不同的數(shù)據(jù)庫就可以了捂掰。橫向拆分的規(guī)則很多敢会,這里總結(jié)前人的幾點,
(1)順序拆分
如可以按訂單的日前按年份才分这嚣,2003年的放在db1中鸥昏,2004年的db2,以此類推。當(dāng)然也可以按主鍵標準拆分姐帚。
優(yōu)點:可部分遷移
缺點:數(shù)據(jù)分布不均吏垮,可能2003年的訂單有100W,2008年的有500W罐旗。
(2)hash取模分
對user_id進行hash(或者如果user_id是數(shù)值型的話直接使用user_id的值也可)膳汪,然后用一個特定的數(shù)字,比如應(yīng)用中需要將一個數(shù)據(jù)庫切分成4個數(shù)據(jù)庫的話九秀,我們就用4這個數(shù)字對user_id的hash值進行取模運算遗嗽,也就是user_id%4,這樣的話每次運算就有四種可能:結(jié)果為1的時候?qū)?yīng)DB1;結(jié)果為2的時候?qū)?yīng)DB2鼓蜒;結(jié)果為3的時候?qū)?yīng)DB3痹换;結(jié)果為0的時候?qū)?yīng)DB4,這樣一來就非常均勻的將數(shù)據(jù)分配到4個DB中都弹。
優(yōu)點:數(shù)據(jù)分布均勻
缺點:數(shù)據(jù)遷移的時候麻煩娇豫;不能按照機器性能分攤數(shù)據(jù) 。
(3)在認證庫中保存數(shù)據(jù)庫配置
就是建立一個DB畅厢,這個DB單獨保存user_id到DB的映射關(guān)系冯痢,每次訪問數(shù)據(jù)庫的時候都要先查詢一次這個數(shù)據(jù)庫,以得到具體的DB信息,然后才能進行我們需要的查詢操作浦楣。
優(yōu)點:靈活性強袖肥,一對一關(guān)系
缺點:每次查詢之前都要多一次查詢,會造成一定的性能損失椒振。