程式設計師修神之路--做好分庫分表其實很難之一(繼續送書)

架構師修行之路發表於2019-07-08

菜哥,領導讓我開發新系統了

這麼說領導對你還是挺信任的呀~

必須的,為了設計好這個新系統,資料庫設計我花了好多心思呢

做一個系統我覺得不應該從資料庫入手,應該從設計業務模型開始,先不說這個,說說你的資料庫設計的優勢

為了高效能我首先設計了分庫 分表策略,為以後打下基礎

那你的資料量將來會很大嗎?分庫分表其實涉及到很多難題,你瞭解過嗎?

我覺得分庫分表很容易呀

是嗎?

是否需要分

說到資料庫分庫分表,不能一味的追求,我們要明白為什麼要進行分庫分表才是最終目的。現在網上一些人鼓吹分庫分表如何應對了多大資料,卻不知針對很多人的業務來說,分庫分表策略也許並非是銀彈,而是令人焦慮的焦油坑。

分庫分表是業務發展到一定階段,資料積累到一定量級而衍生出來的解決方案。當DB的資料量級到達一個階段,寫入和讀取的速度會出現瓶頸,即使是有索引,索引也會變的很大,而且資料庫的物理檔案大的會使備份和恢復等操作變的很困難。這個時候由於DB的瓶頸已經嚴重危害到了業務,最有效的解決方案莫過於DB的分庫分表了。


有的leader甚至架構師會在業務初期以自己的主觀意願就進行分庫分表,會為以後業務高速發展做鋪墊。但是這裡我要表達我幾個觀點:

1. 如果當前這個業務並非公司的核心業務,而且在業務是否能存活的前提下,初級的設計不要這麼複雜。如果每個業務我們都按淘寶那樣的規模做系統架構設計,將來不但會害死業務,更會讓程式設計師死的更慘,背上黑鍋的數量會更多。

2. 單臺資料庫的能力並非想象中那麼脆弱。就算是mysql單表資料量大部分場景下也在百萬級別(當然這和儲存的具體資料格式有關),sqlserver更是不在話下,我司用的sqlserver,單表千萬級別資料的大有所在,億級的也有幾個,Oracle更是不用多說。

3. 如果業務週期比較短,或者人力物力不足的情況下,盲目的在初期就進行分庫分表設計,更是給自己下了績效背D的套,

4. 系統的設計初期和公司的基礎資料有直接關係,比如微信這樣的資料規模,稍微一個小系統就有可能是千萬甚至上億的資料級別,但是多數初創公司有多少能有這樣的級別呢?我這裡噴一句:有的創業公司號稱從XX大公司重金挖來的CTO,技術總監等等高人,尤其是這些帶著金色光環的人在創業初期給開發人員埋雷,一個創業公司搞一套XX分散式,XX設計,殊不知,在當前的公司環境下這些其實沒有必要,給公司帶來的更多是苦不堪言。

一個好的系統設計者會在開始設計之初,充分考慮到各方面的綜合因素來綜合考慮。

分   庫

根據業務劃分

說到分庫,菜菜這裡想多囉嗦一句:推薦大家根據業務來進行劃分,我一直在過去的文章中強調,一個系統的好壞,業務的邊界劃分起到舉足輕重的作用。業務按照規則劃分好邊界,每個業務對應的資料庫自然而然就誕生了,不要站在資料庫的層面上去給業務分庫。有的leader會有這樣的行為:某個表的資料量太大,分配到單獨的一個庫,結果導致的結果就是很多SQL語句必須跨庫Join。


具體的業務怎麼劃分呢?這個規則我不敢說,每個公司的業務形態不同,劃分的維度就會不同。舉一個簡單的例子:一個典型的電商系統根據業務可劃分為商品,訂單,這也是許多公司的典型業務劃分,但是我司根據自己的業務規則,劃分為商品,訂單,支付。因為支付系統在我司是一個獨立的業務,不但包含了訂單的支付,還包含了很多其他的支付場景。根據業務上的劃分,DB的層面就出現了商品DB,訂單DB和支付DB。

同一業務橫向劃分

除了根據業務垂直切分的策略之外,還有另外一種常用的分庫方案,如果某個具體業務資料量比較大,可以把這業務的資料庫根據某種規則來進行橫向切分。比如使用者資訊的業務,當使用者量達到一定量級,有些公司會把使用者資訊拆分到多個資料庫,說到這裡,有的同學會問,這和拆分到多個表有什麼區別呢?如果把使用者資訊橫切到同一個資料庫的多個表,如果這些表位於一個物理磁碟上,對於提高這個業務的寫入和讀取IO最大值並沒有什麼用處,但是如果分配到多個伺服器上,意味著這個業務整體的最大IO得到了提升,在一定程度上要比拆表效果要好,當然如果用到了表分割槽,每個分割槽散落在不同的物理磁碟上,也不一定比分庫方式差。

把某個業務的DB按照規則橫向切分之後,當然也會引入新的問題,下邊會介紹。切分的規則在很多情況下用的最多的就是雜湊取餘的方式了,有時間我們們在討論。

分庫引入複雜性

我在上文提到過,分庫分表並非是銀彈,任何一種解決方案能解決一個問題,但是有可能會引入其他問題,世界是公平的,計算機世界亦如此。那分庫會引入哪些問題呢?

1. 在執行了分庫之後,難以避免會將原本邏輯關聯性很強的資料劃分到不同的表、不同的庫上,這時,表的關聯操作將受到限制,我們多數情況下無法join位於不同分庫的表(因為多數公司都明令禁止跨庫sql),結果原本一次查詢能夠完成的業務,可能需要多次查詢才能完成。

2. 原來在單體DB環境下,可以用DB的事務來保證一些操作的原子操作,但是在分散到多個資料庫的情況下,統一管理這些操作變的困難。雖然一些大廠提供的也有跨庫的事務解決方案,但是效能上實在是差強人意,所以在很多情況下並不實用。比如上邊提到的商品庫存支付,在單體應用的情況下,三個業務在同一個資料庫,當發生支付業務,更改商品庫存和更新訂單狀態這兩個操作可以利用資料庫提供的事物來完成,而且效能在可接受範圍之內,如果這三個業務分佈在不同的資料庫,有機率會發生只執行其中一個操作的情況發生,其實這也是分散式事物要解決的問題。在很多情況下,分散式事物是無法避免的,根據業務綜合情況適當採用分散式事物也是一種有效的解決方案,最壞的情況下,可能需要人工介入了。

3. 分庫對於DBA來說意味著工作量的成倍增加,原來只需要管理一個DB,現在卻要管理N個DB,而且每個DB都需要備份,監控,甚至做高可用,擴充套件等工作。原來可能只需要一個DBA管理人員,分庫之後可能會需要兩個甚至三個,導致了公司在人力投入上的加大。

關於分庫你有什麼要說的嗎?歡迎在留言區討論,公眾號內回覆“抽獎”,送書活動還在繼續!!

程式設計師過關斬將--你為什麼還在用儲存過程?
程式設計師過關斬將--小小的分頁引發的加班血案
程式設計師修神之路--問世間非同步為何物?
程式設計師修神之路--提高網站的吞吐量?
程式設計師修神之路--?分散式高併發下Actor模型如此優秀?
程式設計師過關斬將--論商品促銷程式碼的優雅性
程式設計師過關斬將--你的面向介面程式設計一定對嗎?
程式設計師修神之路--高併發下為什麼更喜歡程式內快取
程式設計師修神之路--高併發優雅的做限流


相關文章