陸金所去 Oracle 實踐有四大特點:
一是在線更換數(shù)據(jù)庫,不做服務降級。讓去 O 這類重大架構改造實施落地的時候對全站用戶影響最小,同時也最考驗去 O 的架構改造的技術實現(xiàn)能力。
二是對于高頻上線了上百次的去 O 變更,全程 0 故障、0 風險,這一點非??简炾懡鹚?O 的變更工具水平。
三是在短短 24 個月的時間完成全站 98% 的數(shù)據(jù)庫去 O 改造,并且涉及陸金所全部最核心的業(yè)務,去 O 的整體落地效率非???。
四是在去 O 各個環(huán)節(jié)實現(xiàn)了從開發(fā)、測試到運維各種自研智能工具來把控去 O 各個核心環(huán)節(jié)的質量,這也是把一個龐大、復雜、高風險的金融核心系統(tǒng),在非常短的時間內 0 風險、0 故障,穩(wěn)妥落地去 O 的關鍵。
陸金所為什么要全站去 Oracle?
陸金所為什么需要啟動去全站去 O,并且是 100% 全部去 O。
在去 O 項目立項之初,我們希望通過去 O 來實現(xiàn)三個方面的提升。
首先是降低昂貴的金融系統(tǒng)數(shù)據(jù)庫運營成本。2013 年至 2018 年期間,陸金所的業(yè)務成長了上百倍。業(yè)務量增長帶來的數(shù)據(jù)庫運營成本暴增。無論是傳統(tǒng)的 IOE 架構還是去 IE 后的 X86+Oracle 分布式架構都是如此。IOE 架構下,高端服務器和高端存儲的價格隨著提供的計算和 IO 能力呈現(xiàn)指數(shù)型增長。X86+Oracle 架構下,分布式改造和數(shù)據(jù)庫細粒度水平拆分后雖然沒有 I 和 E 的成本,但數(shù)據(jù)庫節(jié)點暴增后導致 Oracle 軟件授權費用暴增。
其次是希望通過去 O 來打造一個不依賴特定數(shù)據(jù)庫特性的金融交易系統(tǒng),徹底擺脫被商業(yè)數(shù)據(jù)庫廠商技術綁架的風險。傳統(tǒng)金融交易系統(tǒng)使用數(shù)據(jù)庫特性承擔了大量的業(yè)務邏輯和架構屬性,造成系統(tǒng)對某個數(shù)據(jù)庫特性的強依賴,也大大增加了被技術綁架的風險。陸金所通過全站去 O 實現(xiàn)了把金融交易系統(tǒng)里數(shù)據(jù)庫的角色轉化為只支持基本增、刪、改、查的存儲引擎,全站系統(tǒng)架構弱依賴數(shù)據(jù)庫特性。
最后一點也是最重要的一點,我們希望通過全站去 O 這樣一個涉及到開發(fā)、測試、架構、DBA 等全部研發(fā)團隊都參與的重大架構改造項目,來鍛煉研發(fā)隊伍、提升研發(fā)能力,并把歷史上一些架構設計不完善的地方,通過全站去 O 進行重構。因為去 O 不僅僅是更換數(shù)據(jù)庫,更重要的是落地架構拆分、微服務化、分布式事務等配套的大量架構改造工作。這些工作需要開發(fā)、架構、測試、運維高度協(xié)同配合,并穩(wěn)妥落地。所以去 O 是非??简炑邪l(fā)團隊技術水平的架構改造項目。通過,我們也希望通過去 O 打造“研發(fā)規(guī)范——研發(fā)工具——研發(fā)人員”的研發(fā)管理體系閉環(huán)。這一塊我們在后面會詳細展開,并向大家進行介紹。
技術選型:為什么是 MySQL,又不僅是 MySQL
決定去 Oracle 之后,選擇什么數(shù)據(jù)庫或存儲引擎來承載 Oracle 的流量?我們從功能、資源、案例和壓測四個方面來進行選型和評估。
首先,選擇的數(shù)據(jù)庫要從功能和性能上能夠承接 Oracle 在各種場景下計算和 IO 能力。其次,它還要具備最廣泛的社區(qū)資源、技術資料和問題處理案例,通俗的說就是大量坑被踩過,以及最廣泛的用戶基礎,外面招開發(fā)和運維工程師都比較好招。然后,還要在業(yè)界有可參考的金融場景案例。這一點相信大家都很熟悉,阿里和騰訊在金融場景上已經(jīng)有不少成功的案例。
最后,同時也是最重要的一個評估標準就是陸金所自身上線前嚴格的壓測環(huán)節(jié)。陸金所在切換任何一張表流量的時候,都會使用生產環(huán)境完全真實的數(shù)據(jù)搭建 O 和 M 并行壓測環(huán)境,來獲取訪問這張表的所有讀寫接口的在 Oracle11.2 和 MySQL5.7 下的性能比對報告。經(jīng)過每一輪非常嚴格的壓測后,發(fā)現(xiàn) MySQL5.7 的性能比我們預估中的更好。通過從邊緣系統(tǒng)往核心系統(tǒng)的逐步去 O 演進中,MySQL5.7 就成為陸金所去 O 最主要的替代存儲引擎。
我們都知道 Oracle 是個非常優(yōu)秀、且覆蓋場景非常全面,無論是 OLTP 還是 OLAP 場景表現(xiàn)都很優(yōu)秀,所以這種功能承接應該遠遠不止一種數(shù)據(jù)庫或存儲引擎,涉及到多種存儲引擎發(fā)揮他們的優(yōu)勢在各種特定場景下來替換 Oracle。
所以最終的結論是綜合選型下來確定 使用 MySQL 為主,TiDB、Redis、ES、HBase 等多種存儲引擎為輔的方式,100% 全部替換掉 Oracle。
陸金所去 Oracle 方案
接下來,我們就詳細介紹陸金所的去 Oracle 方案。
去 O 雙寫和切換方案
首先介紹一下應用層部分的落地。應用層在去 O 的時候會做一個整體規(guī)劃,把一個大的系統(tǒng)或庫拆分成多個可獨立落地的批次,然后會把應用的業(yè)務邏輯層從數(shù)據(jù)庫的訪問接口盡可能剝離出來,讓 DAL 層專注只做好數(shù)據(jù)庫交互的操作。同時,在 Oracle DAL 層的基礎上,對 MySQL DAL 層的進行重構,并且配置流量開關讓上層的業(yè)務邏輯層可以自由選擇和數(shù)據(jù)庫的交互是走 Oracle DAL 層還是 MySQL DAL 層。每個批次都會有自己單獨的流量開關進行控制。批次拆分的時候遵循一個原則就是把具備業(yè)務相關性和事務相關性的表放在一個批次里。
再說數(shù)據(jù)庫層的落地,在 Oracle 還在不斷對外提供服務的時候,我們會在后臺建立起一個和 Oracle 保持實時數(shù)據(jù)同步的 MySQL 數(shù)據(jù)庫,即當 Oracle 的事務提交后,秒級同步到后端的 MySQL 里面。同時這個同步是雙向的,當未來流量切換到 MySQL 后,也會在 MySQL 事務提交完成后,把數(shù)據(jù)秒級同步回 Oracle,這就類似 MySQL 的雙 master 架構,只不過數(shù)據(jù)是在 Oracle 和 MySQL 這個異構數(shù)據(jù)庫之間建立雙 master 架構。
在這個架構中為了確保數(shù)據(jù)庫的一致性和完整性,一定是嚴格要求某個批次的寫流量只能在某個時間點只能在 O 和 M 一個地方寫入。陸金所研發(fā)了一整套自動化構建數(shù)據(jù)庫雙寫的工具平臺,只要在平臺上選擇需要建立批次的 Oracle 表,就能在后臺全自動完成 Oracle to MySQL 從表結構轉化、數(shù)據(jù)全量同步、數(shù)據(jù)增量同步、數(shù)據(jù)實時同步、數(shù)據(jù)校驗和數(shù)據(jù)雙向同步建立整個全流程繁瑣。依據(jù)這套自動化平臺,陸金所只投入 2 個 DBA 就完成了全站上萬張表的去 O 數(shù)據(jù)庫遷移和運維層的全部準備工作。
最后是流量切換,我們設計并研發(fā)了一套總控開關機制來協(xié)調從應用、到數(shù)據(jù)庫、到傳輸、最后到流向的全盤流量切換。實現(xiàn)當流量在 O 時,實時同步到 M。當流量在 M 時,實時同步到 O。保證切換一瞬間,最后一筆事務在源庫提交成功,在目標庫傳輸成功,并完成最后一筆事務的數(shù)據(jù)在源庫和目標庫的數(shù)據(jù)校驗后,同一個批次下所有表的寫流量在同一個時間點同時完成切換。
應用流量在 O 和 M 之間快速切換
雖然去 O 流量切換會在 10 秒內瞬間完成,但整個過程按照細粒度劃分會有十多個步驟。為了方便介紹,我們把這十幾個步驟精簡成了三個狀態(tài)。
首先是初始狀態(tài),這個狀態(tài)下生產的只讀流量可以在 Oracle 或 MySQL,寫流量可以在 Oracle,由 Oracle 對外提供服務。這個狀態(tài)狀態(tài)可以理解為 Oracle 為主庫,MySQL 為 Oracle 的異構實時備庫。
其次是中間狀態(tài),這個狀態(tài)下 Oracle 和 MySQL 會進入一個非常短暫的寫保護靜止狀態(tài)。在完成最后一筆 Oracle 事務提供成功,并同步至 MySQL,且完成最后一筆數(shù)據(jù)一致性校驗后,會把應用開關的流量切換到 MySQL,這個時候這個批次的寫流量在某個時間點全部一致性都切換到 MySQL。
一旦在 MySQL 里寫流量進來,就進入了第三個狀態(tài)即完成狀態(tài),一旦寫流量的事務在 MySQL 中提交成功,雙向實時同步鏈路會把 MySQL 的數(shù)據(jù)秒級同步回 Oracle,這個時候可以理解為 MySQL 是主庫,Oracle 是 MySQL 的實時備庫。
需要注意的是,這個架構下需要解決大量的細節(jié)問題,比如避免同一筆記錄雙向循環(huán)寫的問題。
陸金所實現(xiàn)的這個雙寫框架流量切換速度極快,在數(shù)秒內就能實現(xiàn)有狀態(tài)的寫流量從 O 到 M 的快速切換,整個過程在低峰期落地對業(yè)務影響非常小,甚至是不感知。如果在去 O 之前在 Oracle 內部已經(jīng)完成了對用戶的水平拆分,以批次和用戶雙重細粒度進行去 O 流量切換,那么整個更換數(shù)據(jù)庫過程幾乎是無感的。
在流量從 O 切換到 M 后,以陸金所落地的經(jīng)驗來看,大概有一定概率(比如程序的 bug)需要回切到回 Oracle。這套切換框架可以確保在幾秒內流量快速回到 Oracle,且在 MySQL 寫入的少量數(shù)據(jù)也會同步會 Oracle,且在保證 Oracle 和 MySQL 兩邊的數(shù)據(jù)嚴格一致性和完整性的過程中,進行流量的快速前滾和回滾。
適用于金融核心系統(tǒng)的穩(wěn)妥去 O 推進方案
了解了去 O 流量切換的架構和方案,接下來我們介紹如何在一個關聯(lián)系統(tǒng)龐大、業(yè)務邏輯復雜、改造風險極高的金融核心系統(tǒng)里落地整個去 O 方案。
首先我們會以表為粒度來把一個復雜、龐大的金融核心系統(tǒng)和數(shù)據(jù)庫拆分成多個批次,拆分的原則上面也提到了一點,即把有業(yè)務相關性和事務相關性的表放在同一個批次里,在確保這個基本原則的情況下,把單個大庫盡可能的拆分成多個批次,確保每個批次里的表盡可能的少。
為什么要基于這個原則來落地實施呢,因為批次是去 O 變更的單位,O 和 M 之間的流量切換開關是控制到批次的。把批次拆分的足夠細,最終目標是為了實現(xiàn)“改造難度可控、上線進度可控、切換風險可控”的 3 原則。
首先對于金融核心系統(tǒng)中一個復雜的模塊來說,去 O 改造的周期會橫跨半年甚至一年以上,在這個過程中,金融核心系統(tǒng)在 7*24 小時不間斷對外提供服務,應用層的代碼和功能每個月甚至是每周也處在高速迭代中,不斷的新功能被加入到系統(tǒng)并被發(fā)布到生產。
而在這個過程中,要落地去 O 這類龐大的架構改造,必須框定一個可快速迭代和實施的改造范圍,批次就是一個合理設定的單次去 O 改造和變更的范圍。批次拆分的粒度細,可以確保在單個批次的去 O 改造工作量可控、改造難度也可控。
同時因為批次的粒度細,在做去 O 變更切換流量時,對整個金融核心系統(tǒng)的影響也可控?;谶@種思路,就可以實現(xiàn)“小步快跑”的高速迭代方式來改造應用、上線版本以及切換流量。即每次只改動核心系統(tǒng)的一小部分,改動完成后快速測試、快速發(fā)版上線、并且風險可控的把這部分流量切換到 MySQL 運行,如果有問題依靠強大的流量切換框架,快速把流量回切回 Oracle。
從圖中大家可以看到一個龐大的金融核心系統(tǒng)去 O 改造中,應用改造、上線版本和流量切換這 3 件事情實在并行落地的。
最開始是應用改造,改造完了上線發(fā)版,發(fā)版后就有了這個批次 O 和 M 的流量開關,并具備了切換條件,之后在某個變更日把流量從 O 切換到 M,如果遇到任何問題可以快速切回來。應用版本在不斷上線迭代,流量在分批次不斷切換,一個龐大的金融核心系統(tǒng)就在多次高速迭代中一點點的從 O 切換到了 M。
整個過程對核心業(yè)務不影響、不感知,且對參與去 O 的開發(fā)、測試和運維開展去 O 工作非常友好,讓他們可控的去落地各項工作。
在這個過程中,從第 1 張表從 Oracle 切換到 MySQL,到最后一張表關閉 Oracle 流量,在非常長的一段時間內,整個應用是由 Oracle 和 MySQL 在同時提供服務。其中某些表已經(jīng)完成去 O,讀寫的流量在 MySQL 上,由 MySQL 同步到 Oracle,部分表還未完成去 O,讀寫流量在 Oracle 上,由 Oracle 同步至 MySQL。這就非常考驗運維的能力,要確保在這個架構下每天高頻的各種發(fā)版和數(shù)據(jù)庫變更都非常準確。
基于此,陸金所是有研發(fā)一整套配套去 O 變更工具,來確保整個去 O 過程中大量變更準確實施和落地。以陸金所交易、主賬戶、資產中心、基金、賬務等核心庫為例,從第一張表流量切換到 MySQL 到最后一張表切換到 MySQL,歷時 12 個月以上。按照上述方案一點一點的替換掉 Oracle 數(shù)據(jù)庫,整個過程完全不做服務降級,對陸金所的 4500 多萬用戶無感知。
陸金所去 Oracle 方案的落地
在 PPT 中畫出去 Oracle 的架構圖是很簡單的事情,但是架構改造的難點和重點在于落地。要在生產環(huán)境落地是非常龐大且復雜的系統(tǒng)工程,尤其是對一個 7*24 小時的金融核心系統(tǒng)來說,進行重大架構改造本身就是一件高風險的工作,既要做到規(guī)避風險,確保各種工程實現(xiàn)細節(jié)有效落地,同時又要保證系統(tǒng)的業(yè)務連續(xù)性,甚至是對外部用戶不感知。
去 Oracle 架構改造的本質是什么?我覺得有兩方面,一是細節(jié)規(guī)則,二是上生產前發(fā)現(xiàn)和上生產后兜底。
去 O 的重點不僅僅是方案本身,更重要的是組成方案的數(shù)百條細節(jié)規(guī)則,能在一個參與去 O 的、龐大的研發(fā)團隊里每個開發(fā)所寫的每一行代碼都有效遵守規(guī)則,同時在每個運維設計的生產變更方案里每一條命令都有效遵守規(guī)則。方案通過從邊緣系統(tǒng)往核心系統(tǒng)逐步推進過程中,會逐步趨于完善,方案中的規(guī)則也會被逐步積累和完善起來,那么把這些規(guī)則落地到研發(fā)團隊的每個人上,是關鍵和重點。
上生產前發(fā)現(xiàn)是指如果規(guī)則在某個微小的細節(jié)實施時沒有被遵守,如何盡可能的在上生產環(huán)境之間發(fā)現(xiàn)隱患。上生產后兜底如果問題突破了所有檢測環(huán)節(jié)上了生產,如何設計一個兜底方案可以有效控制風險,把影響盡可能降低。
去 Oracle 落地工作都應該圍繞有效解決這兩個本質問題展開,并提升這兩個問題的解決效率,降低人力成本。
陸金所的做法是建立“人員——規(guī)則——工具”的閉環(huán)。
陸金所通過“人員制定規(guī)則——規(guī)則通過工具落地——工具確保所有人員的代碼和變更符合規(guī)則”的方式來確保各種細節(jié)工作落實到位,整套工具最終沉淀為陸金所數(shù)據(jù)庫升級平臺。
以陸金所的去 O 落地經(jīng)驗來看,一個不起眼的細節(jié)問題如果未進行有效管控,都有可能引發(fā)嚴重的生產故障。所以我們可以把陸金所數(shù)據(jù)庫升級平臺理解成為一套強大的去 O 風控系統(tǒng)。這套風控系統(tǒng)覆蓋 SQL 重構、表結構轉化、數(shù)據(jù)遷移、數(shù)據(jù)校驗、分布式事務構建、流量切換等橫跨從開發(fā)到運維在去 O 架構改造方方面面會遇到的問題。通過這套工具平臺,有效確保參與去 O 的研發(fā)團隊在每個細節(jié)上都處理的非常規(guī)范,從而實現(xiàn)歷時 24 個月的全站去 O,無風險平穩(wěn)落地。
除了確保各種規(guī)則精準落地外,金融核心系統(tǒng)去 O 改造需要多個研發(fā)團隊協(xié)同作戰(zhàn)、有效配合、共同推進。其中涉及到大量工程實現(xiàn)細節(jié)工作需要多團隊有條不紊、事無巨細的協(xié)同配合好。任何疏漏都有可能會引發(fā)嚴重的生產故障。
經(jīng)驗總結:談談企業(yè)去 Oracle 的目標
去 Oracle 的口號喊了很久了,但是為什么要去 Oracle,去 Oracle 想要達到什么樣的目標…有些企業(yè)可能沒有想得很清楚,所以我也想從自己的角度和經(jīng)歷來談談去 Oracle 的目標。
目標一:省錢
去 O 完成后,使用“免費的開源數(shù)據(jù)庫 + X86 架構的 PC Server”來搭建金融核心系統(tǒng),真的很省錢。因為搭建金融核心系統(tǒng)從昂貴的高端服務器、高端存儲和 Oracle 一體機,以及昂貴的 Oracle 軟件授權變成只需要 6 萬一臺的 X86 服務器,花在數(shù)據(jù)庫上的運營成本降為之前的 10% 不到。
在整個去 Oracle 的過程中,陸金所架構從一個傳統(tǒng)金融的超大型數(shù)據(jù)庫支持各種核心業(yè)務的架構變成了以微服務化驅動的分布式架構,這種架構具備以下特點:
通過微服務化拆分,幾套集中式的 IOE 大庫就變成了微服務小庫,同時對于訪問量和數(shù)據(jù)量較大的中臺服務,又會進一步細粒度水平拆分。
目標二:架構升級和改造
除了降低成本,我認為更重要的是通過去 O 實現(xiàn)傳統(tǒng)金融系統(tǒng)全方位的架構升級和改造。
對于一個傳統(tǒng)金融系統(tǒng)來說,借助去 O 來實施和落地全系統(tǒng)的架構改造和升級,應該是一個再好不過的機會。以陸金所為例,通過去 O 實現(xiàn)了以下的升級和改造:
目標三:引入更合適的存儲引擎
提到去 Oracle,可能很多人在第一時間就想到了 MySQL。其實,MySQL 是承接 Oracle 主要流量的數(shù)據(jù)庫,但 MySQL 無法承接 Oracle 的全部流量,例如以下幾類經(jīng)典場景:
在這些場景中,可以引入 TiDB、Elasticsearch、Impala+kudu、Redis 等多種存儲引擎。這些存儲引擎在合適的場景下替換 Oracle,產生的效果是不但比 IOE 架構成本低得多,性能也會比 Oracle 快得多。
我們以 TiDB 為例來講講使用 MySQL 之外的存儲引擎是如何支撐 Oracle 流量的。
陸金所有個實時對賬的場景,需要跨用戶庫、交易庫、資金庫和資產庫進行復雜的關聯(lián)查詢。在完成去 O 后,數(shù)據(jù)庫在 MySQL 上做了細粒度拆分,無法跨多個獨立的服務庫進行復雜且高頻的跨庫查詢。
為了支持這個場景,我們研發(fā)了數(shù)據(jù)總線來實施解析 MySQL binlog 并生成消息同步至 TiDB,事務在 MySQL 提交后實現(xiàn)秒級同步至 TiDB。之后通過 TiDB4.0 的 TiFlash 功能(類似 clickhouse 的列式存儲),在 MySQL 和 Hadoop 之間搭建一個實時 ODS,實現(xiàn)了秒級處理跨庫、多表、復雜關聯(lián)的查詢場景。性能遠超去 O 之前在 IOE 架構下的處理結果。
來源:網(wǎng)絡