性能優化之數據庫篇5-分庫分表與數據遷移


一、數據庫拆分

1. 為什么要做數據庫拆分

單機數據庫存在的問題?

從容量、性能、可用性和運維成本上難以滿足海量數據的場景。

  1. 性能方面,數據量超過一定閾值,B+樹索引慎獨增加導致磁盤訪問的IO次數增加,進而導致查詢性能的下降。
  2. 容量方面,單機能存儲的數據量有限
  3. 可用性方面,大量的查詢落到單一的數據庫節點或者簡單的主從架構上,數據庫很難承擔。
  4. 運維方面,數據量達到一定閾值,主從同步延遲高、增加字段索引、備份這些都會很慢,影響業務系統。

主從結構解決了高可用、讀擴展。但是單機容量不變,單機寫性能無法解決。

為了解決這些問題,我們需要采用分庫分表,將數據庫拆分開。降低單個節點的寫壓力,提升整個系統的數據容量上限。

擴展立體方

  • X軸:通過clone整個系統復制,集群
  • Y軸:通過解耦不同功能復制,業務拆分
  • Z軸:通過拆分不同數據擴展,數據分片

2. 垂直拆分

垂直拆分,按照業務緯度分庫分表。

垂直拆庫

將一個數據庫,拆分為多個提供不同業務數據處理能力的數據庫。如:將一個電商的單獨庫拆為用戶庫、訂單庫、商品庫。

垂直拆表

如果單表數據量過大,還需要對單表進行拆分。如:一個200列的訂單主表,拆分為十幾個子表:訂單表、訂單詳情表、訂單收件信息表等。

垂直拆分的優缺點:

優點:

  • 單庫(單表)變小,便於管理
  • 對性能和容量有提升
  • 拆分后,系統和數據復雜度降低
  • 可以作為微服務改造的基礎

缺點:

  • 庫變多,管理變復雜
  • 對業務系統有較強的侵入性
  • 改造過程復雜,容易出故障
  • 拆分到一定程度就無法繼續拆分

3. 水平拆分

水平拆分就是直接對數據進行分片,有分庫和分表兩個具體方式。不改變數據本身的結構,只是降低單個節點數據量。這樣對業務系統本身的代碼來說不需要做特別大的改動,甚至可以基於一些中間件做到透明。

比如把一個10億條記錄的訂單的單庫單表。按用戶id除以32取模,將單庫拆分為32個庫;再按訂單id除以32取模,每個庫再拆為32個表。這樣就是32*32=1024個表,單個表數據量就只有不到百萬條了。

水平分庫分表

一般來說我們我們的數據都是有創建時間的,可以按時間拆分,按照年、季度、月、天都可以。

或者根據用戶拆分、甚至可以根據一些自定義的復雜的邏輯來拆分。

為什么有時候不建議分表,只建議分庫?

因為分表不能解決容量問題,如果瓶頸在IO(磁盤IO、網絡IO)上,分表也解決不了,因為分表還是在同一個機器,而分庫可以在兩個機器上。

分庫還是分表,如何選擇?

一般情況下,如果數據本身讀寫壓力較大,磁盤IO已經成為瓶頸,那么分庫比分表要好。而使用不同的庫,可以並行提升整個集群的並行數據處理能力。

相反的情況下,可以盡量考慮分表,降低單表的數據量。

水平分庫分表的優缺點:
優點:

  • 解決容量問題
  • 比垂直拆分對系統影響小
  • 部分提升性能和穩定性

缺點:

  • 集群規模大,管理復雜
  • 復雜SQL支持問題
  • 數據遷移問題
  • 一致性問題

4. 數據的分類管理

數據的分類管理是指通過對數據進行分類提升數據管理能力。

隨着對業務系統、對數據的分析了解發現,很多數據對質量的要求是不一樣的。

如訂單數據,肯定一致性要求最高,不能丟失。而一些日志數據,中間數據,則沒有那么高的一致性。丟了就丟了。

另外,同一張表里的訂單數據也可以采用不同策略,無效訂單比較多,我們可以定期轉移或清除。(一些交易系統里80%以上的是下單后取消的無意義訂單,所以可以清理它

如果沒有無效訂單,也可以考慮:

  1. 最近一周下單但是未支付的訂單,被查詢和支付的可能性較大。而再以前一點的,可以直接取消掉。
  2. 最近3個月下單的數據,被在線重復查詢和系統統計的可能性最大。
  3. 3個月以前-3年以內的數據,查詢的可能性小,可以不提供在線查詢
  4. 3年以上的數據,可以直接不提供任何方式的查詢。

這樣的話,我們就可以根據分類采用一定的手段去優化系統:

  1. 定義一周內下單但未支付的數據為熱數據,同時放到數據庫和內存
  2. 定義3個月內的數據為溫數據,放到數據庫,提供正常的查詢操作
  3. 定義3個月到3年的數據為冷數據,從數據庫刪除,歸檔到一些便宜的磁盤,用壓縮的方式(比如MySQL的tokuDB引擎)存儲,用戶需要查詢的話提工單來查詢
  4. 定義3年以上的數據為冰數據,備份到磁帶之類的介質上,不提供任何查詢操作。

5. 數據庫中間件

數據庫中間件的技術演進

ShardingSphere是一套開源的分布式數據庫中間件解決方案組成的生態圈,它由JDBC、Proxy和Sidecar(規划中)這3款相互獨立,又能混合部署配合使用的產品組成。它們均提供數據分片、分布式事務和數據庫治理功能,可適用於如Java同構、異構、雲原生等各種多樣化的應用場景。

ShardingSphere-JDBC

框架ShardingSphere-JDBC,可以直接在業務代碼使用,支持常見的數據庫和JDBC。只適用於Java語言。

使用實例:

二、數據遷移

方案一:全量

  1. 業務系統停機
  2. 數據庫遷移,校驗一致性
  3. 業務系統升級,接入新數據庫

如果新數據庫結構一樣,可以dump后全量導入。如果是異構的話,需要用程序處理。

方案二:全量+增量

依賴於數據本身的時間戳

  1. 先同步數據到最近的某個時間戳(如前一天)
  2. 然后再發布升級時停機維護
  3. 再同步最后一段時間的變化數據
  4. 最后升級業務系統,接入新數據庫。

方案三:binlog+全量+增量

  • 通過主庫或從庫的binlog來解析和重新構造數據,實現復制。
  • 一般需要中間件工具的支持。

可以實現多線程,斷點續傳,全量或增量的數據同步。

繼而可以做到:

  1. 實現自定義復雜異構數據結構
  2. 實現自動擴容和縮容,比如分庫分表到單庫單表、單庫單表到分庫分表、分4個庫到分8個庫等等。

下面介紹一個遷移工具:

ShardingSphere-scaling

下載包:https://archive.apache.org/dist/shardingsphere/4.1.0/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM