-
1 # 架構思維
-
2 # 淺析架構
1.最佳化SQL加索引
2.業務是否可以垂直拆分,業務拆分了可以分庫
3.業務單邊資料量還是大,是否可以把一些欄位獨立出去,表垂直拆分。水平拆分表可以按時間,或者id的has值進行拆分
4.分庫分表必然帶來很多問題,比如關聯查詢,聚合等操作,可以嘗試下NewSQL,業務不再關心分庫分表操作了。國內開源實現有TiDB,可以瞭解下,NewSQL應該是未來的趨勢。
-
3 # JAVA前線
1 阿里開發手冊的建議
關於分庫分表,阿里開發手冊有這樣的建議:單錶行數超過500萬行或者單表容量超過2G,才推薦進行分庫分表。如果預計三年後的資料量根本達不到這個級別,請不要在建立表時就分庫分表。
2 分庫分表實踐分庫分表是比較複雜的工作,有以下要點需要考慮:遷移資料的準確性,系統是停機還是不停機,上線後資料驗證,分表後資料統計,分庫後分布式事務,出現異常回滾方案等等。所以決定分庫分表前,一定要考慮周全。
3 我的建議先從語句效能考慮,找出慢SQL,看看索引是否使用得當,先最佳化語句,成本最小。
再考慮增加快取,將熱點資料快取起來,本地快取效能最好,分散式快取也可以。
最後思考分庫分表,優先考慮分表,再考慮分庫。建議最好由有經驗的同事主導。
-
4 # 一席話君
不到萬不得已,不要分庫分表。
資料庫遇到瓶頸,應該首先考慮最佳化。sql伺服器硬體最佳化,sql語句最佳化,索引最佳化,讀寫分離,快取層。
如果都不行,那就只能考慮分庫分表了,可以利用mycat,DBProxy等中介軟體。
一旦分庫分表,就會引出分散式事物,應該儘量避免。關聯查詢,聚合統計等操作等地方也有坑,一定要注意!
個人建議:一般到了分庫分表的地步,都是因為資料量到了一定級別,單臺伺服器無法承受。一般都是某幾張表或者某個庫資料量過大。與其費力分庫分表,倒不如考慮一些新興的資料庫,例如HBase或者TiDB等newSQL甚至ES。如果這些大表,不涉及複雜,需要考慮事物的業務,完全可以頂上。
本人專注網際網路前沿動態,大資料,資料採集,資料處理,資料治理,望交流!
-
5 # 會點程式碼的大叔
大部分的軟體架構、元件或解決方案,都是在解決一些問題的同時,會帶來另外的問題。
資料庫的分庫分表,又可以分為垂直拆分和水平拆分(可能大家常說的分庫分表主要指的是後者):
垂直拆分:這是一種比較常見的資料庫設計方法,就是把一個欄位比較多的大表,拆分成多個小表,特別是在現在分散式、微服務的架構下,可以把各個小表按照業務模型,劃分到不同的資料庫中,這樣就可以利用多臺資料庫伺服器的效能;但當被拆分出來小表的資料量不斷增長,到了一個極限的時候,還是需要考慮水平拆分。
水平拆分:將表中的資料,按照一定的規則分佈到不同的資料庫中,比如對主鍵進行Hash和取模操作後,按照結果把資料路由到對應的資料庫上;水平分庫分表,可以降低每張表的資料量,這也是現在大部分公司所使用的方法。
資料庫擴容問題上文中說到,水平拆分常用的手段是對主鍵進行Hash和取模操作後,按照結果把資料路由到對應的資料庫上;但如果被拆分的子表,資料量也達到極限值以後,就要面對資料庫擴容的問題,比如開始規劃分成8個庫,現在要擴到16個庫;
路由規則發生變化:hash(id)%8 變成了 hash(id)%16,那麼歷史資料也就要面臨遷移的問題;這種情況,要麼做資料遷移,要麼增加分表演算法的複雜性,讓演算法可以相容增加分表前後的資料路由。
複雜查詢、關聯查詢、order by、group by等的問題在單庫時代,複雜的關聯查詢是很容易實現的,但是資料庫被拆分後,資料被儲存在了不同的資料庫伺服器上,那麼誇庫的join就成了很大的問題。通常解決方案有:
如果是垂直拆分,那麼可以考慮做一定程度的欄位冗餘,避免跨表關聯;或者可以做資料同步,把需要的表同步到同一個庫中,進行表關聯;
程式碼層面組裝,也就是把兩邊的資料都拿出來,然後在程式碼裡面關聯組裝;或者先獲取主表資料,再把其餘欄位補齊;但是從實際情況來看,這個方案在大多數場景下,實現起來都比較困難;
現在一個比較主流的做法,是引入ES或ES+HBase或solr+HBase,把部分欄位的全量資料儲存在同一個地方。
ID問題在水平拆分的場景下,一單一張表被拆分成多張表部署在多個數據庫中,那麼就不能使用資料庫自身的主鍵生成機制了;這時候就需要由我們自己來考慮主鍵生成策略:
主鍵生成中心:可以利用資料庫、Redis、MongoDB、zookeeper等元件實現,需要生產主鍵的時候,呼叫主鍵生成中心的介面;缺點也很明顯,增加了網路開銷,並且主鍵生成中心如果發生問題,後果會很嚴重。
UUID:本地生成,不需要第三方元件,生成比較簡單,效能好;不過缺點也不少,長度長,不利於儲存,並且沒有排序,是個字串,不利於查詢。
一些唯一性ID的生成演算法:比如Snowflake、UidGenerator、Leaf等等。
事務問題單庫的時候,解決事務問題很簡單,但是現在要保證跨庫的事務問題,需要額外的成本;
這種場景下(效能要求高,一致性要求不是那麼的高),大部分公司會放棄事務的【實時】一致性,只要在一定的時間內,事務【最終】一致即可。
回覆列表
分庫分表是比較靠後的最佳化手段,因為成本比較高。
遇到資料庫瓶頸:
- 首先考慮sql最佳化,這是最簡單的方法。對現有系統基本沒有影響。
- 其次就是考慮資料庫的讀寫分離,這也是相對簡單的方法。在資料庫層面進行配置,系統層面只需要調整一下獲取資料庫連線的邏輯。讀資料時即可以獲取主庫連線,也可以獲取從庫連線。寫資料時只獲取主庫連線。
- 再考慮增加快取層。將資料快取到快取中,當再次訪問時不再從資料庫獲取。一般快取層對系統是透明的,基本對系統本身沒有影響。但是引入快取,也引入了相應的需要考慮的問題,比如雪崩,命中率,分散式快取等
- 還有一種非技術手段,就是改需求。引起效能問題的原因是否是需求不合理?或者需求太複雜?是否可以簡化需求?此方法對系統的影響也相對較小。
- 最後才考慮分庫分表。優先分庫,因為相對分表更簡單。將對應的表移動到新庫,調整系統獲取資料庫連線的邏輯。這裡需要考慮要移動哪些表,在提高效能的前提下,首先儘量避免分散式事務。
- 最最後,考慮分表。分表的主要原因是單表資料量太大。分表又分縱切和橫切。縱切就是按列切,比如使用者表,常用資訊為基本資訊表,其它資訊為詳情表。橫切就是按行切,比如一億資料量的表切分為十張一千萬的表。這裡就涉及資料該存放到哪張表,或從哪張表裡取。分表後又可以分庫,來進一步最佳化。
- 如果涉及到分散式事務,又要考慮如何保證分散式事務。理論方面2pc,3pc,paxos,cap,base。對應的中介軟體的使用。
對系統的設計和最佳化不是人云亦云,需要根據實際的場景來進行處理。