在架構上,TDSQL 的核心思想有兩個:數據的復制(replica)和分片(sharding),其它都是由此衍生出來的。其中,

TDSQL 面向數據一致性考驗

在金融行業(yè),銀行、風控、渠道等第三方通常通過讀寫分離方式來查詢數據,而在互聯(lián)網行業(yè),由于 x86 相對較高的故障率,導致數據可能經常性的出現(xiàn)錯亂、丟失場景。為了解決這個問題,就必須要求主從數據保持強一致和良好的讀寫分離策略。而其中的關鍵在于如何實現(xiàn)強同步復制技術。

由于 MySQL 的半同步和 Galera 模式不僅對性能的損耗是非常大的,而且數據同步有大量毛刺,這給金融業(yè)務同城雙中心或兩地三中心架構容災架構帶來了極大的挑戰(zhàn)。為什么會這樣呢?

從 1996 年的 MySQL3.1.1.1 版本開始,業(yè)務數據庫通常跑在內網,網絡環(huán)境基本較好,因此 MySQL 采用的是每個連接一個線程的模型,這套模型最大的好處就是開發(fā)特別簡單,線程內部都是同步調用,只要不訪問外部接口,支撐每秒幾百上千的請求量也基本夠用,因為大部分情況下 IO 是瓶頸。

但隨著當前硬件的發(fā)展,尤其是 ssd 等硬件出現(xiàn),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 基本可以應對復雜的網絡模型。

但上述方案還有小缺陷:當主機故障,binlog 沒有來得及發(fā)送到遠端,雖然此時不會返回給業(yè)務成功,備機上不存在這筆數據,然而在主機故障自愈后,主機會多出來這筆事務的數據。解決方法是對新增的事務根據 row 格式的 binlog 做閃回,這樣就有效解決了數據強一致的問題。

基于規(guī)則和基于代價的查詢引擎

當前大多數分布式數據庫都設計的是基于規(guī)則的查詢引擎 (RBO),這意味著,它有著一套嚴格的使用規(guī)則,只要你按照它去寫 SQL 語句,無論數據表中的內容怎樣,也不會影響到你的“執(zhí)行計劃”,但這意味著該規(guī)則復雜的數據計算需求不“敏感”。雖然金融業(yè)務都有自己的數據倉庫,然而也會經常需要在 OLTP 類業(yè)務中執(zhí)行事務、Join 甚至批處理。

TDSQL 在 SQLENGINE 實現(xiàn)了基于代價的查詢引擎 (CBO),SQL 經過 SQLENGINE 的詞法、語法解析、語義分析和 SQL 優(yōu)化之后,會生成分布式的查詢計劃,并根據數據路由策略(基于代價的查詢引擎)進行下推計算,最后對匯總的數據返回給前端。

而作為分布式的計算引擎,在存儲與計算引擎相分離的情況下,非常重要的一環(huán)就是如何將計算盡量下推的下面的數據存儲層。因此 TDSQL 的 SQLENGINE 在經過大量業(yè)務打磨后,實現(xiàn)了基于 shard key 下推、索引條件下推、驅動表結果下推、null 下推、子查詢下推、left join 轉化成 inner join 等多達 18 種下推優(yōu)化手段,盡量降低數據在多個節(jié)點傳輸帶來的壓力,以提供更好的分布式查詢的能力,支撐金融交易的關聯(lián)操作。

如果說騰訊云數據庫歷史是一部從蟄伏到發(fā)展再到突破的歷史,那么可以說接下來 CynosDB 的推出,讓騰訊云數據庫迎來了新一輪云應用場景下的突破與變遷。

二、真正云原生數據庫 CynosDB 技術解析

2017 年,在騰訊云服務了百萬客戶之后,騰訊云數據庫迎來了突破。由開源數據庫適配業(yè)務和具體場景,騰訊云自主研發(fā)了一款真正的云原生數據庫CynosDB。作為騰訊云在數據庫領域的重要布局,CynosDB 單節(jié)點讀性能可以達到 130 萬 QPS,全面超越業(yè)內目前最高的 100 萬 QPS 水平。它將傳統(tǒng)數據庫與云計算的優(yōu)勢相結合,解決了傳統(tǒng)數據庫云上的難題,其設計思路可以概括為以下幾點:

  1. 首先是計算存儲分離,比如把運算 CPU 或者內存放在一起統(tǒng)一分配,可以獲得彈性調度能力。
  2. 第二個是日志下沉及異步回放,同時我們移除了數據頁面的刷臟邏輯,這樣降低了計算存儲分離的架構下的網絡開銷。
  3. 第三個就是分布式存儲,這也是我們騰訊云自研的分布存儲系統(tǒng),共享的分布式存儲可以橫向擴展。
  4. 第四個是后臺的持續(xù)日志備份,傳統(tǒng)數據庫我們的備份是在數據庫主機上去拷日志完成備份,而 CynosDB 的持續(xù)備份是在存儲上進行,不干擾數據庫實例,減輕由于備份的工作任務對數據庫的沖擊,并且用戶可以不必關心備份策略和備份存儲資源規(guī)劃。
計算存儲分離架構的實現(xiàn)和優(yōu)化

這里需要重點說下計算和存儲分離。傳統(tǒng)數據庫的優(yōu)化演進歷史,基本上是和IO 做斗爭的歷史,因為數據庫是有狀態(tài)、重 IO 的服務,傳統(tǒng) MySQL 架構有多個 IO 類型,存儲相同的文件,所以主機和備機的磁盤會有很多相同的 IO 和冗余的文件。即便數據庫被搬上云,為了在云上做彈性的擴容,開發(fā)者依然面臨傳統(tǒng)數據庫所面臨的問題。

基于以上痛點,CynosDB 引入計算存儲分離的架構,存儲層使用共享的分布式塊存儲云服務,計算層則將不必要的 IO 全部卸載,實現(xiàn)計算與存儲基于日志傳輸的新架構。

CynosDB 架構有如下幾個特點:
  1. 日志即數據庫。架構中只有日志流,因而只有日志能表達數據庫;
  2. IO 卸載。除了日志,其他所有類型 IO 全部卸載,如數據文件、源數據文件、biglog 文件等;
  3. 無狀態(tài)。本地文件將不復存在,包括日志文件,所以計算層是無狀態(tài)的。

在新架構中,日志處理無可厚非具有非常重要的作用。其中連續(xù)的日志在存儲層被打散成了很多的小的分片,分別存儲在不同的 cell 里。而日志處理的邏輯是將存儲引擎將日志發(fā)給存儲節(jié)點,存儲節(jié)點將日志放到一個日志隊列里面,并將其持久化,之后立即返回給存儲引擎,當存儲引擎獲得日志的反饋后就可以將一部分事務提交。其中,存儲節(jié)點會異步的進行一些操作,這些操作和事務的提交過程無關,不影響事務的提交響應速度。

而在數據庫里面,如果 buffer 足夠的話,數據庫的寫性能是和日志的落盤時間相關的,傳統(tǒng)數據庫組提交機制可能存在幾個問題,一是如果有大量的連接進來,MySQL 將會為每一個連接創(chuàng)建一個線程,如果用戶的業(yè)務沒有連接管理,那么將會存在頻繁的線程創(chuàng)建與銷毀,浪費很多資源,同時,大量并發(fā)線程的鎖沖突以及切換代價也會非常大。

針對以上問題,CynosDB 引入了線程池,直接解決了資源管理和線程切換的問題,但線程池只適合處理短任務。為此,CynosDB 同時引入了異步組提交的機制,基于線程池實現(xiàn),再增加獨立的日志寫線程 log writer,每一個工作線程提交事務的時候,并不是去做寫和刷的操作,而是將自己的請求提交到一個提交隊列里去,然后立即返回給 Server 層,以便釋放自己的線程資源。如果某一段日志持久化成功之后,log writer 會喚醒提交隊列里面等待的請求,將其重新調度到線程池的高優(yōu)先級隊列,重新獲得工作線程執(zhí)行事務提交后的工作。如此一來就能高效的利用線程池的資源,同時做到資源的控制,避免上下文頻繁切換帶來的性能問題。

日志下沉、異步回放的關鍵設計

日志下沉是什么意思?比如開發(fā)者在一個頁面做插入操作,生成的日志會放到日志管理子系統(tǒng)的日志 buffer 里,日志 buffer 的重用、刷新、并發(fā)管理等都是由數據庫來做。CynosDB 會把日志管理做成獨立模塊,并在 CynosStore Client 中實現(xiàn)。任何數據庫如果想接入這個系統(tǒng)的話,都不用去關心日志管理,直接調相關接口完成日志記錄即可。這里的日志和普通日志存在區(qū)別,比如 PG 的日志更偏向邏輯的概念,而 CynosDB 的日志,記錄的是物理修改(對某頁面的什么位置做了什么內容的修改)。另外,日志向日志 buffer 的插入過程是并行的,若有 5 個用戶同時生成日志,往日志 buffer copy 都是并行進行的而非串行。

總結來說,日志下沉是指 DB 層產生的日志都會放到 CynosStore Client 的 buffer 中,然后異步發(fā)送到分布式存儲中,而不是存到本地。而在分布式存儲中有一塊固定的存儲空間來專門存儲日志,由于空間大小固定,因此在 CynosStore 中會有特定的線程,定時地把日志異步地合并到數據頁面上,通過這種日志回收機制可以有效的利用日志空間,保證寫的連續(xù)性。

CynosDB 應用場景及未來規(guī)劃

近日,騰訊云數據庫 CynosDB 正式亮相 MariaDB 用戶者大會,并受到了 MariaDB 基金會以及眾多參會者的認可。

與此同時,騰訊云數據庫產品總監(jiān)王義成還向記者透露,今年 Q3,CynosDB 將會徹底完成商業(yè)化。CynosDB 的技術能力以及存儲層早已具備按使用量計費的能力,計算層也正在進行相應的適配,待 CynosDB 商業(yè)化后將逐步推上日程。

由于 CynosDB 對主流開源數據庫的兼容,以及快速彈性升級、海量數據存儲等優(yōu)勢,王義成稱,CynosDB 未來將持續(xù)落地應用于包括互聯(lián)網及游戲等廣闊的行業(yè),幫助用戶更好地應對業(yè)務高峰,加速業(yè)務創(chuàng)新。

三、后記

從 2012 年到 2019 年,這七年,騰訊云數據庫無不見證、參與數據庫技術發(fā)展史上的一次次突破與迭代?;赝@段從開源到適配,從適配到自研的歷程,騰訊云可以說將每一次經由業(yè)務適配考驗后的思考、經驗都化作數據庫服務的“活水”,灌溉自身業(yè)務的同時也灌溉了開發(fā)者社區(qū)。

但值得注意的是,在長達幾十年的時間里,由于國內數據庫市場啟動較晚,國外巨頭始終占據數據庫絕對領先優(yōu)勢,使得國產數據庫的發(fā)展十分艱難。未來,由云原生技術帶來的一系列新技術與市場機遇,不僅僅是對數據庫管理員的挑戰(zhàn),也是對數據庫產品內核與工具的考驗,接下來騰訊云數據庫“風”往何處吹?且看“行云”。

分享到

songjy

相關推薦