效能優化之資料庫篇5-分庫分表與資料遷移

女友在高考發表於2021-07-29

一、資料庫拆分

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/

相關文章