標籤:應該 遷移 朋友 表之間 server 中間 瓶頸 取資料 抽象
一、資料的垂直切分
概念:資料的垂直切分,也可以稱之為縱向切分。將不同的表分散到不同的資料庫主機中。
一個應用系統,總體功能肯定是由很多個功能模組所組成的,而每一個功能模組所需要的資料對應到資料庫中就是一個或者多個表。
在架構設計中,各個功能模組相互之間的互動點越統一越少,系統的耦合度就越低,系統各個模組的維護性以及擴充性也就越好。
這樣的系統,實現資料的垂直切分也就越容易。
1)可以根據功能模組來進行資料的切分,不同功能模組的資料存放於不同的資料庫主機中,可以很容易就避免掉跨資料庫的Join存在,同時系統架構也非常的清晰。
2)很難有系統能夠做到所有功能模組所使用的表完全獨立,完全不需要訪問對方的表或者需要兩個模組的表進行Join操作。根據實際的應用情境進行評估權衡。
1.遷就應用程式,將需要Join的表的相關某快都存放在同一個資料庫中。
2.讓應用程式做更多的事情,程式完全通過模組介面取得不同資料庫中的資料,然後在程式中完成Join操作。
通過這樣的垂直切分之後,之前只能通過一個資料庫來提供的服務,就被分拆成四個資料庫來提供服務,服務能力自然是增加幾倍了。
垂直切分的優點
◆ 資料庫的拆分簡單明了,拆分規則明確;
◆ 應用程式模組清晰明確,整合容易;
◆ 資料維護方便易行,容易定位;
垂直切分的缺點
◆ 部分表關聯無法在資料庫層級完成,需要在程式中完成;
◆ 對於訪問極其頻繁且資料量超大的表仍然存在效能平靜,不一定能滿足要求;
◆ 交易處理相對更為複雜;
◆ 切分達到一定程度之後,擴充性會遇到限制;
◆ 過讀切分可能會帶來系統過渡複雜而難以維護。
Notice:在資料庫進行垂直切分的時候,如何切分,切分到什麼樣的程度,是一個比較考驗人的難題。只能在實際的應用情境中通過平衡各方面的成本和收益,才能分析出一個真正適合自己的拆分方案。
可能在某些操作的單次回應時間會稍有增加,但是系統的整體效能很可能反而會有一定的提升。
二、資料的水平切分
概念:水平切分主要是將某個訪問極其平凡的表再按照某個欄位的某種規則來分散到多個表之中,每個表中包含一部分資料。
就是按照資料行的切分,就是將表中的某些行切分到一個資料庫,而另外的某些行又切分到其他的資料庫中。
1)按照某種特定的規則來進行切分。
1.某個數字類型欄位基於特定數目模數
2.某個時間類型欄位的範圍
3.某個字元類型欄位的hash值。
2)使相關的資料進行切分之後盡量存放在相同的資料庫中,即使是需要join查詢,也可以非常簡單的關聯上,在資料庫層面上就可以進行關聯查詢。
水平切分的優點
◆ 表關聯基本能夠在資料庫端全部完成;
◆ 不會存在某些超大型資料量和高負載的表遇到瓶頸的問題;
◆ 應用程式端整體架構改動相對較少;
◆ 交易處理相對簡單;
◆ 只要切分規則能夠定義好,基本上較難遇到擴充性限制;
水平切分的缺點
◆ 切分規則相對更為複雜,很難抽象出一個能夠滿足整個資料庫的切分規則;
◆ 後期資料的維護難度有所增加,人為手工定位元據更困難;
◆ 應用系統各模組耦合度較高,可能會對後面資料的遷移拆分造成一定的困難。
三、垂直與水平切分的聯合使用
每一個應用系統的負載都是一步一步增長上來的,在開始遇到效能瓶頸的時候,大多數架構師和DBA都會選擇先進行資料的垂直分割,因為這樣的成本最先,最符合這個時期所追求的最大投入產出比。然而,隨著業務的不斷擴張,系統負載的持續增長,在系統穩定一段時期之後,經過了垂直分割之後的資料庫叢集可能又再一次不堪重負,遇到了效能瓶頸。這時就需要進行水平切分。
實際上,在很多大型的應用系統中,垂直切分和水平切這兩種資料的切分方法基本上都是並存的,而且經常在不斷的交替進行,以不斷的增加系統的擴充能力。我們在應對不同的應用情境的時候,也需要充分考慮到這兩種切分方法各自的局限,以及各自的優勢,在不同的時期(負載壓力)使用不同的結合方式。
聯合切分的優點
◆ 可以充分利用垂直切分和水平切分各自的優勢而避免各自的缺陷;
◆ 讓系統擴充性得到最大化提升;
聯合切分的缺點
◆ 資料庫系統架構比較複雜,維護難度更大;
◆ 應用程式架構也相對更複雜;
四、資料切分及整合方案
資料庫中的資料在經過垂直和(或)水平切分被存放在不同的資料庫主機之後,應用系統面臨的最大問題就是如何來讓這些資料來源得到較好的整合
總的來說,存在兩種解決思路:
1. 在每個應用程式模組中組態管理自己需要的一個(或者多個)資料來源,直接存取各個資料庫,在模組內完成資料的整合;
2. 通過中間代理層來統一管理所有的資料來源,後端資料庫叢集對前端應用程式透明;
可能90%以上的人在面對上面這兩種解決思路的時候都會傾向於選擇第二種,尤其是系統不斷變得龐大複雜的時候。確實,這是一個非常正確的選擇,雖然短期內需要付出的成本可能會相對更大一些,但是對整個系統的擴充性來說,是非常有協助的。
五、資料切分與整合可能存在的問題
在實施資料切分方案之前,有些可能存在的問題我們還是需要做一些分析的。一般來說,我們可能遇到的問題主要會有以下幾點:
◆ 引入分散式交易的問題;
◆ 跨節點Join的問題;
◆ 跨節點合并排序分頁問題;
1. 引入分散式交易的問題
一旦資料進行切分被分別存放在多個MySQLServer中之後,不管我們的切分規則設計的多麼的完美(實際上並不存在完美的切分規則),都可能造成之前的某些事務所涉及到的資料已經不在同一個MySQLServer中了。
在這樣的情境下,如果我們的應用程式仍然按照老的解決方案,那麼勢必需要引入分散式交易來解決。而在MySQL各個版本中,只有從MySQL5.0開始以後的各個版本才開始對分散式交易提供支援,而且目前僅有Innodb提供分散式交易支援。不僅如此,即使我們剛好使用了支援分散式交易的MySQL版本,同時也是使用的Innodb儲存引擎,分散式交易本身對於系統資源的消耗就是很大的,效能本身也並不是太高。而且引入分散式交易本身在異常處理方面就會帶來較多比較難控制的因素。
怎麼辦?其實我們可以可以通過一個變通的方法來解決這種問題,首先需要考慮的一件事情就是:是否資料庫是唯一一個能夠解決事務的地方呢?其實並不是這樣的,我們完全可以結合資料庫以及應用程式兩者來共同解決。各個資料庫解決自己身上的事務,然後通過應用程式來控制多個資料庫上面的事務。
也就是說,只要我們願意,完全可以將一個跨多個資料庫的分散式交易分拆成多個僅處於單個資料庫上面的小事務,並通過應用程式來總控各個小事務。當然,這樣作的要求就是我們的應用程式必須要有足夠的健壯性,當然也會給應用程式帶來一些技術難度。
2.跨節點Join的問題
上面介紹了可能引入分散式交易的問題,現在我們再看看需要跨節點Join的問題。資料切分之後,可能會造成有些老的Join語句無法繼續使用,因為Join使用的資料來源可能被切分到多個MySQLServer中了。
怎麼辦?這個問題從MySQL資料庫角度來看,如果非得在資料庫端來直接解決的話,恐怕只能通過MySQL一種特殊的儲存引擎Federated來解決了。Federated儲存引擎是MySQL解決類似於Oracle的DBLink之類問題的解決方案。和OracleDBLink的主要區別在於Federated會儲存一份遠端表結構的定義資訊在本地。咋一看,Federated確實是解決跨節點Join非常好的解決方案。但是我們還應該清楚一點,那就似乎如果遠端的表結構發生了變更,本地的表定義資訊是不會跟著發生相應變化的。如果在更新遠端表結構的時候並沒有更新本地的Federated表定義資訊,就很可能造成Query運行出錯,無法得到正確的結果。
對待這類問題,我還是推薦通過應用程式來進行處理,先在驅動表所在的MySQLServer中取出相應的驅動結果集,然後根據驅動結果集再到被驅動表所在的MySQLServer中取出相應的資料。可能很多讀者朋友會認為這樣做對效能會產生一定的影響,是的,確實是會對效能有一定的負面影響,但是除了此法,基本上沒有太多其他更好的解決辦法了。而且,由於資料庫通過較好的擴充之後,每台MySQLServer的負載就可以得到較好的控制,單純針對單條Query來說,其回應時間可能比不切分之前要提高一些,所以效能方面所帶來的負面影響也並不是太大。更何況,類似於這種需要跨節點Join的需求也並不是太多,相對於總體效能而言,可能也只是很小一部分而已。所以為了整體效能的考慮,偶爾犧牲那麼一點點,其實是值得的,畢竟系統最佳化本身就是存在很多取捨和平衡的過程。
3. 跨節點合并排序分頁問題
一旦進行了資料的水平切分之後,可能就並不僅僅只有跨節點Join無法正常運行,有些排序分頁的Query語句的資料來源可能也會被切分到多個節點,這樣造成的直接後果就是這些排序分頁Query無法繼續正常運行。其實這和跨節點Join是一個道理,資料來源存在於多個節點上,要通過一個Query來解決,就和跨節點Join是一樣的操作。同樣Federated也可以部分解決,當然存在的風險也一樣。
還是同樣的問題,怎麼辦?我同樣仍然繼續建議通過應用程式來解決。
如何解決?解決的思路大體上和跨節點Join的解決類似,但是有一點和跨節點Join不太一樣,Join很多時候都有一個驅動與被驅動的關係,所以Join本身涉及到的多個表之間的資料讀取一般都會存在一個循序關聯性。但是排序分頁就不太一樣了,排序分頁的資料來源基本上可以說是一個表(或者一個結果集),本身並不存在一個循序關聯性,所以在從多個資料來源取資料的過程是完全可以並行的。這樣,排序分頁資料的取數效率我們可以做的比跨庫Join更高,所以帶來的效能損失相對的要更小,在有些情況下可能比在原來未進行資料切分的資料庫中效率更高了。當然,不論是跨節點Join還是跨節點排序分頁,都會使我們的應用伺服器消耗更多的資源,尤其是記憶體資源,因為我們在讀取存取以及合并結果集的這個過程需要比原來處理更多的資料。
mysql資料庫切分