mysql 多张表公用一个序列_Mysql--序列3--分库分表策略
分庫分表是存儲層設計中一個普遍而重大的問題,什么時候分?怎么分?分完之后引發的新問題,比如不能Join、分布式事務? 本篇將從最基本的策略出發,逐步深入講解這里面涉及的一序列策略。
分庫-業務分拆 & 數據隔離
分庫的首先目的就是做“業務分拆“,關于業務分拆,在前面的序列文章“分布式系統--基本思想匯總“中已經有闡述。通過業務分拆,把一個大的復雜系統拆成多個業務子系統,之間通過RPC或消息中間件通信。這樣做既便于團隊成員的職責分工,也便于對未來某個系統做擴展。
另外一個考慮角度是“數據隔離”。如果你把核心業務的數據和非核心業務數據放在一個庫里面,不分輕重,同等對待。這樣如果因為非核心業務把DB搞掛了,核心業務也受到牽連。分開之后,區別對待,投入的開發和運維人力也不一樣。
讀多寫少 vs. 讀少寫多
對于業務來講,讀多寫少/讀少寫多,所對應的策略是不一樣的。
如果是讀多寫少,那你可以通過加從庫、加緩存來解決,不一定要分庫分表。
如果是讀少寫多,或者說寫入的QPS已經達到了DB的瓶頸,這個時候就得考慮分庫分表了。
對于MySQL來講,一般寫入的QPS有3k/s左右,讀寫的QPS可以達到2萬/s。可見寫入和查詢的吞吐量區別是很大的。
分表/分庫
考慮了上面2個策略之后,最后萬不得已,再做分庫分表。因為分庫分表的代價是很大的,意味著代碼要大規模重構,以前能用的join,事務可能都不能用了,需要用新的辦法解決。
垂直切分
垂直切分一般主要用于表的字段太多(比如上百個字段),這種情形通常就對應著上層業務沒有很好的分拆,解耦。如果做好了上面的“業務分拆”,需要這種“垂直切分”的場景可能就會變得很少。下面主要講“水平切分”。
水平切分
當表的記錄數太多,幾千萬,上億,并且有很高的寫入QPS,這個時候就得考慮水平切分了。
一般思路是:保證單表的記錄條數不要超過千萬,然后根據總數據量估算出要拆多少個表,再考慮把這些表分散到多少個庫里面。
水平切分的最關鍵問題就是:拆分維度的選擇。
拆分維度(字段)的選擇
比如電商的訂單表,至少有3個查詢維度:訂單id,用戶id,商戶id。那你拆分的時候,根據哪個維度進行拆分呢?
假設你按用戶id拆分,同一個用戶的所有訂單記錄都落到同1個庫的同1張表里面。那查詢的時候,按user id查,就很容易;
但如果按訂單id,或者商戶id呢?拆分之后,同1個商戶id的訂單,可能被分到了不同的庫、不同的表里面,根本沒辦法查。
對于這種分庫分表之后,其他維度的查詢,一般有以下幾個辦法:
(1)建立一個映射表,建立輔助維度和主維度之間的映射關系(也就是商戶id和用戶id之間的映射關系)。? 查詢的時候,根據商戶id,查出用戶id。再根據用戶id,來查
(2)業務雙寫? 同1份數據,2套分庫分表。1套按user id切分,1套按商戶id 切分。這個其實也就是我在”分布式系統--基本思想匯總“中所用的“重寫輕讀”
(3)異步雙寫? 還是2套表,只是業務單寫。然后通過binlog同步(比如阿里的canal,點評的puma),同步到另外一套表上。
(4)2個維度統一到1個維度? 這個在特殊的場景下可以使用。比如order id和user id就可以統一成1個維度,把user id作為order id中的某幾位,這樣order id中就包含了user id信息。無論按user id,還是order id,都可以hash算出所在的庫,所在的表。
Join問題
分庫分表之后,有些Join就不能用了,針對這種情況,一般有下面幾種解決辦法:? (1)把Join拆成多個單表查詢,上層業務代碼進行結果拼裝? (2)提前做寬邊,重寫輕讀? 很多時候,你有這樣的情況:需要把Join的結果分頁,這個需要利用mysql本身的分頁功能。對于這種不得不用Join的情況,可以另外做一個Join表,提前把結果Join好。這是“重讀輕寫”,其實也是“空間換時間”的思路。? (3)利用搜索引擎? 對于(2)當中提到的場景,還可以利用Lucence,ES這種搜索引擎,把DB中數據導入到搜索引擎中來查詢,從而解決Join問題。
分布式事務
做了分庫之后,純DB的事務就搞不了了。一般解決辦法都是:通過精心選擇維度,優化業務,避免跨庫的事務,保證所有事務都落到單庫上面。
如果實在無法避免,那就需要分布式事務的解決方案了。關于分布式事務,又是一個系統化的課題,沒有一個標準答案。
后續文章會詳細闡述這個問題,敬請期待!
總結
以上是生活随笔為你收集整理的mysql 多张表公用一个序列_Mysql--序列3--分库分表策略的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 红眼病的症状有哪些
- 下一篇: java string字节数组_java