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