突破數據存儲瓶頸!轉轉業財系統億級數據存儲優化實踐
1.背景
1.1 現狀
目前轉轉業財系統接收了上游各個業務系統(例如:訂單、oms、支付、售后等系統)的數據,并將其轉換為財務數據,最終輸出財務相關報表和指標數據,幫助公司有效地進行財務管理和決策。
轉轉業財系統于2021年開始構建,前期為了滿足需求短時間內上線,選擇了主動接收上游業務系統的數據。然而隨著時間的推移,數據量在不斷增長,系統已經達到無法承載的邊緣,引發了許多問題。因此,我們需要對數據存儲進行優化。
1.2 數據量統計
業財系統數據量較大表統計:
表名 | 行數 | 數據長度 | 索引長度 |
出庫明細表 | 106280176 | 29.48GB | 34GB |
出庫單頭表 | 25344110 | 7GB | 6GB |
入庫明細表 | 22766910 | 8GB | 5GB |
銷售訂單表 | 29578659 | 10GB | 9GB |
應收單表 | 24686267 | 5GB | 2GB |
入庫單表 | 20777457 | 4GB | 6GB |
應付單表 | 15387724 | 4GB | 2GB |
以下是數據量較大的表數據增量趨勢圖,可以觀察到近幾個月由于新業務的增加,每月的數據增量已經達到一千萬。
1.3 慢查詢情況
從慢查詢監控平臺可以看到,每天慢查詢個數已經到達千量級別。慢查詢不僅影響用戶體驗,還會大量消耗所在機器資源,嚴重可能導致機器宕機。另外,轉轉MySQL數據庫架構屬于單機多實例,一臺物理機上部署多套集群的實例,所以不僅會影響系統本身集群,還會拖累其他集群,引發雪球效應。
2.設計目標
2.1 解決數據量問題
在未來五年,不用考慮數據庫數據量問題,能夠輕松應對未來的業務增長和覆蓋公司全量業務,且具備良好的擴展性,最終可以穩定向外輸出更多數據報表等。
2.2 解決讀寫性能
通過此次優化,提升報表查詢效率,減少定時任務執行時間,避免因為慢查詢導致任務失敗和接口超時問題,提高服務穩定性。
3.方案選擇
3.1 db存儲方案選型
為解決底層表數據量問題,我們對比了以下四個方案:
- 方案一:分庫分表
- 優點
- 將數據分散到多個數據庫和表中,從而減輕單一數據庫的負載壓力。這樣可以提高數據庫的讀寫性能和響應速度,降低查詢延遲。
- 拆分的表結構相同,程序改造較少。
- 缺點
- 需要提前規劃好分片規則,一旦定好規則就難以移動,擴展性比較差。
- 拆分規則很難抽象出來。
- 跨庫事務問題。
- 適用場景
- 數據庫面臨高并發訪問的壓力,又需要面對海量數據的存儲問題,這時需要對數據庫既采用分表策略,又采用分庫策略,以便同時擴展系統的并發處理能力,以及提升單表的查詢性能。
- 數據有統一的業務規則主鍵,使數據可以均勻分布。
- 業財系統適用分析
- 業財系統作為底層系統,接受了各個業務系統的數據,數據比較多樣性和復雜性,很難定義出一個業務主鍵,數據分布均勻困難。
- 若某業務數據量迅速增長或接入其他業務數據,那么可能又會面對數據量問題。
- 方案二:冷熱庫
- 優點
- 將不常訪問的數據從在線存儲中移動到歸檔存儲中,減少了在線存儲的容量需求,從而降低了存儲成本。
- 減少了在線存儲中數據的數量,因此可以提高數據庫讀寫性能。
- 可以將歷史數據長期保存,避免了數據的丟失。
- 可以將數據備份到不同的存儲位置,以便在需要時進行數據恢復。
- 缺點
- 需要保證歸檔事務性,防止歸檔數據同時出現在冷熱庫,出現數據重復。
- 需要考慮合適的歸檔策略,不影響服務訪問。
- 需要有明確的業務邊界,業務復雜的數據不適用。
- 適用場景
- 數據庫中存在大量的歷史數據,且查詢頻率比較低。
- 數據庫的寫入操作比讀取操作更頻繁。
- 數據庫的存儲成本較高,需要降低成本。
- 業財系統適用分析
- 業財系統業務數據復雜,現階段還會更改和查詢歷史數據,時間口徑不統一,邊界比較模糊,無法確認一個準確的邊界。
- 考慮后續接入更多的業務數據,由于目前無法統一數據格式,那么可能就需要重新考慮邊界等問題。
- 方案三:TiDB
- 優點
- 高度兼容 MySQL:大多數情況下,無需修改代碼即可從MySQL輕松遷移至TiDB。
- 水平彈性擴展:通過簡單地增加新節點即可實現 TiDB 的水平擴展,按需擴展吞吐或存儲,輕松應對高并發、海量數據場景。
- 缺點
- 仍有一些MySQL的特性和行為,TiDB目前暫時不支持或表現與MySQL有差異。
- 系統復雜,組件太多。
- 適用場景
- 對數據一致性及高可靠、系統高可用、可擴展性、容災要求較高的金融行業屬性的場景。
- 對存儲容量、可擴展性、并發要求較高的大量數據及高并發的OLTP場景。
- 數據匯聚、二次加工處理的場景。
- 業財系統適用分析
- 由于TiDB兼容了MySQL,所以改動點也較少。
- 近幾年是不用考慮數據量問題,可以接入更多樣化數據。
- TiDB能夠支持大表經常有加列減列的需求,可擴展性高,目前也比較符合業財現狀。
- 方案四:OceanBase
- 優點
- 高性能:采用了讀寫分離的架構,把數據分為基線數據和增量數據。其中增量數據放在內存里(MemTable),基線數據放在SSD盤(SSTable)。對數據的修改都是增量數據,只寫內存。所以DML是完全的內存操作,性能非常高。
- 高兼容:兼容常用MySQL/ORACLE功能及MySQL/ORACLE前后臺協議,業務零修改或少量修改即可從MySQL/ORACLE遷移至OceanBase。
- 高可用:數據采用多副本存儲,少數副本故障不影響數據可用性。
- 缺點
- 對環境要求極高,需要采購使用其指定的服務器。
- 學習和運維成本比較高。
- 盡管OceanBase具有高可用性的特性,但其實現仍然依賴于底層硬件和網絡的穩定性。
- 適用場景
- 金融級數據可靠性需求。金融環境下通常對數據可靠性有更高的要求,OceanBase 每一次事務提交,對應日志總是會在多個數據中心實時同步,并持久化。
- 數據庫面對飛速增長的業務數據量。
- 業財系統適用分析
- 目前運維沒有維護,所以就不考慮此方案,大家可以參考此方案是否適用于本身系統。
綜合以上各個方案的分析,目前最適用于轉轉業財系統的方案是TiDB。該方案能夠在短時間內解決數據量問題,并且改動成本相對較低。
3.2 慢查詢優化方案
在分析了慢查詢語句以后,發現大部分慢查詢都是由于聯表查詢導致的,所以此次主要解決聯表問題。聯表解決方案對比如下,根據適用分析選擇ES方案。
方案 | 業財適用分析 |
寬表 | 1.寬表可能包含大量重復數據,導致存儲空間的浪費。這會增加數據庫的存儲需求,尤其在大規模數據集上會更為顯著 2.由于涉及到大量列和關聯數據,后續性能優化可能需要考慮更多的因素,而且可能需要采用復雜的索引策略 3.復雜度增加,改動量比較大 |
ES | 1.通過建立索引方式解決聯表問題,也一并提高了查詢效率 2.后續可擴展性比較高,增加查詢條件等,都易實現 3.需要保持數據源與ES數據一致問題 4.可以減低現有的數據庫索引數據量 |
4.方案實踐
4.1 方案實踐步驟
根據方案選擇分析,最適合業財系統當前狀況的方案是首先切換底層數據存儲,然后再接入ES。在實施這兩個方案之前,我們需要考慮它們的先后順序,并分析業財系統的現狀。由于數據量的突增,考慮到現有業務和后續新增業務,同時在不影響現有使用的前提下,首要需要解決的問題是數據量。因此,我們建議首先切換底層數據存儲。這樣做的好處是,即使在后續的實施中遇到問題,我們仍然可以回滾到原有的數據存儲。這樣既可以保證數據的完整性,也減少了實施過程中的風險。另一方面,如果我們選擇先接入ES,就需要考慮如何保證數據切換過程中的數據完整性,并且同步方式也需要考慮兩種不同數據存儲方案之間的兼容性,這將增加許多額外的工作量和風險。
綜上所述,我們選擇的優化步驟是首先切換底層數據存儲,待其穩定后再接入ES。這樣能夠有效解決當前的數據量問題,同時保證系統的穩定性和數據完整性。隨后,我們可以繼續進行ES的接入,以進一步優化業財系統的性能。
4.2 切換底層數據存儲步驟
在選擇數據遷移方式時,考慮到業財系統對實時性要求并不是很高,且評估了下目前大部分數據接入寫入方式,是可以接受停寫幾分鐘,這樣便大大降低了整個數據遷移成本。
遷移過程要求:
- 檢查TiDB是否都能兼容目前服務中的SQL語句,保證遷移之后系統不會報錯。
- 數據需要保證完整性,遷移之后需要保證MySQL庫和TiDB庫的數據是嚴格一致。
- 遷移過程中需要做到可以回滾,一旦遷移過程中出現問題,可以立即回滾到MySQL庫,不會對系統可用性造成影響。
4.3 接入ES
- 根據報表查詢頁面的功能和聯表SQL分析,我們進行了索引模型設計,核心是優化查詢性能和提高系統的響應速度。
- 在建立索引模型之后,我們需要考慮數據庫(DB)與Elasticsearch(ES)之間增量數據的同步方式。
以下表格是對比了四種不同的同步方式,我們根據已設計的索引分析,考慮到每個索引涉及的表較多、相關業務代碼尚未收口以及對實時性較高的需求,我們決定采用數據訂閱的方式進行同步。在當前公司提供的實現方式中,我們選擇了Kafka。
同步方式 | 優點 | 缺點 |
同步雙寫 | 這種方式簡單粗暴,實時性高 | 1.業務耦合:這種方式代碼侵入性強,耦合大量數據同步代碼,要在寫DB的地方寫ES的代碼 2. 影響性能:寫入兩個存儲,響應時間變長,系統的性能必然會下降 3.不便擴展:搜索可能有一些個性化需求,需要對數據進行聚合,這種方式不便實現 4.高風險:存在雙寫失敗丟數據風險 |
異步雙寫 | 1.性能高 2.不易出現數據丟失問題 3.多源寫入之間相互隔離,便于擴展更多的數據源寫入 | 1.硬編碼問題,接入新的數據源需要實現新的消費者代碼 2.系統復雜度增加,引入了消息中間件 3.MQ是異步消費模型,用戶寫入的數據不一定可以馬上看到,造成延時 |
定期同步 | 實現比較簡單 | 1.實時性難以保證 2.對存儲壓力較大 |
數據訂閱 | 1.業務入侵較少 2.實時性比較高 | 需要選型數據訂閱框架,系統復雜度增加 |
- 在增量數據同步以后,最后一步就是需要完成歷史數據的同步,此次我們選擇的同步方式是公司內部提供的ECP,可以參考文章:不可思議!億級數據竟然如此輕松同步至ES!
5.總結與成果
目前,業財系統已成功完成底層數據存儲的切換,可以看到近幾年來不再擔心數據量存儲的問題,并且成功接入了更多的業務數據。隨著引入了Elasticsearch(ES),業務人員也不再反饋報表頁面超時等問題。這次針對數據存儲的優化實質上是對系統的重構,選擇方案時考慮了對系統影響范圍較小且不影響業務人員使用的因素,這也是優化的核心所在。
由于歷史原因,業財系統仍存在許多需要優化的方面,如慢SQL的持續治理、定時任務優化等。因此,我們需要保持此優化的核心理念,并在后續的重構中繼續完善,以使業財系統更加穩定。