數據庫

中國銀聯跨中心,異構數據同步技術與實踐

作者:翁海星  編輯:張曉藝

摘要:Moray 是中國銀聯為支持應用的異地多活、異構數據庫的數據同步而設計的組件。本次將分享中國銀聯實現跨數據中心、高性能、可異構化的實時數據同步技術,以及 Moray 在中國銀聯異地多活系統中的實踐經驗。

翁海星,中國銀聯異構&異地數據同步項目 Moray 負責人,從事數據庫內核研發工作,主要關注存儲引擎、數據復制。

本文根據翁海星老師在DTCC數據庫大會分享內容整理而成,將介紹中國銀聯實現跨數據中心、高性能、可異構化的實時數據同步技術,以及 Moray 在中國銀聯異地多活系統中的實踐經驗。 1 需求背景

1.1 數據同步 

數據同步(也可以說數據復制或者數據傳輸)在一些特定的場景中是非常重要的,比如說業務系統的災備部署:為了應對某個業務中心不可服務的情況,數據需要及時同步到另一個中心以完成業務切換;在實際的應用場景中,兩個城市的業務中心可能會各自承擔部分流量,雙活的架構對數據實時同步的要求就比較高。

從2012年開始,中國銀聯在技術上確定了比較重要的方向:去IOE和多活建設。在這之前中國銀聯的傳統業務數據都部署在DB2上,由2012年起,逐漸遷移到開源數據庫或者國產數據庫之上,如圖【1】中的UPSQL就是中國銀聯在MySQL上的定制數據庫版本(相信大家都可以通過“UP”聯想到)。

同時,目前銀聯在上海、北京各有一個信息中心,銀聯也正有計劃地將業務系統進行多活改造。傳統的金融企業去做國產數據庫或者是自研開源數據庫的原因無非三點:

第一個是前段時間去IOE的“風氣”,這里面包含政策激勵和技術導向,金融行業或多或少地會去開始接觸這類工作,同樣也是得益于去IOE之風,我們的國產數據庫和開源數據庫才能蓬勃發展;

第二個是商業數據庫維護的成本問題;

第三個是商業數據庫有時的確無法負載實際的業務發展規模,以銀聯云閃付為例,在有優惠或者是折扣之類的活動時,系統處理業務時會存在熱點賬戶,在做大促活動的實踐中,銀聯已經發現DB2的熱點更新是存在問題的,可以察覺到明顯的時延(熱點賬戶更新問題也是我們今年的一個主要的工作)。

在以上的背景下,我們發現這些工作從開發到運維,每一步都充滿了挑戰,這里主要分享一下銀聯在數據同步上做的工作。

假設我們有兩個業務,放在兩個機房或者兩個中心,在做業務災備或者多活的時候需要搭建數據同步,最簡單的一個方案肯定是MySQL的原生復制。復制的原理,簡單來說,就是主庫在事務提交的時候會寫binlog,從庫獲取主庫上的binlog并寫到自己的中繼日志(relaylog)中,再回放relaylog中的事務。

MySQL的復制其實是做得比較完善的,它除了提供單向的主從復制之外,還可以雙向地做主主復制,使得在做業務雙活的時候,兩邊都可以得到數據的同步。

MySQL在5.7之后還提供了半同步復制,相對于異步復制,能保證主庫在提交事務之前確認從庫收到日志并落盤,可以很大程度上確保數據一致。銀聯在做一些系統雙活的時候,在實際業務場景中,會發現它的原生復制其實有很大限制。

下面看一個比較復雜的場景,這里會有一個新朋友叫proxy。實際業務場景里銀聯的數據體量是非常大的。拿銀聯無卡系統來舉例,每天生成的交易量均過千萬,單一的MySQL是無法支撐這樣規模的數據量的。

為了實現部署數據庫集群,銀聯自主研發了中間件UPSQL-Proxy,實現了自動的分庫分表、SQL路由、自動擴縮容以及數據庫高可用,時至今日,這個技術路線已經發展成了分布式數據庫叫UPDRDB。銀聯的DRDB通過自主研發的MySQL 存儲引擎插件,協調整個數據庫集群,給用戶提供像單機MySQL一樣的體驗。

現在來看一下整個業務中心的場景。上海中心的每個數據分片都分一個主從,然后主從去做半同步復制來確保它的高可用。

但此時就會出現這樣一個問題,兩個中心之間的復制該怎樣同步?最直觀的就是從數據庫拉一條復制鏈路,這個其實是有問題的。因為這樣做對于MySQL來說,其實就是一個多源復制鏈路,即其中某個分片的relaylog是從多個數據源獲取。

MySQL的多源復制是不支持半同步復制的,這樣它就不能保證高可用。另外,上海中心和北京中心的資源本身是不一樣的。可能北京中心拿不出那么多的物理資源,比如說上線一個系統,上海中心出50個CG,北京中心就只能出25。如果在這上面去搭建復制方向就不太好去維護。這個是銀聯遇到的第一個問題。

再來的問題是異構數據之間的同步:

一、在做業務系統的時候不僅用到數據庫,而且還用到緩存。在做活動的時候,經常會把一些促銷信息或者用戶積分放到緩存里面,應用再從緩存里去讀寫。當然這些數據不會一直放在緩存里面,還需要落地到數據庫;

二、從DB2遷移系統的時候,肯定會有兩個地方用到異構數據的同步,DB2存量的數據遷移,以及上線之后的并行測試,兩個數據庫都需要承擔部分流量。

更復雜的情況是也是需求帶來的。做過業務的人應該會比較清楚,大部分業務系統的聯機庫都會往匯總庫同步數據。

很多銀行的做法就是T+1去跑批,然后把它放到匯總庫中,此時會有更“豐富”的要求,如:聯機的業務日志或者是流水只需要往匯總庫去寫,交易中的狀態只需要記錄成功或者失敗,還有把交易中的記錄按照日期來做分表,甚至把某些字段給過濾掉或改掉,也就是數據的形變和過濾,這些都要求即時完成。

銀聯在做這個事情之前,也調查過很多其他的工具或者是開源組件,但是一直沒有找到合適的,所以去年開始決定自己來研發數據同步組件,實現前面說的那些復雜的需求。這個組件就是我們自己研發的Moray。

簡單來說,Moray就是一個數據的同步組件,它是為數據庫提供點對點和準實時的數據同步的服務,這里面的數據庫不僅僅是指UPSQL,也有DRDB、Proxy和Redis,還有一些其它的異構數據庫。它的原理有些類似ETL,就是獲取數據去進行傳輸和加工,再進行回放的過程。

在設計Moray的時候,主要考慮到三個要點:

對應用透明,應用不需要去感知Moray的,它只需要在上層把自己的業務做好,實際數據同步不需要它去關心。

應用無需額外開發,比如之前提及的既要寫Redis又要寫緩存,這個是不需要去關心的。

盡量降低對主庫性能的影響。我們在設計的時候盡量去解析數據庫日志,比如UPSQL就去解析binlog,針對Redis我們去解析EOF日志,去盡量降低對主庫性能影響。2   架構設計

2.1 前后端分離

上圖是在Moray的組件設計框架。考慮到之后業務的發展可能會有更多的、更新的數據端給加進來,所以說在考慮設計Moray的時候,是把它一分為二來看的。

Moray分為前端模塊和后端插件兩部分,這個設計很簡潔,前端就是一個生產者,它從數據源抽取數據,通過設計的內部通用協議,把數據流傳給后端的插件處理。

后端是使用熱插拔插件的方式來實現的,Moray提供標準的四個接口。在做新的數據流同步的時候,可以很輕松地寫一個新的插件,主要實現四個接口:插件初始化函數,插件銷毀函數,將數據包寫入目的端數據庫的處理函數,以及處理完成的回調接口,實現完這四個函數之后,就可以把插件加入到Moray進程,實現異構數據庫的同步。

整個Moray架構是比較靈活和多變的,可以很好的支持不同數據源和目標數據庫的組合。

目前前端模塊可以處理的數據源為DB2、UPSQL(Proxy)、Redis以及遠程模塊,UPSQL前端處理Binlog,Redis前端解析AOF日志,DB2前端由于日志的協議未開放,因此是通過時間片掃描的方法獲取增量數據,遠程模塊是較特殊的前端,用于接收異地Moray發送的數據。

后面的插件可以將同步的數據寫入DB2、Redis、ES及其他大數據平臺,Remote插件與遠程前端模塊配合,將數據流發給異地的moray組件。

2.2 設計要點

以下是銀聯在設計上考慮得比較多的地方。

事務性

第一個我們比較看重的一點,Moray在數據同步的時候,解析階段和回放階段都要保證數據回放的事務性。數據在主庫中的事務如何提交,在回放的時候,這些數據肯定也要到一個事務里面去。因為我們不希望另一個業務中心讀到臟的數據,這個是通過設計內部的協議格式來做的。

高安全

還有在做跨中心數據同步的時候,要保證數據是安全、不丟失的。Moray在設計上具有斷點續傳功能。如果Moray出故障down掉了或者因為其它需求需要遷移環境,只需要重新拉一個進程,就可以從上一次同步的進度開始繼續進行;異地中心報文還做了校驗,防止數據篡改。

高性能

Moray在數據同步時盡量保證數據庫不受影響,盡可能地不直接讀源表,不去和應用競爭數據庫的資源(解析binlog或者AOFlog);在做數據同步的時候,對數據做壓縮傳輸;使用多線程并行回放,尤其對于UPSQL,參考了MySQL8.0的回放的算法。

高可用

Moray作為輕量級組件,采用的是端到端同步的方法。各個業務之間的Moray進程是獨立運行的,降低了它和源庫的耦合度,也可以靈活部署,并通過銀聯的數據組件調度平臺(DBASS)實現高可用。

高可管理

這里指與Moray搭配的一個監控平臺。在平臺上可以很方便的建立起Moray的數據同步流向。并通過監控平臺我們可以看到Moray的同步狀態、健康狀況以及數據時延。

容錯

我們還考慮到一些容錯的場景,比如說在數據回放的時候,可能會遇到insert數據已經存在,或者update的記錄不存在的一些場景,Moray支持對此類問題的自動容錯。另外在做數據追補的時候(時間點回撥),Moray可以過濾掉已經執行過的事務,這個是通過數據庫的GTID的機制來做的。

插件化

插件化,Moray的模塊和插件都是易于擴展的,未來可以實現更多數據庫的異構同步。

異步化

要保證高性能的比較重要的一點是要異步化。前端模塊傳輸數據給后端、后端寫入數據到目的庫,都是通過異步方式實現的。

2.3 UPSQL實時同步

對Moray來說,同步UPSQL數據就是通過binlog dump的協議,把自己偽裝成一個從庫,獲取日志來進行解析處理。Moray設計的內部協議格式保證了數據庫回放的數據的事務特性,同時為了配合UPDRDB,也支持XA協議以完成分布式事務的同步。

接下來看看高可用問題,在數據同步的時候一般考慮到高可用主要有兩點:Moray本身的高可用和數據庫里主從的高可用切換。現在的策略是每組一個數據分片(一組主備庫)去共享一條同步鏈路。

這樣,Moray與UPSQL-Proxy(或者DRDB)交互,依靠UPSQL-Proxy保證主從庫可以在異常時如預期切換,主庫上未同步的數據日志在從庫上也能獲取,不會有數據丟失的問題。

那么Moray自身的高可用是怎么去做到的呢?分為兩種情況,如果沒有任何其它底座的話,Moray自身只能做冷備,當Moray進程宕機或者是無法恢復的時候,需要去手動切換到冷備進程。

這并不難,因為Moray的啟動配置本身并不復雜,配置以及同步進度信息支持寫入數據庫或者Zookpeer,完全可以實現探測腳本獲取啟動信息,重新拉起進程;銀聯在使用Moray的時候,會將其和自研的數據庫平臺(DBAASE)集成,如果Moray宕機DBAASE可以及時感知,由它來重新建立同步鏈路。

再來看擴容問題,UPDRDB支持數據庫的在線擴容,與之對應的,Moray的擴容策略目前是由源端的數據分片來決定的,因為獲取binlog只能從每一組數據庫里面去獲取。這樣的話意味著源端有多少個數據庫分片的組,就有多少個Moray的同步線路。

DDL變更其實對很多數據同步工具來說是一個比較頭疼的問題。之前的版本暫時不支持DDL語句同步,在某些情況下,雙活數據同步時,需要暫停Moray進程。最新的Moray版本中,DDL語句同步時,將會把每一個數據表的版本都保存起來。在內部協議格式增加版本號,根據版本號來決策當前使用哪一個版本的數據表結構。

為了滿足多變的業務場景,Moray支持使用lua腳本配置數據形變。Moray是用C語言寫的,C語言能夠很方便的去調用lua腳本。如果需要做比較靈活的形變,那只需要提供一個lua函數。Lua本身是很靈活的語言,用戶可以去對數據做任意的形變。

Moray-Upsql在實現各類同步需求時,性能也足以支持銀聯所有的業務壓力,以內部通用的轉接測試為例,目前DRDB集群性能在二十萬TPS以上,使用Moray完全沒有問題。

2.4 UPRedis實時同步

再簡單說一下Moray-Redis。與UPSQL有所區別的地方在于前端模塊解析EOF日志,后端使用了PIPELINE設計去寫目的端的緩存,當然異地傳輸時需要對報文進行壓縮。實際的傳輸性能在10萬QPS左右。

在做高可用設計時,Moray使用了Redis官方推薦的HA的sentinel組件。正常情況下,Moray連接Redis從庫同步數據。遇到故障時,如果是一主一從,只能從主庫(或切換后的主庫)再去同步數據。因為redis是單線程的工作機制,直接去從主庫上同步肯定會影響一些性能。如果是一主多從的話,Moray則從其他的從庫繼續同步數據,Moray通過sentinel信息來得知主從切換的信息。

 3  案例實踐

再簡單介紹一下銀聯的一些實踐和Moray研發的近況。Moray是在去年2月份開始投入研發,三個月做了一個版本并release,之后一直在不斷做測試和驗證。

在9月份時第一次業務上線,用于TSP(支付Token標記)的聯機和管理遷移。現在已上線的系統包括TSP、無卡前置的管理系統、云閃付的統一賬戶平臺、管理全國商戶的平臺系統以及二維碼支付平臺。陸續會有更多的系統投入使用。

4    未來規劃

在未來Moray需要做的事情可能分以下幾個方向。

一是更多的模塊和插件。通過解析Oracle日志(Logminer性能有限)實現Oracle的數據同步,以及支持寫入Kafka或更多的數據平臺。

二是Moray集群化,進一步簡化部署配置和集中管理,銀聯也正朝著金融云平臺的方向探索未來,所以也需要有一個類似DTS的數據傳輸平臺。Moray也會對此作出適配。

期待銀聯能為數據庫做一些更多技術方面的輸出,也希望大家一起努力,把開源或自主的數據庫的技術做得更好,共同向前。

我還沒有學會寫個人說明!

MySQL Batched Key Access (BKA)原理和設置使用方法舉例

上一篇

MySQL 百萬級數據量分頁查詢方法及其優化

下一篇

你也可能喜歡

中國銀聯跨中心,異構數據同步技術與實踐

長按儲存圖像,分享給朋友

ITPUB 每周精要將以郵件的形式發放至您的郵箱


微信掃一掃

微信掃一掃
重庆百变王牌开奖结果