隨着業務的迅速發展,農業銀行某系統承擔的運行壓力越來越大。現階段, 該系統每天的交易量在2300 萬筆以上,峰值達2950 萬筆。交易量的攀升導致了后台數據庫數據量的激增,從而影響了聯機程序響應時間,也增加了系統各類資源開銷和后續數據分析的處理時間。為保障系統穩定運行,項目組從增加系統資源、優化資源配置、優化重點程序和升級系統數據庫等多個維度對系統進行了綜合優化。下面筆者從大表、熱表的數據分析和優化角度,闡述對大數據量表進行的存儲優化。
一、大表數據分析
目前農業銀行某系統工作流數據量最大且訪問最頻繁的兩張核心表:
(1)流程實例表,用於存儲系統發起的所有流程實例,包括基本流程、會簽流程、補充資料流程和抄送流程;
(2)任務實例表,用於存儲每個流程實例的流轉記錄。
截至2013 年4 月1 日, 工作流兩張大表的數據量如表1 所示。其中任務實例表為系統中數據量最大的一張表,達到了1.2 億。根據ProDBA 抓取的執行次數最多且執行時間最長的前30 條SQL 信息中,顯示流程實例表和任務實例表壓力比較大。大表中的數據按照結束時間和狀態兩個維度可以區分為三類:
(1)正在運行的流程數據,即業務正在辦理過程中,尚未結束;
(2)已結束流程一年內的數據,即業務總體流程已經結束,期限在一年內(包含一年);
(3)已經結束流程一年以上的數據,即業務總體流程已經結束,期限在一年以上(如表2 所示)。事實上,由於存在業務制度等方面的規定,已經結束一年以上的數據基本處於靜態無變化的情況,不會發生修改、刪除等數據操作,但是占據了一定的表空間,同時也影響了對其他運行中數據的訪問效率。為降低大數據量對系統訪問的影響,需制定遷移規則,進行數據拆分。
二、拆分規則
根據上述大數據表的數據分布特點,建立三套表結構:運行表、歷史表和備份表。運行表僅存儲正在運行的流程數據,流程結束后(正常完成或者終止)將基本流程以及其所屬子流程相關的所有數據(流程實例、任務實例、流程變量、異常、分支等)實時遷移至歷史表。如業務需要將已結束的流程恢復,系統支持流程從歷史表實時遷回到運行表繼續流轉,整個過程對用戶是完全透明的。
由於已完成和終止一年以上的流程,需恢復的業務需求很少(系統上線以來未發生過類似業務),因此由備份表存放第三類數據,形成三級存儲模式如圖1 所示。歷史表中的數據,每年執行一次批量拆分操作,拆分至備份表。
為保障數據平穩的遷移,應采取分布實施的策略。2012 年12 月8日,流程結束數據實時遷移到歷史表功能先期投產,因此目前工作流運行表中存放的數據包含三種情況:正在運行的數據;2012 年5 月至2012 年12 月結束的流程;2012 年5 月前結束一年以上的流程(如圖2所示)。
按照數據三級存儲規則,需要對大數據表進行拆分、剝離及整合,最終實現運行表只存儲運行的數據,降低系統壓力(如圖3 所示)。
三、問題分析及拆分策略
1. 數據表重命名
數據遷移前需要對流程實例表和任務表進行BCP 數據備份,以確保出現異常情況時,可及時恢復數據。任務實例表(1.2 億)和流程實例表(2 千萬),備份估計需要2~3個小時。數據遷移最終要達到運行表中僅存放流程正在運行中的數據,因此采取如下策略,節省BCP 備份時間。
首先,創建任務實例和流程實例中間表,表結構和運行表保持完全一致;其次,將運行表中正在運行的數據遷移至中間表;再次,對流程運行表和中間表重命名,實現中間表轉換為運行表,運行表轉換為備份表。如出現數據遷移異常和驗證不通過等情況,由於備份表保存了遷移當日的全量數據,因此,再次執行數據表重命名即可解決問題,無需再對兩張大表進行BCP 備份。數據表重命名腳本執行時間,經測試在1 分鍾內即可完成,大大減少遷移時間。
2. 數據完整性
一筆完整的流程,包含一條流程實例和多條任務實例,任務實例根據流程實例編號和狀態等屬性,確定所屬流程。遷移方法一:為保障遷移數據完整,需要根據流程的狀態,查詢流程和關聯任務的記錄,一次性遷移兩張表的記錄,如遷移失敗同時回滾,因此,需要進行任務實例表和流程實例表關聯。考慮到兩張表的數據量,此方案將會導致遷移效率很低。經測試,遷移5萬筆流程(5 萬條流程和36 萬條任務記錄) 數據約7分鍾,循環執行遷移,遷移完全部流程數據需要約42 個小時。
為提高拆分效率,減少對投產時間窗口的占用,對拆分方法進行了優化。遷移方法二:首先,流程實例表按照I D 號升序排列,取前50 萬條記錄存放至臨時表;其次,將臨時表(50 萬)和任務表(1.2 億)進行關聯,遷移流程所屬的所有任務;再次,再遷移50 萬條流程記錄;最后,刪除臨時表。循環執行操作,每次遷移,以前一次遷移的最大I D 號為條件, 再取50 萬條記錄。此方法同樣可以保障事務一致性,每次遷移兩張表的數據,但是少了表關聯的數據量。經測試,遷移50 萬筆流程(包括流程和任務記錄)數據約8 分鍾,遷移正在運行的數據預計可在1 個小時內完成。兩種遷移方法對比示意如圖4所示。
3. 自增字段
任務實例表和流程實例表的主鍵ID,同為Identity 型字段。數據遷移過程中,要保持ID 號一致。首先,建表DBO 用戶和數據遷移操作用戶需保持一致;其次,數據遷移腳本中,使用SET IDENTITY_INSERT 表名 ON 命令強制關閉對表的自增字段設置;再次, 遷移完成后,再使用SET IDENTITY_INSERT 表名 OFF 命令再打開自增字段設置。
4. 划分數據拆分批次
對拆分策略和腳本進行測試和優化后,完成全部遷移仍然需5 個小時左右,因此考慮分批次執行。在數據拆分規則中,數據被區分為三類,根據此規則遷移分為兩個批次:一是執行遷移正在運行的數據;二是執行遷移已經完成流程一年內的數據。盡可能減小兩批次執行的時間間隔。第一批次執行完成后,流程運行中的數據不受影響,一年內已結束的流程如需恢復,將受到影響。考慮到業務的實際辦理情況,流程結束后再次被恢復的情況很少,因此分兩個批次執行的影響面積較小。
四、數據遷移方案實踐
以遷移正在運行的數據為例,闡述數據遷移過程。遷移流程結束一年內的數據到歷史表的操作過程同此,不再贅述。
1. 操作步驟
第一,執行腳本查詢流程實例表和任務實例表,獲取數據以備驗證。同時查詢最大流程和任務I D號, 以備在步驟六中設置自增起始值。
第二,創建中間表,表結構和運行表保持一致。
第三, 遷移未完成流程數據,每次遷移50 萬個流程,檢查日志內容,直到執行影響結果不足50 萬個,證明數據遷移完成。
第四,執行數據驗證腳本,比較此腳本的執行結果和步驟1 中的執行結果是否一致。如不一致,后續步驟不再執行。
第五,執行腳本對流程運行表和中間表重命名,執行完成后驗證表結構是否一致。
第六,根據步驟一的查詢結果,設置運行表自增字段的起始值。
第七,開啟工作流WAS,由開發人員進行驗證。如驗證通過,關閉工作流WAS ;如驗證不通過,執行應急方案。執行完成后再次進行驗證。
第八,進行運行表的索引統計值更新(如圖5 所示)。
2. 應急方案
(1)異常情況一:執行遷移腳本出現時間超長等異常情況,在計划時間窗口內不能正常執行完成。應急方案:遷移腳本未對運行表進行更新和刪除等操作,數據未受影響,因此后續操作步驟不再執行,刪除中間表即可。
(2)異常情況二:數據拆分完成,開啟工作流WAS 驗證,開發人員驗證不通過。應急方案:執行腳本將運行表更名為中間表,備份表更名為運行表,執行完成后,再次由開發人員進行驗證,驗證通過刪除中間表。
3. 數據量比較
經過兩輪遷移,數據量對比如表3 所示,從中可以看出訪問最頻繁的運行表數據量減少95%。
4. 結論
數據經過拆分、剝離及整合后形成了三級存儲模式。流程結束后數據實時轉移到歷史表,而運行表數據增量變化不大,因此有效解決了由於數據量巨大帶來的數據訪問響應時間長等問題,提升了系統性能。
五、未來規划
數據遷移完成后,根據數據增長特點,每年對歷史表數據進行一次批量遷移,遷移至備份表存儲,而運行表數據不受影響, 即消除表 3 遷移前后數據量對比了對運行中流程的影響。由此帶來備份表數據也將不斷增大。備份表的存儲采用索引存儲方式,增加備份數據索引表( 如圖6 所示)。為做到對業務操作的完全透明, 如需對備份表的數據恢復,則根據索引定位流程數據, 縮小數據查詢范圍, 最終降低系統響應時間。備份表中數據也可轉移至其他存儲設備進行保存。對備份表中數據查詢需求, 提供單獨的查詢、統計及分析服務。