技術分析!中國銀聯分布式資料庫實踐

導語: 本文根據周家晶老師在2018年5月12日【第九屆中國數據庫技術大會(DTCC)】現場演講內容整理而成。

技術分析!中國銀聯分佈式數據庫實踐

周家晶

中國銀聯股份有限公司 高級工程師

中國銀聯分佈式中間件UPSQL Proxy負責人,從事開源數據庫MySQL的研發工作,主要關注分佈式事務、SQL優化等。

摘要: 介紹銀聯為滿足自主安全可控這一目標,通過較長時間的積累,所形成的MySQL產品體系與架構。具體介紹分佈式數據庫中間件的分佈式事務實現機制、SQL優化和分佈式存儲引擎實踐。

正文:

分佈式數據庫

分佈式數據庫簡單來說就是海量數據和高性能要素可以水平擴展的數據庫。中國銀聯在2014年開始投入MySQL開源數據庫,主要為了自主可控以及去IOE。

產品的建設分為UPSQL和UPSQL Proxy。

回顧整個研發歷程,可以分為三個階段,初期、中期和當前。初期主要關注高可用、讀寫分離和分庫分表;中期階段開始考慮一些更加複雜議題,比如說分佈式事務如何支持和實現、數據庫連接池以及SQL解析執行優化;當前是一些新的議題,比如複雜查詢。

初始架構

技術分析!中國銀聯分佈式數據庫實踐

銀聯的初始架構,從下往上看,最下層是UPSQL data node數據節點,主要負責數據庫層的高可用,是一個邏輯節點。中間層叫做UPSQL Proxy,在生產實踐中我們一般錄入兩個或兩個以上UPSQL Proxy。

最上面一層是客戶端,應用上要求負載均衡連接兩個UPSQL或Proxy,同時我們有一個adm-server的組件,這個組件跟UPSQL和Proxy協同完成數據庫檢測和高可用決策、切戶以及Proxy隔離,實現了從數據節點到UPSQL Proxy節點的高可用切換。

技術分析!中國銀聯分佈式數據庫實踐

在整個研發工程中,我們一直在思考一個問題:Spanner方案和Proxy方案現在是業界的兩種方案,那麼Spanner方案和Proxy方案在功能上有哪些區別,是否Spanner就是最終解決方案?

分佈式數據庫

技術分析!中國銀聯分佈式數據庫實踐

無論是Spanner方案還是Proxy方案,在分佈式事務實現上只有一條途徑,那就是2PC。銀聯的實現方案主要有兩點:一是用後端的數據庫儲存XA日誌,避免對其他分佈式組件依賴,另一點則是使用最後參與者策略去優化性能。

方案對比

技術分析!中國銀聯分佈式數據庫實踐

左側是一個通用方案,右側是我們的方案。

左側方案,在一個全局事務裡,寫入兩個數據分片節點,在commit 階段兩個本地事務都會做XA,然後選擇一個節點進行分佈式日誌記錄,完成之後,整個事務分佈式就可以保證提交了,最後再進行xa commit。

2PC方案最大的問題就是參與者和協調者處理網絡異常數據比較困難,通過分佈式日誌就可以保證對異常的處理。

我們方案的區別是,選擇某一個本地事務,比如選擇數據分片1作為最後參與者,最終參與者不需要使用XA事務,過程中不需要做xa commit,並由最後參與者進行分佈式日誌記錄。

l 主要優勢

a) 不需要使用單獨會話進行xa日誌記錄(友商方案中向xa日誌表的寫入是自動提交的另一個會話)

b) 減少一個兩階段事務

l 主要缺點

a) 涉及分佈式事務的後端用戶,都需要配置xa日誌表權限,因而存在運維風險。

所以左側方案更適合雲上公共產品的使用,右側方案依賴嚴格的運維管理性策略。

分佈式死鎖

技術分析!中國銀聯分佈式數據庫實踐

但是我們發現一個分佈式死鎖的問題。比如說,全局事務的a&b開啟分佈式事務,那麼在time 1: a write db1.resource1 、time 2: b write db2.resource2緊接著time 3: a write db2.resource2、 time 4: b write db1.resource1,交叉反向的操作導致db1和db2上都出現了ab的所有等待,從全局的角度上看,就出現了死鎖的問題,那麼怎麼去解決這個問題呢?

死鎖檢測

技術分析!中國銀聯分佈式數據庫實踐

一個方案就是衝突圖的檢測。我們需要修改innodb-trx表,增加XAID信息,將XAID作為全局事務的一個標誌,以XAID的角度去看這個鎖的關聯關係。這樣只要我們拿到所有參與這張表的信息,就可以實現對死鎖衝突的檢測。

死鎖預防

技術分析!中國銀聯分佈式數據庫實踐

分佈式死鎖的預防策略是時間戳策略(Timestamp ordering, TO),保證單一時序的鎖等待,來避免死鎖的發生。

具體做法是,在XAID的生成規則裡進行邏輯時間拼接,事務開始時間+ TM(proxy)事務序號+ TM編號+ datanode + ...就可以保證業務上的需求。然後在DeadlockChecker::search() 中獲取xaid,根據死鎖預防策略進行處理,進行一個簡單的時序保證。

進一步優化

技術分析!中國銀聯分佈式數據庫實踐

雖然我們使用了最後參與者,但是最後參與者在整個事務提交過程中事務管理上是有相互的。我們正常的事務是begin、commit就結束了,要想盡可能的讓操作一樣多,就需要把xa end拿掉。

拿掉的做法也很簡單,以前在進入xa commit之前,會要求所處的事務狀態必須先是xa end然後才能跳轉到提交執行,現在把這個約束給修改掉,這樣就會減少一個網絡交互。

架構演變

技術分析!中國銀聯分佈式數據庫實踐

從初期的上線結構推進到中期階段,整個邏輯上沒有太大的變化,但是UPSQL Proxy和UPSQL之間的內在聯繫變的更為緊密。

SQL解析優化

技術分析!中國銀聯分佈式數據庫實踐

為什麼要做SQL解析優化?

關於Proxy,首先要做SQL解析,然後是路由計算、分佈式執行計劃計算、網絡IO。這樣,很明顯可以發現Proxy主要資源開銷和性能優化點為: SQL解析和網絡IO。

為避免硬解析,業界提供了兩種方法:一種是Prepare,做一次語句解析後,使用語句編號與變量值進行交互。我們在最開始做的時候,Proxy已經支持了Prepare,Prepare協議的優點是不需要對它做SQL解析。

另外一種方法是軟解析,即如果是相互的語句,就可以複用之前的語法樹,這樣的話都能夠避免SQL解析重複提高性能。

相似性優化

技術分析!中國銀聯分佈式數據庫實踐

Prepare避開了語句輸入這一層,軟解析避開了詞法解析這一層,那麼我們就考慮能不能只做詞法解析不做語法解析。於是我們提出了相似性優化,即輸進去的語句通過詞法解析之後,如果發現語法樹相似就直接複用之前的語法樹。

相似性分析

技術分析!中國銀聯分佈式數據庫實踐

詞法分析的結果是一組單詞序列,單詞序列的每個單詞由單詞類型和值組成。

MySQL的SQL解析過程中,詞法和語法解析耦合在一起,即語法解析的移進規約動作觸發詞法解析,而不是先完成詞法解析,再開始語法解析。我們將流程修改為先完成詞法解析獲取單詞序列,然後進行語法解析。

另外是我們定義的相似性規則。什麼是相似呢?就是對比兩個SQL的單詞序列,滿足單詞類型相同,如果是類型非參數,則要求單詞的值相等(忽略大小寫)。我們根據這個相似性規則制定了一個相似性hash算法,用於提升相似性查找性能。

相似性複用

技術分析!中國銀聯分佈式數據庫實踐

需要實現該功能點,需要修改LEX_STRING。LEX_STRING是詞法分析和語法解析的最基礎數據。這裡增加兩個字段,一個是index,即其在詞法解析中的位置。

另一個是next_lex_string(MySQL的SQL語法中,它可以把連續的兩個字符串拼接到一起,next_lex_string表示的是字符串後續的下一個字符串)。

複雜查詢

技術分析!中國銀聯分佈式數據庫實踐

如何解決複雜查詢(例如典型的跨庫Join)?

基於MySQL有兩條路,一條是強化Proxy層構建支持複雜查詢的執行計劃,但是這樣做代價很高,並且無法保證SQL解析知識的完備性以及分佈式計劃的症狀性,風險性很高。

另一條路是使用分佈式儲存引擎,MariaDB Spider和MySQL NDB。但是MariaDB Spider同步調用較多、性能不佳,而MySQL NDB缺乏實踐經驗。

MariaDB Spider是一個比較完善的解決方案,但其水平擴展主要是擴展存儲容量,性能上的提升不明顯。

因此我們就考慮做一個類似於MariaDB Spider的方案。

設計思路(Federated+Proxy)

技術分析!中國銀聯分佈式數據庫實踐

設計思路:Federated+Proxy

核心思路是,由Federated引擎外掛UPSQL Proxy,由UPSQL Proxy實現數據拆分和事務管理。這樣UPSQL Proxy把拆表的過程隱藏起來,Federated連上去的時候只看到一個單表,就可以輕鬆實現複雜查詢了。

這樣的改動邏輯簡單,功能可控。但是缺點也很明顯:Federated是使用同步請求訪問UPSQL Proxy,且UPSQL Proxy被屏蔽在Federated之後,導致整體性能低下。

設計思路(語句分類路由)

技術分析!中國銀聯分佈式數據庫實踐

設計思路:語句分類路由

核心思路是,OLAP和OLTP的融合技術。一條應用語句過來了之後,我們做一個語句分類,把複雜語句交給OLAP,簡單語句交給OLTP,然後最終都訪問同一個事務管理模塊和執行模塊,這樣可以保證無論什麼樣的語句都居於統一的事務之中。

設計思路:(協處理器:XProxy)

技術分析!中國銀聯分佈式數據庫實踐

在我們的方案中,我們研發了一個XProxy協處理器。

核心思路是,UPSQL 和Proxy拿到語句後,做一個解析和分類執行,如果是一個複雜語句,就丟給MySQL Server,它會把複雜語句拆解成簡單語句,然後反向的丟回給UPSQL 和Proxy。這個路徑很長,但是優點是簡單語句可以通過Proxy直接到數據庫上,同時也可以支持複雜語句。但是缺點是交互次數變多,性能較差。

夥伴部署

技術分析!中國銀聯分佈式數據庫實踐

在實際部署中我們會考慮兩種部署方案,一種叫做夥伴部署。

把UPSQL 、Proxy和MYSQL一一對應部署在一起,但是缺點是需要額外增加一個資源。

集群部署

技術分析!中國銀聯分佈式數據庫實踐

第二種方案叫集群部署,也就是在夥伴部署的基礎上做了一些改動。將XProxy引擎下沉到數據存儲節點,實現資源複用。這樣可以實現UPSQL 、Proxy和數據節點之間是集群和集群的關係。

一般情況下我們會把它的複雜查詢入到下面的一個備庫,這樣可以保證性能和資源。但是這種集群關係必須要保證Proxy轉發請求到回來的這種雙方的關聯關係。

技術分析!中國銀聯分佈式數據庫實踐

複雜查詢總結

• XProxy實現要點:

a) 使用STMT協議訪問UPSQL Proxy

b) 會話關聯(UPSQL Proxy與XProxy雙向話關聯),事務管理器關聯

c) 在線DDL

• 進一步優化(生產實踐優先級低):

a) ICP(Index Condition Pushdown)

b) ECP(Engine Condition Pushdown)

• 該方案在如下場景下性能極差,複雜查詢下:

a) 不帶過濾條件的分頁– 需要增加存儲引擎接口

b) 統計運算- 可以借鑑MariaDB Spider的MapReduce方案


分享到:


相關文章: