Part1 什麼情況下需要考慮庫表拆分呢?
實際上,是沒有一個非常量化的名額來判定庫表瓶頸的,因為每個系統的業務場景,查詢複雜度都有不同。 但力有窮盡時,我們雖然可以盡量地從加從庫讀寫分離、優化 sql、優化索引、複用連接配接等等方面進行優化,但總會有到達極限的時候的時候,量變引發質變。甚至,在真實生産環境,要更加未雨綢缪,不能等到崩了才去考慮。那麼,應該怎麼去判斷已經到了庫表拆分的時機呢:
- 硬體性能瓶頸,如果是讀操作多,其實可以加多個從庫分擔主庫讀壓力;但如果是寫操作多,會因為主庫磁盤 IO 增大,拖慢處理速度;另外,如果單表資料量過大,導緻索引層級增多,掃描行增多,CPU 效率降低,影響 sql 執行效率,拖慢處理速度。而處理速度慢最終會導緻連接配接數增加直至無連接配接可用。
- 日常運維投入,就如蘇甯拼購的情況,如果一個月就要搞一次資料遷移,這個人力的投入産出比,應該是完全不比對的,那就不如一次性搞定它。
- 業務發展可支援程度、難度和風險,當資料增長到一定程度,雖然沒有達到極限,還能湊活,但是遇到活動型流量脈沖,無法完全支援業務需求;而業務需要進行疊代增加模式時,修改資料表帶來的風險又比較大。就可以考慮重構資料模型,拆分庫表了。
Part2 分庫分表的目的和方案
2.1 業務資料解耦 - 垂直拆分
把不同的業務資料拆分到各自的資料庫中獨立維護,那麼最底層的原因是什麼呢?
是微服務下的上層服務拆分。為了滿足快速疊代、安全釋出、鍊路降級、主次業務解耦等問題,去解決代碼大量沖突、小功能排隊等待大版本釋出等等問題,将業務按照一定邏輯進行拆解,形成一個個功能完備,獨立運作的服務,然而,如果資料庫層面不配合,就無法解決根本問題。當上層服務執行個體拆分後可以被大量橫向擴充,以應對高并發的流量沖擊,會導緻底層資料庫的承載壓力和連接配接數急劇增加。
是以,通過垂直拆分将業務資料解耦,各管一事,以滿足微服務的效能最大化。
2.2 解決容量和性能壓力 - 水準拆分
對某一業務庫,當資料增量達到了庫瓶頸,或者表瓶頸,就要進行庫表的水準拆分了。
我之前遇到的很多情況,總是先分表,解決單表的容量和讀寫性能問題,随着業務發展,單庫也遇到瓶頸了再考慮分庫。為啥不一步到位?
就像之前在阿裡,新應用上來搞個百庫百表?一來是因為一些使用者規模和一些路由規則的問題;更重要的,不是所有公司其實不是所有的公司都和阿裡一樣有錢,有限的資源要用在更重要的生存問題上。如果你作為一個初創公司的架構,給出了一套可能撐 10 年的存儲方案,感覺會被同僚在心裡怼,公司能活 3 年麼就這麼浪費?但肯定沒有人說這話,因為我們還是希望所有公司都能蓬勃發展,蒸蒸日上的。
是以,拆分方法就很有講究了,怎麼分能讓後續疊代發展的代價最小呢?
2.3 分多少合适?
表主要看容量,很多經驗表明 上千萬後性能會有顯著下降,是以,我們可以把表容量定在一半多一點,600w。
庫主要看的是連接配接數,我們以阿裡對外售賣的雲存儲來大緻估計,單庫的連接配接數定在 4000 左右。抽象一個實際的評估案例來看:假如目前平台每天産生 10w 訂單,峰值并發數 8000QPS,然後考慮業務擴充和增長的速率:
比如,業務是和銀行合作擴充業務,将大小銀行量級平均一下,估計每合作一家可以帶來多大的增長量,這裡假設是 5000 單 / 天 / 家,如果業務計劃是每年度合作 10 家,那就是 5w,5 年以後每天的單量,理論上可能會到 25w / 天。加上現有的 10w, 峰值 35w。如果我們計劃系統的容量需要支撐 3 年,或者說,3 年之後的該業務擴充會趨于平緩,那麼我們可以大緻的估計為:
表:(3 年 * 365 天 * 35w=3.8 億 )/600w = 63 約 64 張表
庫:10000 并發 / 4000 = 2.5 , 可按 4 個庫來處理
2.4 怎麼分适合
- Hash 取模
- range 劃分
Part3 拆分會帶來的問題
- 分區鍵的選取
- 分區鍵要足夠的均勻,比如,使用者表用 UID,訂單表可以用 UID,也可以用訂單 ID,商戶表用商戶 ID,問題表用會話 ID 等等,總之,一定可以找到業務上的唯一 ID。當然還有一些特殊的分區,比如,日表,月表,則要按時間來分,等等。
- 全局唯一主鍵 ID
- 這個其實可以了解為分布式 ID 的生成問題
- 如何實作平滑資料遷移?
- 好處是簡單,風險小;缺點是業務有損。那就看這個損能不能接受了
- 事務問題
- 之前由于資料都在一個庫中,是以,隻要保證一個本地事務就可以辦到。現在資料被分到了多個庫,那麼事務如何保證,分布式事務的方式有很多:TCC、本地事務表 + 事務消息、最大努力通知,saga 等等。
- 查詢問題
- 之前一個庫就能搞定的 join、count 等各種聯合查詢,将不複存在,老老實實在接口代碼層面實作吧。
Part4 大廠案例,知識面擴充
4.1 大衆點評分庫分表的資料遷移
- 階段一:資料雙寫,以老資料為準。通過對賬補平差異
- 階段二:導入曆史資料,繼續雙寫,讀切到新資料。
- 階段三:停掉雙寫,删除老資料完成遷移
4.2 淘寶萬億級交易訂單的存儲引擎
淘寶超級量級下的交易單是怎麼解決存儲性能等問題的:
以上就是本篇文章的索引内容,如有遺漏和錯誤,歡迎補充和指正。