分庫分表引起的問題以及處理方式

本文節選自《可伸縮服務架構:框架與中間件》一書,作者:李豔鵬、楊彪、李海亮、賈博巖、劉淏。


分庫分表按照某種規則將數據的集合拆分成多個子集合,數據的完整性被打破,因此在某種場景下會產生多種問題。


擴容與遷移


在分庫分表後,如果涉及的分片已經達到了承載數據的最大值,就需要對集羣進行擴容。擴容是很麻煩的,一般會成倍地擴容


通用的擴容方法包括如下5個步驟。

  • 按照新舊分片規則,對新舊數據庫進行雙寫。

  • 將雙寫前按照舊分片規則寫入的歷史數據,根據新分片規則遷移寫入 新的數據庫。

  • 將按照舊的分片規則查詢改爲按照新的分片規則查詢。

  • 將雙寫數據庫邏輯從代碼中下線,只按照新的分片規則寫入數據。

  • 刪除按照舊分片規則寫入的歷史數據。


這裏,在第2步遷移歷史數據時,由於數據量很大,通常會導致不一致,因此,先清洗舊的數據,洗完後再遷移到新規則的新數據庫下,再做全量對比,對比後評估在遷移的過程中是否有數據的更新,如果有的話就再清洗、遷移,最後以對比沒有差距爲準。


如果是金融交易數據,則最好將動靜數據分離,隨着時間的流逝,某個時間點之前的數據是不會被更新的,我們就可以拉長雙寫的時間窗口,這樣在足夠長的時間流逝後,只需遷移那些不再被更新的歷史數據即可,就不會在遷移的過程中由於歷史數據被更新而導致代理不一致。


在數據量巨大時,如果數據遷移後沒法進行全量對比,就需要進行抽樣對比,在進行抽樣對比時要根據業務的特點選取一些具有某類特徵性的數據進行對比。


在遷移的過程中,數據的更新會導致不一致,可以在線上記錄遷移過程中的更新操作的日誌,遷移後根據更新日誌與歷史數據共同決定數據的最新狀態,來達到遷移數據的最終一致性。


分庫分表維度導致的查詢問題

這裏我們分析分庫分表中的查詢問題。


在分庫分表以後,如果查詢的標準是分片的主鍵,則可以通過分片規則再次路由並查詢;但是對於其他主鍵的查詢、範圍查詢、關聯查詢、查詢結果排序等,並不是按照分庫分表維度來查詢的。


例如,用戶購買了商品,需要將交易記錄保存下來,那麼如果按照買家的緯度分表,則每個買家的交易記錄都被保存在同一表中,我們可以很快、很方便地查到某個買家的購買情況,但是某個商品被購買的交易數據很有可能分佈在多張表中,查找起來比較麻煩。反之,按照商品維度分表,則可以很方便地查找到該商品的購買情況,但若要查找到買家的交易記錄,則會比較麻煩。


所以常見的解決方式如下。

  • 在多個分片表查詢後合併數據集,這種方式的效率很低。

  • 記錄兩份數據,一份按照買家緯度分表,一份按照商品維度分表。

  • 通過搜索引擎解決,但如果實時性要求很高,就需要實現實時搜索。


實際上,在高併發的服務平臺下,交易系統是專門做交易的,因爲交易是核心服務,SLA的級別比較高,所以需要和查詢系統分離,查詢一般通過其他系統進行,數據也可能是冗餘存儲的。


這裏再舉個例子,在某電商交易平臺下,可能有買家查詢自己在某一時間段的訂單,也可能有賣家查詢自己在某一時間段的訂單,如果使用了分庫分表方案,則這兩個需求是難以滿足的。因此,通用的解決方案是,在交易生成時生成一份按照買家分片的數據副本和一份按照賣家分片的數據副本,查詢時分別滿足之前的兩個需求,因此,查詢的數據和交易的數據可能是分別存儲的,並從不同的系統提供接口。


另外,在電商系統中,在一個交易訂單生成後,一般需要引用到訂單中交易的商品實體,如果簡單地引用,若商品的金額等信息發生變化,則會導致原訂單上的商品信息也會發生變化,這樣買家會很疑惑。因此,通用的解決方案是在交易系統中存儲商品的快照,在查詢交易時使用交易的快照,因爲快照是個靜態數據,永遠都不會更新,所以解決了這個問題。可見查詢的問題最好在單獨的系統中使用其他技術來解決,而不是在交易系統中實現各類查詢功能;當然,也可以通過對商品的變更實施版本化,在交易訂單中引用商品的版本信息,在版本更新時保留商品的舊版本,這也是一種不錯的解決方案。


最後,關聯的表有可能不在同一數據庫中,所以基本不可能進行聯合查詢,需要藉助大數據技術來實現,也就是上面所說的第3種方法,即通過大數據技術統一聚合和處理關係型數據庫的數據,然後對外提供查詢操作,請參考第5章的內容。


通過大數據方式來提供聚合查詢的方式如圖所示。

跨庫事務難以實現

 要避免在一個事務中同時修改數據庫db0和數據庫db1中的表,因爲操作起來很複雜,對效率也會有一定的影響。請參考3.3.3節的內容。

同組數據跨庫問題

 要儘量把同一組數據放到同一臺數據庫服務器上,不但在某些場景下可以利用本地事務的強一致性,還可以使這組數據自治。以電商爲例,我們的應用有兩個數據庫db0db1,分庫分表後,按照id維度,將賣家A的交易信息存放到db0中。當數據庫db1掛掉時,賣家A的交易信息不受影響,依然可以正常使用。也就是說,要避免數據庫中的數據依賴另一數據庫中的數據。



END


本文分享自微信公衆號 - IT一刻鐘(it_info)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章