
作者:胡刀 阿裡雲運維專家/ 舟濟 阿裡雲解決方案架構師
實時曆史庫需求背景
在當今的數字化時代,随着業務的迅速發展,每天産生的資料量會是一個驚人的數量,資料庫存儲的成本将會越來越大,通常的做法是對曆史資料做歸檔,即将長期不使用的資料遷移至以檔案形式存儲的廉價儲存設備上,比如阿裡雲OSS或者阿裡雲資料庫DBS服務。
然而在部分核心業務的應用場景下,針對幾個月甚至幾年前的“舊”資料依舊存在實時的,低頻的查詢甚至更新需求,比如淘寶/天貓的曆史訂單查詢,企業級辦公軟體釘釘幾年前的聊天資訊查詢,菜鳥海量物流的曆史物流訂單詳情等。
如果這時從曆史備份中還原後查詢,那麼查詢時間将會是以天為機關,可接受度為0
如果将這些低頻但實時的查詢需求的曆史資料與近期活躍存儲在同一套分布式資料庫叢集下,那麼又會帶來以下兩大挑戰
- 存儲成本巨大,進而導緻成本遠大于收益,比如釘釘聊天資訊資料量在高度壓縮後接近50PB,很難想象這些資料不做壓縮會帶來多大的資金開銷
- 性能挑戰巨大,随着資料量越來越大,即使針對資料做了分布式存儲,單執行個體容量超過大概5T以後性能也會急劇下滑,進而影響到近期活躍資料的查詢性能,拖垮整個叢集
- 運維難度巨大,比如針對海量資料下發一個表資料結構變更操作,很難想象全部完成需要多長時間
實時曆史庫場景需求分析
通過上面的分析,不管是冷備份還是線上曆史資料混合存儲在同一張實體表上的方法都是不可取的,一般實時查詢曆史資料庫的場景,一般需要有以下幾個關鍵特性
- 成本可控,曆史資料的存儲成本無法接受和線上庫一樣線性增長
- 實時查詢,曆史資料的查詢RT要做到與線上活躍庫幾乎一緻
- 查詢頻次較低,一般來說,越“舊”的資料查詢頻率越低
- 統一查詢入口,不管是活躍資料還是曆史資料,查詢入口保持一緻
- 改造成本需要盡可能低,最好能做到不做任何應用代碼修改,可以認為曆史庫對程式開發人員來說是完全透明的
- 可能存在曆史資料更新需求
- 資料規模較大,一般在100TB以上
X-Engine引擎介紹
X-Engine簡介
X-Engine是阿裡雲資料庫産品事業部自研的聯機事務處理OLTP(On-Line Transaction Processing)資料庫存儲引擎。作為自研資料庫PolarDB 的存儲引擎之一,已經廣泛應用在阿裡集團内部諸多業務系統中,包括交易曆史庫、釘釘曆史庫等核心應用,大幅縮減了業務成本,同時也作為雙十一大促的關鍵資料庫技術,挺過了數百倍平時流量的沖擊。
與傳統的InnoDB引擎不同,X-Engine使用分層存儲架構(LSM-Tree)。分層存儲有兩個比較顯著的優點:
- 需要索引的熱點資料集更小,寫入性能更高。
- 底層持久化的資料頁是隻讀的,資料頁采用緊湊存儲格式,同時預設進行壓縮,存儲成本更低。
相比InnoDB引擎,依據資料特征,使用X-Engine存儲空間可降低至10%~50%,我們在著名的Link-Bench和阿裡巴巴内部交易業務兩個資料集上測試了X-Engine的存儲空間效率。在測試中,對比開壓縮的InnoDB引擎,X-Engine有着2倍空間優勢,而對比未開壓縮的InnoDB,X-Engine則有着3~5倍的優勢。
實時曆史庫方案,為何選擇X-Engine
1.通常我們預設MySQL是當今最流行的開源資料庫,大機率是線上核心資料庫叢集的首選。相比其他高壓縮的存儲引擎,引入X-Engine完全無需做任何SQL代碼改造,并且支援事務,接入成本最低,學習成本幾乎為0
2.寫入性能更強,X-Engine相比同為LSM-tree架構的Rocksdb,有超過10倍的性能提升。
3.在存儲層引入資料複用技術等,優化Compaction的性能,降低傳統LSM-tree架構中Compaction動作對系統資源的沖擊,保持系統性能平穩
4.引入多個層級Cache,同時結合Cach回填和預取機制,利用精細化通路機制和緩存技術,彌補傳統LSM-tree引擎的讀性能短闆,X-Engine的點查詢能力幾乎與Innodb持平
下圖是X-Engine與主流曆史資料存儲方案對比
實時曆史資料庫架構設計和實作
總體架構思路
基于上文對實時曆史庫和X-Engine的介紹,阿裡雲資料庫團隊推出以X-Engine引擎為曆史資料存儲核心,同時生态工具DTS作為線上/曆史資料流轉通道,DMS作為曆史資料無風險删除的完整“實時線上-曆史庫”方案,針對不同的業務場景和客戶需求,在具體實作上可能會有所不同,我們提供了多種實時曆史庫方案的具體實作。主體架構圖如下,核心思路為:
- 久經考驗的Innodb引擎作為OLTP線上庫核心引擎,主要處理高頻查詢/更新請求,滿足線上活躍資料高并發,高性能,強範圍查詢的業務需求
- 阿裡巴巴資料庫團隊自研的高壓測存儲引擎X-Engine作為曆史庫核心引擎,主要響應曆史資料入庫/查詢/更新請求,滿足曆史資料冷熱資料頻次不一,低存儲成本,高性能的業務需求(範圍查詢可能性能受限)
- 統一DB接入層,根據設定的業務時間屬性将請求分别轉發至不同的存儲引擎。針對特殊場景下的跨引擎通路,在應用層做聚合展示
- 線上-曆史資料通過阿裡雲提供的生态體系工具做曆史資料遷移和過期資料删除,確定鍊路更為穩定可靠
深度 | 實時曆史資料庫存儲成本驚人,怎麼破?
線上庫/曆史庫拆分方案
一般來說,需要使用到實時曆史庫的場景,資料量都足夠大到單台主控端存放不了。線上資料庫可能是根據業務水準或垂直拆分的多個RDS,也可能是一個規模較大的DRDS叢集。為了盡可能地保證線上庫的性能,推薦将線上庫/曆史庫完全拆分解耦
• 曆史庫叢集存儲全量資料
• 通過DTS鍊路打通線上庫和曆史庫,實時同步
• DTS鍊路過濾Delete操作
• 可直接使用新版DMS配置曆史資料定期删除
源端為DRDS叢集
a.資料同步鍊路走RDS
• 多條DTS鍊路打通底層RDS節點,同步性能強
• RDS數量較多可支援API批量建立和配置
• 鍊路穩定性更好
• 需要保證源端目标端庫表數量一緻,資料路由規則一緻
b.資料同步鍊路走DRDS
• 隻需要配置一條DTS鍊路,友善省錢
• 資料同步性能較差
• 源端DRDS擴容會影響到DTS同步鍊路
• 源端目标端的執行個體數量和資料路由規則可自由配置
源端為多個RDS
a.目标端為多個RDS
• 業務代碼無需任何改造
• 運作後期曆史庫節點磁盤容量存在風險
b.目标端為DRDS叢集
可能涉及到業務代碼輕量改造,目标端不走分庫分表鍵性能無法保證
可将多個線上庫業務合并至一套曆史庫叢集,架構更加簡潔
DTS鍊路也分為走RDS和DRDS兩種
資料同步鍊路走RDS
資料同步鍊路走DRDS
同執行個體混用存儲引擎方案
線上庫/曆史庫拆分方案相對較為複雜,RDS支援同一執行個體混用存儲引擎。針對總資料量不是特别大的場景,可以考慮同一執行個體下Innodb&X-Engine引擎混合使用
使用DMS-->資料工廠-->資料編排功能可以輕松地實作同一執行個體内的資料流動和過期資料删除,架構示意圖如下。
- 實作簡單靈活
- 混用存儲引擎,在資料庫核心參數優化上難以兼顧兩者性能
- 曆史資料compact階段可能對整個執行個體産生性能抖動
- 同一執行個體下的庫或者表無法重名,涉及到輕量業務改造
深度 | 實時曆史資料庫存儲成本驚人,怎麼破?
DTS賦能線上/曆史資料流轉
DTS不僅支援全量&增量同步,支援不同資料庫産品之間的資料同步,在線上/曆史庫解決方案中,DTS強大的"條件過濾"功能是非常重要的一環,通過配置DTS任務可以非常便捷地實作過濾Delete操作,動動滑鼠點兩下即可實作自定義的資料同步政策。
DMS賦能線上庫過期資料删除
線上庫的過期資料删除既要保障删除效率,也要保證删除過程中對線上庫不會造成性能上的抖動,新版DMS支援建立“曆史資料清理”的資料變更任務,通過該任務可以非常友善地完成以下工作
• 曆史資料定期删除,指定排程時間和一次排程時長
• 大事務拆分,減少事務執行過程中鎖表時間過長,避免主備延遲
• 清理遭遇異常中斷可重試
• 支援檢視任務運作狀态和失敗原因分析
• 配置方面簡潔
過期資料清理思路
如果沒有使用DMS生态工具,也自行實作過期資料删除,但實作較為複雜。一般較為通用的設計思路為将表的主鍵按照大小做拆分,保證一次删除"恰當數量"的資料,既保證删除效率又不影響線上服務
1 線上庫的曆史資料删除政策(假設主鍵為id,資料儲存180天,時間屬性列為date_col)
2 初始化數值Y=select min(id) from $table_name
3到了業務低峰期以後,DELETE FROM $table_name WHERE date_col< SUBDATE(CURDATE(),INTERVAL 180 DAY) and id >= Y and id <=
Y+100000 ,執行成功後代碼層重新指派 Y=Y+100000
4程式sleep 3s,重複步驟b
5時間到了業務高峰期以後,停止執行,記錄下目前的數值Y,第二天執行時直接從Y開始注意
6線上庫曆史資料清理注意點
• 代碼上注意不要出現高并發删除的情況,即步驟b還沒跑完,新的步驟b又進來了
• 程式sleep的具體秒數,要通過測試,取一個最合适的數值,主要看主備是否存在較大延遲,3隻是估值
• 100000也是一個估值,實際取值最好也通過測試,取一個效率最高,對業務影響最小的數值。因為drds的序列不是單點遞增1的,是以這裡的10w不代表10w條記錄。
• 假設删除程式中途崩潰了,或者執行很多天後發現部分資料沒有删除。那麼可以手工先删除一小部分殘留的資料,比如預估下id<100w的記錄還有多少條,不多的話直接執行DELETE FROM logs_trans WHERE reqdate < SUBDATE(CURDATE(),INTERVAL 30 DAY) and id<100w 然後初始化整個程式,這樣保證重新初始化以後不會做很多無用功,即反複執行删除條目很少的sql
極端場景分析
在臨界時間處理上,實時曆史庫方案可能遭遇極端場景導緻業務可能存在曆史庫的髒讀問題,假設線上庫資料儲存180天
• 更新179天前23時59分59秒的資料,請求路由至線上庫
• 資料同步鍊路異常中斷或鍊路存在延遲,該更新請求未能及時到達曆史庫
• 這時業務查詢該資料時,由于已經資料已經"舊"到超過180天,請求路由至曆史庫,由于鍊路異常,曆史庫查到了髒資料
解決方法
• 配置鍊路異常告警,及時發現及時處理
• 預計影響的資料範圍為DTS鍊路恢複前的臨界時間點附近資料,建議從業務邏輯上訂正資料
• 建議過期資料删除設定保守一點,比如臨界時間為180天,過期資料隻删除190天以後的資料,友善在極端場景下對比源端目标端的資料情況進行資料訂正
最佳實踐參考
1.
X-Engine如何支撐釘釘躍居AppStore第一2.
淘寶萬億級交易訂單背後的存儲引擎3.
将DRDS中的InnoDB引擎轉換為X-Engine引擎直播預告
6月23日15:00-16:00
我們一起見證 Redis 史上最大更新
點選文字預約觀看直播Redis 6.0版釋出會