在2004年,騰訊充值、財付通等業(yè)務爆發(fā)發(fā)展,但那時騰訊和所有的創(chuàng)業(yè)公司有個共同點—“窮”,在這樣的背景下,TDSQL逐步誕生了,所以騰訊金融類業(yè)務從一開始就沒有IOE。
因為期間經歷了業(yè)務層對拆分的濫用,主從數據不一致導致的數據準確性問題,以及上百臺設備集群的管理問題等。
所以,從08年開始,團隊決定重構TDSQL解決方案,針對金融類業(yè)務的特點,列出以下幾個要點:
l 數據強一致的要求
l 數據庫集群的可用性、穩(wěn)定性和容災要求要達到銀行標準
l 業(yè)務無需拆分超大表,數據庫自動拆分
l 接入要簡單,老業(yè)務改造要小,必須兼容MySQL協(xié)議
l 符合并高于金融行業(yè)信息安全監(jiān)管要求
TDSQL的軟件架構組成
整體來說,TDSQL是由決策調度集群/GTM,SQLEngine、數據存儲層等核心組件組成的,其每個模塊都基于分布式架構設計,可以實現快速擴展,無縫切換,實時故障恢復等,通過這一架構,TDSQL的Noshard、Shard、TDSpark實例可以混合部署在同一集群中。并且使用簡單的x86服務器,可以搭建出類似于小型機、共享存儲等一樣穩(wěn)定可靠的數據庫。
在架構上,TDSQL的核心思想只有兩個:數據的復制(replica)和分片(sharding),其它都是由此衍生出來的。其中,
replica配合故障的檢測和切換,解決可用性問題;
sharding配合集群資源調度、訪問路由管理等,解決容量伸縮問題。
同時,因replica引入了數據多副本間的一致性問題和整體吞吐量下降的問題,而sharding的引入也會帶來一定的功能約束。
在最終實現上,TDSQL由Scheduler、Gateway、Agent三個核心組件加上MySQL組成,其中:
Scheduler是管理調度器,內部又分為zookeeper和scheduler server;
Gateway為接入網關,多個網關組成一個接入層;
Agent是執(zhí)行代理,與MySQL實例一起,構成數據節(jié)點。多個數據節(jié)點構成服務單元SET。
相比單機版的MySQL,TDSQL的優(yōu)勢主要體現在集群維度,包括容災、高一致性、高彈性等。
注:√ 支持,×不支持, ○不適用
數據一致性考驗
在金融行業(yè),銀行、風控、渠道等第三方通常通過讀寫分離方式來查詢數據,而在互聯網行業(yè),由于x86相對較高的故障率,導致數據可能經常性的出現錯亂、丟失場景。為了解決這個問題,就必須要求主從數據的強一致和良好的讀寫分離策略。其關鍵在于,如何實現強同步復制技術。
由于MySQL的半同步和Galera模式不僅對性能的損耗是非常大的,而且數據同步有大量毛刺,這給金融業(yè)務同城雙中心或兩地三中心架構容災架構帶來了極大的挑戰(zhàn)。
為什么會這樣呢?從1996年的MySQL3.1.1.1版本開始,業(yè)務數據庫通常跑在內網,網絡環(huán)境基本較好,因此MySQL采用的是每個連接一個線程的模型,這套模型最大的好處就是開發(fā)特別簡單,線程內部都是同步調用,只要不訪問外部接口,支撐每秒幾百上千的請求量也基本夠用,因為大部分情況下IO是瓶頸。
但隨著當前硬件的發(fā)展,尤其是ssd等硬件出現,IO基本上不再是瓶頸,如再采用這套模型,并采用阻塞的方式調用延遲較大的外部接口,則CPU都會阻塞在網絡應答上了,性能自然上不去。
因此,TDSQL引入線程池,將數據庫線程池模型(執(zhí)行SQL的邏輯)針對不同網絡環(huán)境進行優(yōu)化,并支持組提交方案。例如,在binlog復制方案上,我們將復制線程分解:
1、任務執(zhí)行到寫binlog為止,然后將會話保存到session中,接著執(zhí)行下一輪循環(huán)去處理其它請求了,這樣就避免讓線程阻塞等待應答
2、MySQL自身負責主備同步的dump線程會將binlog立即發(fā)送出去,備機的io線程收到binlog并寫入到relaylog之后,再通過udp給主機一個應答
3、在主機上,開一組線程來處理應答,收到應答之后找到對應的會話,執(zhí)行下半部分的commit,send應答,綁定到epoll等操作。綁定到epoll之后這個連接又可以被其它線程檢測到并執(zhí)行
改造后,使得TDSQL可以應對復雜的網絡模型。當然,深入了解過MySQL同步機制的朋友可能會發(fā)現上述方案還有小缺陷:當主機故障,binlog沒有來得及發(fā)送到遠端,雖然此時不會返回給業(yè)務成功,備機上不存在這筆數據,然而在主機故障自愈后,主機會多出來這筆事務的數據。解決方法是對新增的事務根據row格式的binlog做閃回,這樣就有效解決了數據強一致的問題。
2018年初,英特爾技術團隊使用sysbench測試方案,在跨機房、相同機型、網絡和參數配置和高并發(fā)下測試,TDSQL強同步復制平均性能是MySQL5.7異步復制的1.2倍。
基于規(guī)則和基于代價的查詢引擎
當前大多數分布式數據庫都設計的是基于規(guī)則的查詢引擎(RBO),這意味著,它有著一套嚴格的使用規(guī)則,只要你按照它去寫SQL語句,無論數據表中的內容怎樣,也不會影響到你的“執(zhí)行計劃”,但這意味著該規(guī)則復雜的數據計算需求不“敏感”。雖然金融業(yè)務都有自己的數據倉庫,然而也會經常需要在OLTP類業(yè)務中執(zhí)行事務、JOIN甚至批處理。
TDSQL在SQLENGINE實現了基于代價的查詢引擎(CBO),SQL經過SQLENGINE的詞法,語法解析,語義分析和SQL優(yōu)化之后,會生成分布式的查詢計劃,并根據數據路由策略(基于代價的查詢引擎)進行下推計算,最后對匯總的數據返回給前端。
而作為分布式的計算引擎,在存儲與計算引擎相分離的情況下,非常重要的一環(huán)就是如何將計算盡量下推的下面的數據存儲層。因此TDSQL的SQLENGINE在經過大量業(yè)務打磨后,實現了基于shard key下推,索引條件下推,驅動表結果下推,null下推,子查詢下推, left join轉化成inner join等多達18種下推優(yōu)化手段,盡量降低數據在多個節(jié)點傳輸帶來的壓力,以提供更好的分布式查詢的能力,支撐金融交易的關聯操作。
全局事務一致性與全局時間戳服務GTM
金融行業(yè)對事務處理的需求極高,轉賬、扣費,無一不是使用事務,而騰訊是少數幾個將分布式事務處理,分布式JOIN用于金融核心系統(tǒng)的企業(yè)。
TDSQL仍然是通過經典的XA兩階段提交加兩階段封鎖協(xié)議實現了強分布式事務的語義,以支撐金融場景對事務管理的需求。在使用語法上與MySQL完全一樣,即后端的分布式事務處理對業(yè)務使用方是完全不感知,以保證兼容性。
在二階段提交實現上,在begin的時候從GTM獲取全局遞增的事務ID,然后在參與事務的各個子節(jié)點通過這個事務ID開啟事務,進行各種DML操作,提交的時候先對各個子節(jié)點執(zhí)行prepare。當prepare成功之后,再更新全局事務ID的事務狀態(tài),同時獲取到一個新的事務ID作為提交的事務ID對各個子事務進行異步并行化的提交,提供更好的事務操作性能。
當前GTM以一主兩從的方式運行,主從節(jié)點底層通過 raft 協(xié)議進行數據的同步以及主從切換,內部交互以及對外通訊均基于 grpc 協(xié)議。當前TDSQL的GTM組件性能完全可以滿足金融業(yè)務需求:
l 全局時間戳:≈180w – 190w TPS,8 Clients,主節(jié)點CPU 跑滿情況下(24core),內存消耗約23GB;
l 遞增序列號:≈750w – 780w TPS,8 Clients,10萬個 key,主節(jié)點 CPU 跑滿情況下 ,內存 消耗約30GB;
從節(jié)點資源消耗:因為所有請求均由Leader節(jié)點完成響應,從只負責接受來自于 主節(jié)點的 raft 數據同步請求,并且 從節(jié)點上不緩存任何數據,因此 CPU 和 內存消耗都在極低的程度;因此,一般場景下,通常GTM與調度決策集群可以混合部署,極大的節(jié)省了物理設備成本。
TDSQL的HTAP能力
TDSQL除了提供計算下推,分布式事務等特性,也針對OLAP需求演進了TDSpark特性。
簡單來說,是將SQLEngine基于OLAP場景做了修改,保留原生的MySQL協(xié)議接入能力。因此業(yè)務繼續(xù)可以通過訪問MySQL的渠道接入到OLAP-SQLEngine,OLAP-SQLEngine在這個時候不是將分布式的查詢計劃直接下推到各個數據庫節(jié)點,而是引入一個中間層,目前是采用SPARKSQL,通過SPARKSQL強大的計算能力能顯著提升復雜SQL的執(zhí)行性能。另外為了確保分析操作與在線的OLTP業(yè)務隔離,我們TDSQL的數據層為每份數據增加1個watch主數據庫的數據異步節(jié)點,確保分析操作與在線業(yè)務操作不互相影響。
數據安全與容災
數據安全和容災是金融類業(yè)務的命脈,而TDSQL現已經應用在多個銀行、保險的公有云或私有云環(huán)境。符合國家等級保護信息安全要求,通過銀保監(jiān)會相關審核,獲得了包括ISO,SOC等國內和國際標準。
而在容災能力方面,TDSQL可以支持:
l 同城數據強一致下的雙活:當前騰訊公有云和金融云有大量的客戶都選擇了類似方案。
l 主從讀寫分離的異地多活:該方案適用于應用完全不做任何改造,就可以實現跨城多活的能力。當前TDSQL很多客戶不想對業(yè)務改造,但是又想具備跨城多活和切換的能力,通常選擇這個方案。
l 多主的異地多活架構,并支持雙向同步:通過應用層根據用戶維度做了區(qū)分之后,可以使得多套TDSQL數據庫分別承載不同的業(yè)務進行讀寫事務訪問,實現完全的多活能力,但是如果業(yè)務系統(tǒng)無法保證調度安全和數據的區(qū)分,可能存在數據異常的風險。
l 多主的異地多活架構,多套主從架構:綜合了前面兩種架構,實現了完全的異地多活+讀寫分離的能力,并且即使業(yè)務層路由錯誤,也不會引起數據異常。當然,對應的應用層也要能配合修改。
當然越高要求對部署的要求約復雜,目前公有云已經提供了前面兩種方案可供大家試用。
數據庫自治運營
為了保證系統(tǒng)的運行做到一切盡在掌控之中,TDSQL不僅有完善的管控系統(tǒng)(赤兔)來完成系統(tǒng)的自動化管理,從可用性、安全、效率、成本維度進行全方位管控。還在赤兔中引入了“數據庫自治運營”的理念,構建了一套能自我學習的智能檢測平臺(簡稱扁鵲)。
以SQL優(yōu)化為例,該系統(tǒng)能自動抽象出當前效率最差的若干SQL,并將這些通過解析SQL生成AST語法樹,分析語法樹中表的連接方式和連接字段,然后遍歷語法樹中的過濾,排序等關鍵字段,再次分析各字段的區(qū)分度,對于區(qū)分度較高的字段會提供推薦優(yōu)化方案,綜合字段區(qū)分度,過濾規(guī)則,表連接順序等多個因素推提供優(yōu)化建議。
TDSQL的自治運營的最終目標是利用公有云龐大的環(huán)境進行自我學習和自我進化,做到無需人工干預即可進行更新、調整和修復,從而解放人力、減少人為差錯,幫助企業(yè)節(jié)約管理及經濟成本、降低風險。
金融業(yè)務的數據庫發(fā)展及展望
金融業(yè)務涉及國計民生的重點業(yè)務,一個小小的BUG,一個操作失誤,就可能影響到數以萬計的百姓資產準確性。正因為這樣的責任,騰訊云TDSQL團隊始終堅守則“本心”。
目前,TDSQL已在北京、深圳、成都三地建立研發(fā)團隊,并通過CMMI3認證,同時在開源社區(qū)擁有自己的開源分支。值得一提的是TDSQL已獲得包括ISO27001、ISO22301、PCI DSS、SOC審計,工信部分布式數據庫測試,IT168技術突破大獎,多項國家或國際認證和行業(yè)殊榮。并與包括中國人民大學,中國銀行等開展產研結合、產用結合,并取得諸多創(chuàng)新成績。
展望2019年,TDSQL將持續(xù)通過產研結合、產用結合的方式進行研發(fā)突破,并開放商用更多特性,擁抱開源社區(qū)。