本文導讀:當系統要滿足每秒數萬次的讀寫請求的需求時,我們可以用分布式計算、編寫優良的程序代碼、對海量數據進行分區操作、建立廣泛的索引、建立緩存機制、加大虛擬內存、分批處理、使用數據倉庫和多維數據庫存儲、使用負載均衡技術、將數據庫的讀寫分離等等來解決數據庫大數據訪問的問題。
隨着互聯網應用的廣泛普及,海量數據的存儲和訪問成為了系統設計的瓶頸問題。對於一個大型的互聯網應用,每天百萬級甚至上億的PV無疑對數據庫造成了相當高的負載。對於系統的穩定性和擴展性造成了極大的問題。
一、那么數據庫如何處理海量數據呢?
1、編寫優良的程序代碼
處理數據離不開優秀的程序代碼,尤其在進行復雜數據處理時,必須使用程序。好的程序代碼對數據的處理至關重要,這不僅僅是數據處理准確度的問題,更是數據處理效率的問題。良好的程序代碼應該包含好的算法,包含好的處理流程,包含好的效率,包含好的異常處理機制等。
2、對海量數據進行分區操作
對海量數據進行分區操作十分必要,例如針對按年份存取的數據,我們可以按年進行分區,不同的數據庫有不同的分區方式,不過處理機制大體相同。例如SQL Server的數據庫分區是將不同的數據存於不同的文件組下,而不同的文件組存於不同的磁盤分區下,這樣將數據分散開,減小磁盤I/O,減小了系統負荷,而且還可以將日志,索引等放於不同的分區下。
3、建立廣泛的索引
對海量的數據處理,對大表建立索引是必行的,建立索引要考慮到具體情況,例如針對大表的分組、排序等字段,都要建立相應索引,一般還可以建立復合索引,對 經常插入的表則建立索引時要小心,筆者在處理數據時,曾經在一個ETL流程中,當插入表時,首先刪除索引,然后插入完畢,建立索引,並實施聚合操作,聚合 完成后,再次插入前還是刪除索引,所以索引要用到好的時機,索引的填充因子和聚集、非聚集索引都要考慮。
4、加大虛擬內存
如果系統資源有限,內存提示不足,則可以靠增加虛擬內存來解決。筆者在實際項目中曾經遇到針對18億條的數據進行處理,內存為1GB,1個P4 2.4G的CPU,對這么大的數據量進行聚合操作是有問題的,提示內存不足,那么采用了加大虛擬內存的方法來解決,在6塊磁盤分區上分別建立了6個 4096M的磁盤分區,用於虛擬內存,這樣虛擬的內存則增加為 4096*6 + 1024 = 25600 M,解決了數據處理中的內存不足問題。
5、分批處理
海量數據處理難因為數據量大,那么解決海量數據處理難的問題其中一個技巧是減少數據量。可以對海量數據分批處理,然后處理后的數據再進行合並操作,這樣逐 個擊破,有利於小數據量的處理,不至於面對大數據量帶來的問題,不過這種方法也要因時因勢進行,如果不允許拆分數據,還需要另想辦法。不過一般的數據按 天、按月、按年等存儲的,都可以采用先分后合的方法,對數據進行分開處理。
6、使用數據倉庫和多維數據庫存儲
數據量加大是一定要考慮OLAP的,傳統的報表可能5、6個小時出來結果,而基於Cube的查詢可能只需要幾分鍾,因此處理海量數據的利器是OLAP多維分析,即建立數據倉庫,建立多維數據集,基於多維數據集進行報表展現和數據挖掘等。
7、使用采樣數據,進行數據挖掘
基於海量數據的數據挖掘正在逐步興起,面對着超海量的數據,一般的挖掘軟件或算法往往采用數據抽樣的方式進行處理,這樣的誤差不會很高,大大提高了處理效率和處理的成功率。一般采樣時要注意數據的完整性和,防止過大的偏差。筆者曾經對1億2千萬行的表數據進行采樣,抽取出400萬行,經測試軟件測試處理的誤差為千分之五,客戶可以接受。
還有一些方法,需要在不同的情況和場合下運用,例如使用代理鍵等操作,這樣的好處是加快了聚合時間,因為對數值型的聚合比對字符型的聚合快得多。類似的情況需要針對不同的需求進行處理。
海量數據是發展趨勢,對數據分析和挖掘也越來越重要,從海量數據中提取有用信息重要而緊迫,這便要求處理要准確,精度要高,而且處理時間要短,得到有價值信息要快,所以,對海量數據的研究很有前途,也很值得進行廣泛深入的研究。
二、下面注意講解下負載均衡技術、數據庫的讀寫分離、數據庫拆分(分布式)
1、負載均衡技術
負載均衡集群是由一組相互獨立的計算機系統構成,通過常規網絡或專用網絡進行連接,由路由器銜接在一起,各節點相互協作、共同負載、均衡壓力,對客戶端來說,整個群集可以視為一台具有超高性能的獨立服務器。
實現原理
實現數據庫的負載均衡技術,首先要有一個可以控制連接數據庫的控制端。在這里,它截斷了數據庫和程序的直接連接,由所有的程序來訪問這個中間層,然后再由中間層來訪問數據庫。這樣,我們就可以具體控制訪問某個數據庫了,然后還可以根據數據庫的當前負載采取有效的均衡策略,來調整每次連接到哪個數據庫。
實現多據庫數據同步
對於負載均衡,最重要的就是所有服務器的數據都是實時同步的。這是一個集群所必需的,因為,如果數不據實時、不同步,那么用戶從一台服務器讀出的數據,就有別於從另一台服務器讀出的數據,這是不能允許的。所以必須實現數據庫的數據同步。這樣,在查詢的時候就可以有多個資源,實現均衡。比較常用的方法是Moebius for SQL Server集群,Moebius for SQL Server集群采用將核心程序駐留在每個機器的數據庫中的辦法,這個核心程序稱為Moebius for SQL Server 中間件,主要作用是監測數據庫內數據的變化並將變化的數據同步到其他數據庫中。數據同步完成后客戶端才會得到響應,同步過程是並發完成的,所以同步到多個數據庫和同步到一個數據庫的時間基本相等;另外同步的過程是在事務的環境下完成的,保證了多份數據在任何時刻數據的一致性。正因為Moebius 中間件宿主在數據庫中的創新,讓中間件不但能知道數據的變化,而且知道引起數據變化的SQL語句,根據SQL語句的類型智能的采取不同的數據同步的策略以保證數據同步成本的最小化。
數據條數很少,數據內容也不大,則直接同步數據
數據條數很少,但是里面包含大數據類型,比如文本,二進制數據等,則先對數據進行壓縮然后再同步,從而減少網絡帶寬的占用和傳輸所用的時間。
數據條數很多,此時中間件會拿到造成數據變化的SQL語句, 然后對SQL語句進行解析,分析其執行計划和執行成本,並選擇是同步數據還是同步SQL語句到其他的數據庫中。此種情況應用在對表結構進行調整或者批量更改數據的時候非常有用。
優缺點
(1) 擴展性強:當系統要更高數據庫處理速度時,只要簡單地增加數據庫服務器就 可以得到擴展。
(2) 可維護性:當某節點發生故障時,系統會自動檢測故障並轉移故障節點的應用,保證數據庫的持續工作。
(3) 安全性:因為數據會同步的多台服務器上,可以實現數據集的冗余,通過多份數據來保證安全性。另外它成功地將數據庫放到了內網之中,更好地保護了數據庫的安全性。
(4) 易用性:對應用來說完全透明,集群暴露出來的就是一個IP
2、數據庫的讀寫分離
實現原理
讀寫分離簡單的說是把對數據庫讀和寫的操作分開對應不同的數據庫服務器,這樣能有效地減輕數據庫壓力,也能減輕io壓力。主數據庫提供寫操作,從數據庫提供讀操作,其實在很多系統中,主要是讀的操作。當主數據庫進行寫操作時,數據要同步到從的數據庫,這樣才能有效保證數據庫完整性。
(ebay的讀寫比率是260:1,ebay的讀寫分離)
(微軟數據庫分發)
實現方法
在MS Sql server中可以使用發布定義的方式實現數據庫復制,實現讀寫分離,復制是將一組數據從一個數據源拷貝到多個數據源的技術,是將一份數據發布到多個存儲站點上的有效方式。使用復制技術,用戶可以將一份數據發布到多台服務器上。復制技術可以確保分布在不同地點的數據自動同步更新,從而保證數據的一致性。SQL SERVER復制技術類型有三種,分別是:快照復制、事務復制、合並復制。SQL SERVER 主要采用出版物、訂閱的方式來處理復制。源數據所在的服務器是出版服務器,負責發表數據。出版服務器把要發表的數據的所有改變情況的拷貝復制到分發服務器,分發服務器包含有一個分發數據庫,可接收數據的所有改變,並保存這些改變,再把這些改變分發給訂閱服務器。
優缺點
(1)數據的實時性差:數據不是實時同步到自讀服務器上的,當數據寫入主服務器后,要在下次同步后才能查詢到。
(2)數據量大時同步效率差:單表數據量過大時插入和更新因索引,磁盤IO等問題,性能會變的很差。
(3)同時連接多個(至少兩個)數據庫:至少要連接到兩個數據數據庫,實際的讀寫操作是在程序代碼中完成的,容易引起混亂
(4)讀具有高性能高可靠性和可伸縮:只讀服務器,因為沒有寫操作,會大大減輕磁盤IO等性能問題,大大提高效率;只讀服務器可以采用負載均衡,主數據庫發布到多個只讀服務器上實現讀操作的可伸縮性。
3、數據庫拆分(分布式)
通過某種特定的條件,將存放在同一個數據庫中的數據分散存放到多個數據庫上,實現分布存儲,通過路由規則路由訪問特定的數據庫,這樣一來每次訪問面對的就不是單台服務器了,而是N台服務器,這樣就可以降低單台機器的負載壓力。
垂直(縱向)拆分:是指按功能模塊拆分,比如分為訂單庫、商品庫、用戶庫...這種方式多個數據庫之間的表結構不同。
水平(橫向)拆分:將同一個表的數據進行分塊保存到不同的數據庫中,這些數據庫中的表結構完全相同。
(縱向拆分)
(橫向拆分)
實現原理
使用垂直拆分,主要要看應用類型是否合適這種拆分方式,如系統可以分為,訂單系統,商品管理系統,用戶管理系統業務系統比較明的,垂直拆分能很好的起到分散數據庫壓力的作用。業務模塊不明晰,耦合(表關聯)度比較高的系統不適合使用這種拆分方式。但是垂直拆分方式並不能徹底解決所有壓力問題,例如 有一個5000w的訂單表,操作起來訂單庫的壓力仍然很大,如我們需要在這個表中增加(insert)一條新的數據,insert完畢后,數據庫會針對這張表重新建立索引,5000w行數據建立索引的系統開銷還是不容忽視的,反過來,假如我們將這個表分成100個table呢,從table_001一直到table_100,5000w行數據平均下來,每個子表里邊就只有50萬行數據,這時候我們向一張只有50w行數據的table中insert數據后建立索引的時間就會呈數量級的下降,極大了提高了DB的運行時效率,提高了DB的並發量,這種拆分就是橫向拆分
實現方法
垂直拆分,拆分方式實現起來比較簡單,根據表名訪問不同的數據庫就可以了。橫向拆分的規則很多,這里總結前人的幾點,
(1)順序拆分
如可以按訂單的日前按年份才分,2003年的放在db1中,2004年的db2,以此類推。當然也可以按主鍵標准拆分。
優點:可部分遷移
缺點:數據分布不均,可能2003年的訂單有100W,2008年的有500W。
(2)hash取模分
對user_id進行hash(或者如果user_id是數值型的話直接使用user_id的值也可),然后用一個特定的數字,比如應用中需要將一個數據庫切分成4個數據庫的話,我們就用4這個數字對user_id的hash值進行取模運算,也就是user_id%4,這樣的話每次運算就有四種可能:結果為1的時候對應DB1;結果為2的時候對應DB2;結果為3的時候對應DB3;結果為0的時候對應DB4,這樣一來就非常均勻的將數據分配到4個DB中。
優點:數據分布均勻
缺點:數據遷移的時候麻煩;不能按照機器性能分攤數據 。
(3)在認證庫中保存數據庫配置
就是建立一個DB,這個DB單獨保存user_id到DB的映射關系,每次訪問數據庫的時候都要先查詢一次這個數據庫,以得到具體的DB信息,然后才能進行我們需要的查詢操作。
優點:靈活性強,一對一關系
缺點:每次查詢之前都要多一次查詢,會造成一定的性能損失。
本文轉自:http://www.studyofnet.com/news/379.html