關於分散式資料庫的一點認識

來源:互聯網
上載者:User

關於分散式資料庫

 

關鍵字

      分散式資料庫 分組 Server Load Balancer

 

      對於單機的資料庫系統如果不能滿足我們對效能的需要,那就需要多機來解決這個問題。有一台中心伺服器負責對外,而其他的內部伺服器則作為單機資料庫使用。這樣中心伺服器需要維持對各個資料服務器的連結,並且要處理相關問題。在花期杯搜尋引擎的製作中,出於系統擴充性的考慮,資料庫系統需要一個這種系統,所以在此討論一下可行性。

      直接在物理資料層處理這個問題的話需要處理的問題太多。典型的例子就是交易處理,如果一個事務更新多個子資料庫,那麼我們的中心伺服器還需要實現自己的交易處理。這個方案看起來不那麼好處理。而將問題向上提升,將問題提交到資料抽象層,問題就好辦多了,有了一個可行的解決方案。通過資料的抽象,封裝事務——每個業務對象只存在於一個資料庫中,並且不會批量更改業務對象(但是可以批量訪問)。這樣的要求就可以實現一個分布式的系統。這個要求看似很苛刻,但實際上很多業務都是這種情況。

      在這種方案中,每個業務對象需要一個可排序的鍵。在各個子伺服器之間按照這個鍵進行資料的分配和尋找。比如這個鍵是一個英文字串,那麼就可以按照字母順序,將A開頭的資料放在一台伺服器上,而B開頭的方在另一台伺服器上。這實際上是重新伺服器的一個分組策略(Grouping)。所謂分組就是使資料按照一定的方法歸類,每一類放在一起。尋找的時候按照分類很容易就可以找到相應的資料,並且可以提高資料查詢的並行性——A開頭和B開頭的資料可以同時進行,而不必等到一個完成再尋找另外一個。這樣的話,對於單個業務對象的操作將被Grouping分配給特定的子伺服器。那批量訪問呢。比如一個尋找操作。廣播是一個解決方案,就是給所有的子伺服器發送一個尋找命令。然後對返回的結果進行相應的處理,並最終返回給使用者。這樣,命令中的排序部分將產生問題——子伺服器的資料到達中心伺服器之後怎麼排序。難道要分析SQL語句。可行。這樣,由於結果已經分好組,並且已經被子伺服器排序,中心伺服器所要做的就是使用分組選擇排序使用O(m*n)時間再排序(m=子伺服器的資料條數,n=子伺服器數)。

 

Server Load Balancer

 

      如果一檯子伺服器滿了怎麼辦。我們的分布式系統應該可以將資料轉移到其他負載不是很高的伺服器上。這和資料庫中廣泛應用的B樹很相似——如果一個節點滿了就調整子樹使得節點不滿,並將資料轉移到其他子樹上,都滿了的話擴充樹的深度——也就是添加新的子伺服器。

這是最簡單的負載平衡,伺服器1的資料滿了,移動一部分資料到其後的伺服器2,並將伺服器2的原有資料後移。但這樣就需要改變原先的Grouping機制,因為伺服器2上也有A開頭的資料了。所以需要引進錨點(Archor)。每個伺服器有其兩端資料的鍵,作為錨點。中心伺服器擷取這個錨點來判斷資料到底可能在那個伺服器中,然後向指定的伺服器發出資料請求。這樣上面的操作出了資料的移動之外就只需要改變中心伺服器的錨點設定,而這項工作完全可以自動完成——資料移動的時候顯然知道各個錨點的值。

      但還有一個問題就是如果伺服器2也滿了,那該怎麼辦。那就向伺服器3移動資料。這是一個非常簡單可行的方案。只是在資料非常不平衡的時候資料移動將非常耗時間。而如果我們去尋找有空間的伺服器的話,必將導致片段,這個問題並非不能處理,但隨著片段的增多,將使得Grouping的速度優勢完全喪失——一個條目一個錨點,那速度將會很慢。所以直接向後邊的伺服器移動資料是一個很可行的方案。而且,即使資料很不平衡,我們也可以通過Grouping的機制使得在填充資料的時候就不把伺服器1填滿,而是直接向伺服器2移動資料這樣就可以使所有的伺服器有一個相同的負載。而這時正好是這個系統的尋找效率最高的時候。這個機制實際上就是樹的平衡機制。

      另外一個問題就是在移動資料的過程中如何保證資料的一致性。也就是如何使得移動期間的資料尋找不會有缺損的資料,也不會有冗餘的資料。實際上使用錨點後,只要錨點不改變,上層軟體的操作就不會有任何改變,也就是說資料的移動變成了錨點的更新。這個時間很短完全可以同過原子操作來完成。之後刪除原資料庫中的資料。

      這個方案實際上是將資料庫的內部處理提到更高的層面上,把一個伺服器上的資料庫作為一個資料節點來處理。

 

      由於各個子伺服器的效能可能不一樣,所以各個子伺服器所能儲存的資料條目的數目也會不一樣,通過統一的條目控制負載不是一個好的方案。應該通過一個負載係數來處理。每個伺服器的配置當眾說明本伺服器可以儲存多少資料,然後中心伺服器在必要時擷取各個子伺服器的負載係數,並將自動資料使得各個子伺服器的負載係數相同。這樣的好處首先就是如果新添加了一檯子伺服器,那麼需要做的只是在中心伺服器的子伺服器列表中添加新的伺服器就可以了,整個系統會迅速通過負載平衡機制將資料添加到新添加的資料庫中。算然這個過程可能會比較慢,但完全自動,可以在系統閒置時候後台執行。如果要去除一檯子伺服器需要做的也只是將該子伺服器的負載調成0,這樣負載係數永遠高於其他的伺服器,以使得其中的條目被分配到別的子伺服器中,等到空了之後,再在中心伺服器的子伺服器列表中講這個子伺服器刪除。整個過程系統不用停機,不用人為幹預資料調整。

      而相比於一台伺服器多個磁碟陣列,這種方式將並行操作,理論峰值效能應該高於單伺服器多磁碟的方案。

 

事務的處理

 

      這是一個棘手的問題。主要是要同步多個伺服器的事務。在中心伺服器上啟動一個事務,將使得中心伺服器對每一個子伺服器啟動一個事務,並儲存所有的事務ID為一張列表,然後對應一個中心伺服器的事務ID。期間的所有的控制中心伺服器將追蹤每個操作所有需要執行的伺服器(不是沒個伺服器都執行命令,例如更新一條記錄)的傳回值,如果有一個出錯的子伺服器操作就返回出錯,這樣可以通知使用者會滾。而復原過程也是對當前事務所對應的所有的子伺服器的事務進行復原。但因為實際上並不是所有的子伺服器都進行了操作,完全可以根據需要,那個子伺服器有操作再在該伺服器上請求事務,然後操作,直至最後提交或復原。但這樣存在子伺服器申請事務失敗的問題——中心伺服器已經返回成功申請事務,而子伺服器卻申請失敗,無法返回子伺服器的事務申請失敗的傳回值。但中心伺服器依然可以返回一個錯誤值指示操作失敗而不是事務申請失敗。

      解決了交易處理,這個系統就和單一資料庫看起來沒有區別了。

 

由排序想到的

 

      由於需要排序,可以考慮實現自身的特殊查詢語言或SQL解析器,並編寫各種資料庫SQL方言的適配器,這樣分布式系統中各個子伺服器可以使用不同的資料庫。Group By 子句也需要相同的處理。各個子伺服器的結果可能依然有相同的Group By 欄位。這樣怎麼處理。處理一個完全的SQL資料庫可就複雜了。將結果集存入本機資料庫,然後再在本地執行,是一個可行的方案,但是這個方案的速度有點慢。對於AVG函數,這個結果就將是錯誤的。計算資料行也將由於列名重複而出錯。

 

由於處理整個SQL標準很不現實,所以處理一個自己就簡單多了。但怎樣使得使用者的使用不會超出我們的要求呢。直接傳遞SQL語句肯定是不行了,因為分析的開銷也不小。直接使用自訂的查詢語句或DOM的方式來限制SQL語句所使用的功能。這是一個可擴充的模型,可以在允許的情況下擴充到整個SQL的支援。這個方案有一個問題就是由於不知道資料的關鍵字,錨點機制不起作用。

 

      現在討論一下在資料抽象層實現。這需要伺服器中的對象都有一個鍵,並且在大量操作的時候比較慢。而在搜尋引擎的開發中需要批量尋找子字串,在這種方式下將使得資料庫自身的緩衝區失效——需要載入每一個對象,然後用自己的代碼尋找,每個對象實際上只訪問一次就被廢棄了。

 

SQL Server的分布式實現使用的是對等資料庫,即每個子伺服器都是對外的介面。然後通過查詢最佳化工具將SQL語句分解,上面那些討論到的問題將不被處理的傳輸到請求伺服器,然後完成剩下的操作。但這樣限制頗多,系統設計中所擁有的特性將有很多無法實現。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.