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


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


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


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


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


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


我覺得分庫分表很容易呀


是嗎?




說到數據庫分庫分表,不能一味的追求,我們要明白為什么要進行分庫分表才是最終目的。現在網上一些人鼓吹分庫分表如何應對了多大數據,卻不知針對很多人的業務來說,分庫分表策略也許並非是銀彈,而是令人焦慮的焦油坑。
分庫分表是業務發展到一定階段,數據積累到一定量級而衍生出來的解決方案。當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管理人員,分庫之后可能會需要兩個甚至三個,導致了公司在人力投入上的加大。



完
