在架構(gòu)上,TDSQL 的核心思想有兩個:數(shù)據(jù)的復(fù)制(replica)和分片(sharding),其它都是由此衍生出來的。其中,
在金融行業(yè),銀行、風(fēng)控、渠道等第三方通常通過讀寫分離方式來查詢數(shù)據(jù),而在互聯(lián)網(wǎng)行業(yè),由于 x86 相對較高的故障率,導(dǎo)致數(shù)據(jù)可能經(jīng)常性的出現(xiàn)錯亂、丟失場景。為了解決這個問題,就必須要求主從數(shù)據(jù)保持強一致和良好的讀寫分離策略。而其中的關(guān)鍵在于如何實現(xiàn)強同步復(fù)制技術(shù)。
由于 MySQL 的半同步和 Galera 模式不僅對性能的損耗是非常大的,而且數(shù)據(jù)同步有大量毛刺,這給金融業(yè)務(wù)同城雙中心或兩地三中心架構(gòu)容災(zāi)架構(gòu)帶來了極大的挑戰(zhàn)。為什么會這樣呢?
從 1996 年的 MySQL3.1.1.1 版本開始,業(yè)務(wù)數(shù)據(jù)庫通常跑在內(nèi)網(wǎng),網(wǎng)絡(luò)環(huán)境基本較好,因此 MySQL 采用的是每個連接一個線程的模型,這套模型最大的好處就是開發(fā)特別簡單,線程內(nèi)部都是同步調(diào)用,只要不訪問外部接口,支撐每秒幾百上千的請求量也基本夠用,因為大部分情況下 IO 是瓶頸。
但隨著當(dāng)前硬件的發(fā)展,尤其是 ssd 等硬件出現(xiàn),IO 基本上不再是瓶頸,如再采用這套模型,并采用阻塞的方式調(diào)用延遲較大的外部接口,則 CPU 都會阻塞在網(wǎng)絡(luò)應(yīng)答上了,性能自然上不去。
為了解決這些問題,TDSQL 引入了線程池,將數(shù)據(jù)庫線程池模型 (執(zhí)行 SQL 的邏輯) 針對不同網(wǎng)絡(luò)環(huán)境進行優(yōu)化,并支持組提交方案。例如,在 binlog 復(fù)制方案上將復(fù)制線程分解:
改造后, TDSQL 基本可以應(yīng)對復(fù)雜的網(wǎng)絡(luò)模型。
但上述方案還有小缺陷:當(dāng)主機故障,binlog 沒有來得及發(fā)送到遠端,雖然此時不會返回給業(yè)務(wù)成功,備機上不存在這筆數(shù)據(jù),然而在主機故障自愈后,主機會多出來這筆事務(wù)的數(shù)據(jù)。解決方法是對新增的事務(wù)根據(jù) row 格式的 binlog 做閃回,這樣就有效解決了數(shù)據(jù)強一致的問題。
當(dāng)前大多數(shù)分布式數(shù)據(jù)庫都設(shè)計的是基于規(guī)則的查詢引擎 (RBO),這意味著,它有著一套嚴格的使用規(guī)則,只要你按照它去寫 SQL 語句,無論數(shù)據(jù)表中的內(nèi)容怎樣,也不會影響到你的“執(zhí)行計劃”,但這意味著該規(guī)則復(fù)雜的數(shù)據(jù)計算需求不“敏感”。雖然金融業(yè)務(wù)都有自己的數(shù)據(jù)倉庫,然而也會經(jīng)常需要在 OLTP 類業(yè)務(wù)中執(zhí)行事務(wù)、Join 甚至批處理。
TDSQL 在 SQLENGINE 實現(xiàn)了基于代價的查詢引擎 (CBO),SQL 經(jīng)過 SQLENGINE 的詞法、語法解析、語義分析和 SQL 優(yōu)化之后,會生成分布式的查詢計劃,并根據(jù)數(shù)據(jù)路由策略(基于代價的查詢引擎)進行下推計算,最后對匯總的數(shù)據(jù)返回給前端。
而作為分布式的計算引擎,在存儲與計算引擎相分離的情況下,非常重要的一環(huán)就是如何將計算盡量下推的下面的數(shù)據(jù)存儲層。因此 TDSQL 的 SQLENGINE 在經(jīng)過大量業(yè)務(wù)打磨后,實現(xiàn)了基于 shard key 下推、索引條件下推、驅(qū)動表結(jié)果下推、null 下推、子查詢下推、left join 轉(zhuǎn)化成 inner join 等多達 18 種下推優(yōu)化手段,盡量降低數(shù)據(jù)在多個節(jié)點傳輸帶來的壓力,以提供更好的分布式查詢的能力,支撐金融交易的關(guān)聯(lián)操作。
如果說騰訊云數(shù)據(jù)庫歷史是一部從蟄伏到發(fā)展再到突破的歷史,那么可以說接下來 CynosDB 的推出,讓騰訊云數(shù)據(jù)庫迎來了新一輪云應(yīng)用場景下的突破與變遷。
2017 年,在騰訊云服務(wù)了百萬客戶之后,騰訊云數(shù)據(jù)庫迎來了突破。由開源數(shù)據(jù)庫適配業(yè)務(wù)和具體場景,騰訊云自主研發(fā)了一款真正的云原生數(shù)據(jù)庫CynosDB。作為騰訊云在數(shù)據(jù)庫領(lǐng)域的重要布局,CynosDB 單節(jié)點讀性能可以達到 130 萬 QPS,全面超越業(yè)內(nèi)目前最高的 100 萬 QPS 水平。它將傳統(tǒng)數(shù)據(jù)庫與云計算的優(yōu)勢相結(jié)合,解決了傳統(tǒng)數(shù)據(jù)庫云上的難題,其設(shè)計思路可以概括為以下幾點:
這里需要重點說下計算和存儲分離。傳統(tǒng)數(shù)據(jù)庫的優(yōu)化演進歷史,基本上是和IO 做斗爭的歷史,因為數(shù)據(jù)庫是有狀態(tài)、重 IO 的服務(wù),傳統(tǒng) MySQL 架構(gòu)有多個 IO 類型,存儲相同的文件,所以主機和備機的磁盤會有很多相同的 IO 和冗余的文件。即便數(shù)據(jù)庫被搬上云,為了在云上做彈性的擴容,開發(fā)者依然面臨傳統(tǒng)數(shù)據(jù)庫所面臨的問題。
基于以上痛點,CynosDB 引入計算存儲分離的架構(gòu),存儲層使用共享的分布式塊存儲云服務(wù),計算層則將不必要的 IO 全部卸載,實現(xiàn)計算與存儲基于日志傳輸?shù)男录軜?gòu)。
在新架構(gòu)中,日志處理無可厚非具有非常重要的作用。其中連續(xù)的日志在存儲層被打散成了很多的小的分片,分別存儲在不同的 cell 里。而日志處理的邏輯是將存儲引擎將日志發(fā)給存儲節(jié)點,存儲節(jié)點將日志放到一個日志隊列里面,并將其持久化,之后立即返回給存儲引擎,當(dāng)存儲引擎獲得日志的反饋后就可以將一部分事務(wù)提交。其中,存儲節(jié)點會異步的進行一些操作,這些操作和事務(wù)的提交過程無關(guān),不影響事務(wù)的提交響應(yīng)速度。
而在數(shù)據(jù)庫里面,如果 buffer 足夠的話,數(shù)據(jù)庫的寫性能是和日志的落盤時間相關(guān)的,傳統(tǒng)數(shù)據(jù)庫組提交機制可能存在幾個問題,一是如果有大量的連接進來,MySQL 將會為每一個連接創(chuàng)建一個線程,如果用戶的業(yè)務(wù)沒有連接管理,那么將會存在頻繁的線程創(chuàng)建與銷毀,浪費很多資源,同時,大量并發(fā)線程的鎖沖突以及切換代價也會非常大。
針對以上問題,CynosDB 引入了線程池,直接解決了資源管理和線程切換的問題,但線程池只適合處理短任務(wù)。為此,CynosDB 同時引入了異步組提交的機制,基于線程池實現(xiàn),再增加獨立的日志寫線程 log writer,每一個工作線程提交事務(wù)的時候,并不是去做寫和刷的操作,而是將自己的請求提交到一個提交隊列里去,然后立即返回給 Server 層,以便釋放自己的線程資源。如果某一段日志持久化成功之后,log writer 會喚醒提交隊列里面等待的請求,將其重新調(diào)度到線程池的高優(yōu)先級隊列,重新獲得工作線程執(zhí)行事務(wù)提交后的工作。如此一來就能高效的利用線程池的資源,同時做到資源的控制,避免上下文頻繁切換帶來的性能問題。
日志下沉是什么意思?比如開發(fā)者在一個頁面做插入操作,生成的日志會放到日志管理子系統(tǒng)的日志 buffer 里,日志 buffer 的重用、刷新、并發(fā)管理等都是由數(shù)據(jù)庫來做。CynosDB 會把日志管理做成獨立模塊,并在 CynosStore Client 中實現(xiàn)。任何數(shù)據(jù)庫如果想接入這個系統(tǒng)的話,都不用去關(guān)心日志管理,直接調(diào)相關(guān)接口完成日志記錄即可。這里的日志和普通日志存在區(qū)別,比如 PG 的日志更偏向邏輯的概念,而 CynosDB 的日志,記錄的是物理修改(對某頁面的什么位置做了什么內(nèi)容的修改)。另外,日志向日志 buffer 的插入過程是并行的,若有 5 個用戶同時生成日志,往日志 buffer copy 都是并行進行的而非串行。
總結(jié)來說,日志下沉是指 DB 層產(chǎn)生的日志都會放到 CynosStore Client 的 buffer 中,然后異步發(fā)送到分布式存儲中,而不是存到本地。而在分布式存儲中有一塊固定的存儲空間來專門存儲日志,由于空間大小固定,因此在 CynosStore 中會有特定的線程,定時地把日志異步地合并到數(shù)據(jù)頁面上,通過這種日志回收機制可以有效的利用日志空間,保證寫的連續(xù)性。
近日,騰訊云數(shù)據(jù)庫 CynosDB 正式亮相 MariaDB 用戶者大會,并受到了 MariaDB 基金會以及眾多參會者的認可。
與此同時,騰訊云數(shù)據(jù)庫產(chǎn)品總監(jiān)王義成還向記者透露,今年 Q3,CynosDB 將會徹底完成商業(yè)化。CynosDB 的技術(shù)能力以及存儲層早已具備按使用量計費的能力,計算層也正在進行相應(yīng)的適配,待 CynosDB 商業(yè)化后將逐步推上日程。
由于 CynosDB 對主流開源數(shù)據(jù)庫的兼容,以及快速彈性升級、海量數(shù)據(jù)存儲等優(yōu)勢,王義成稱,CynosDB 未來將持續(xù)落地應(yīng)用于包括互聯(lián)網(wǎng)及游戲等廣闊的行業(yè),幫助用戶更好地應(yīng)對業(yè)務(wù)高峰,加速業(yè)務(wù)創(chuàng)新。
從 2012 年到 2019 年,這七年,騰訊云數(shù)據(jù)庫無不見證、參與數(shù)據(jù)庫技術(shù)發(fā)展史上的一次次突破與迭代。回望這段從開源到適配,從適配到自研的歷程,騰訊云可以說將每一次經(jīng)由業(yè)務(wù)適配考驗后的思考、經(jīng)驗都化作數(shù)據(jù)庫服務(wù)的“活水”,灌溉自身業(yè)務(wù)的同時也灌溉了開發(fā)者社區(qū)。
但值得注意的是,在長達幾十年的時間里,由于國內(nèi)數(shù)據(jù)庫市場啟動較晚,國外巨頭始終占據(jù)數(shù)據(jù)庫絕對領(lǐng)先優(yōu)勢,使得國產(chǎn)數(shù)據(jù)庫的發(fā)展十分艱難。未來,由云原生技術(shù)帶來的一系列新技術(shù)與市場機遇,不僅僅是對數(shù)據(jù)庫管理員的挑戰(zhàn),也是對數(shù)據(jù)庫產(chǎn)品內(nèi)核與工具的考驗,接下來騰訊云數(shù)據(jù)庫“風(fēng)”往何處吹?且看“行云”。