NOSQL系統一般都會宣傳一個特性,那就是性能好,然後為什麼呢?關聯式資料庫發展了這麼多年,各種優化工作已經做得很深了,NOSQL系統一般都是吸收關聯式資料庫的技術,那麼,到底是什麼因素束縛了關聯式資料庫的性能呢?我們從系統設計的角度看這個問題。

1. 索引支援

 

關聯式資料庫創立之初沒有想到今天的互聯網應用對可擴充性提出如此高的要求,因此,設計時主要考慮的是簡化使用者的工作,SQL語言的產生促成資料庫介面的標準化,從而形成了Oracle這樣的資料庫公司並帶動了上下游產業鏈的發展。關聯式資料庫在單機儲存引擎支援索引,比如Mysql的 Innodb儲存引擎需要支援索引,而NOSQL系統的單機儲存引擎是純粹的,只需要支援基於主鍵的隨機讀取和範圍查詢。NOSQL系統在系統層面提供對索引的支援,比如有一個使用者表,主鍵為user_id,每個使用者有很多屬性,包括使用者名,照片ID(photo_id),照片URL,在NOSQL系統中如果需要對photo_id建立索引,可以維護一張分散式表,表的主鍵為形成的二元組。關聯式資料庫由於需要在單機儲存引擎層面支援索引,大大降低了系統的可擴充性,使得單機儲存引擎的設計變得很複雜。

 

2. 事務併發處理

 

關聯式資料庫有一整套的關於事務併發處理的理論,比如鎖的細微性是表級,頁級還是行級,多版本併發控制機制MVCC,事務的隔離等級,鎖死檢測,回滾,等等。然而,互聯網應用大多數的特點都是多讀少些,比如讀和寫的比例是10 : 1,並且很少有複雜事務需求,因此,一般可以採用更為簡單的copy-on-write技術:單線程寫,多執行緒讀,寫的時候執行copy-on- write,寫不影響讀服務。NOSQL系統這樣的假設簡化了系統的設計,減少了很多操作的overhead,提高了性能。

 

3. 動態還是靜態的資料結構

 

關聯式資料庫的儲存引擎總是一顆磁片B+樹,為了提高性能,可能需要有insert buffer聚合寫,query cache緩存讀,經常需要實現類似Linux page cache的緩存管理機制。資料庫中的讀和寫是互相影響的,寫操作也因為時不時需要將資料flush到磁片而性能不高。簡而言之,關聯式資料庫儲存引擎的資料結構是通用的動態更新的B+樹。然而,在NOSQL系統中,比如Bigtable中採用SSTable + MemTable的資料結構,資料先寫入到記憶體的MemTable,達到一定大小或者超過一定時間才會dump到磁片生成SSTable檔,SSTable是唯讀的。如果說關聯式資料庫儲存引擎的資料結構是一顆動態的B+樹,那麼SSTable就是一個排好序的有序陣列。很明顯,實現一個有序資料比實現一個動態B+樹且包含複雜的併發控制機制要簡單高效地多。

 

4. Join操作

 

關聯式資料庫需要在儲存引擎層面支援Join,而NOSQL系統一般根據應用來決定Join實現的方式。舉個例子,有兩張表:使用者表和商品表,每個使用者下可能有若干個商品,使用者表的主鍵為,使用者和商品的關聯屬性存放在使用者表中,商品表的主鍵為item_id,商品屬性包括商品名,商品URL,等等。假設應用需要查詢一個使用者的所有商品並顯示商品的詳細資訊,普通的做法是先從使用者表查找指定使用者的所有item_id,然後對每個item_id去商品表查詢詳細資訊,即執行一次資料庫Join操作,這必然帶來了很多的磁片隨機讀,並且由於Join帶來的隨機讀的局部性不好,緩存的效果往往也是有限的。在NOSQL系統中,我們往往可以將使用者表和商品表集成到一張寬表中,這樣雖然冗余存儲了商品的詳細資訊,卻換來了查詢的高效。

 

關聯式資料庫的性能瓶頸往往不在SQL語句解析上,而是在於需要支援完備的SQL特性。互聯網公司面臨的問題是應用對性能和可擴充性要求很高,並且DBA和開發工程師水準比較高,可以通過犧牲一些介面友好性來換取更好的性能。NOSQL系統的一些設計,比如通過寬表實現Join操作,互聯網公司的DBA和開發工程師也做過,NOSQL系統只是加強了這種約束。從長遠來看,可以總結一套約束集合,並且定義一個SQL子集,只需要支援這個SQL子集就可以在不犧牲可擴充性的前提下支援比如90%以上的互聯網應用。我想,NOSQL技術發展到這一步的時候就算是比較成熟了,這也是我們最終想做的事情。我們在設計和使用NOSQL系統的時候也可以適當轉化一下思維,如下:

 

1) 更大的資料量。很多人在使用Mysql的過程遇到記錄條數超過一定值,比如2000W的時候,資料庫性能開始下降,這個值的得出往往需要經過大量的測試。然而,大多數的NOSQL系統可擴充性都比較好,能夠支援更大的資料量,因此也可以採用一些空間換時間的做法,比如通過寬表的方式實現Join。

 

2) 性能預估更加容易。關聯式資料庫由於複雜的併發控制,insert buffer及類似page cache的讀寫優化機制,性能估算相對較難,很多時候需要憑藉經驗或者經過測試才能得出系統的性能。然後,NOSQL系統由於儲存引擎實現,併發控制機制等相對簡單,可以通過硬體的性能指標在系統設計之處大致預估系統的性能,性能預估可操作性相對更強。

 

原文連結:HTTP://womendu.iteye.com/blog/979757
arrow
arrow
    全站熱搜

    戮克 發表在 痞客邦 留言(0) 人氣()