導語 | 數據庫正處在變革期,變革的動力同時來自於外因和內因,外因是用戶需求的變化,內因是新技術的爆發。用戶需求從強調物理上擁有數據到邏輯上擁有數據,所以雲服務的形式被愈來愈普遍地接受;新技術的爆發體如今新的存儲介質的產品化。騰訊雲原生數據庫就是這種變革的產物,騰訊雲原生數據庫以雲服務的方式提供更好的數據庫性能,可用性和可靠性。本文由騰訊雲數據庫技術總監 張青林在 Techo TVP開發者峯會「數據的冰與火之歌——從在線數據庫技術,到海量數據分析技術」 的《騰訊雲TDSQL-C架構探索和實踐》演講分享整理而成,爲你們詳盡介紹騰訊雲原生數據庫的架構、在覈心指標上的突破以及探索。
點擊可觀看精彩演講視頻html
咱們今天的分享主要由三部分組成,第一部分是咱們作TDSQL-C這款產品的背景,即爲何作TDSQL-C、它的架構和現狀如何。第二部分主要介紹TDSQL-C有哪些突破性的創新,以及從用戶視角來看咱們主要作了哪些能夠方便用戶的事。第三部分是TDSQL-C將來的RoadMap,偏技術。算法
首先看第一點。咱們以前是作CDB的產品運營研發相關工做,但在作的時候遇到了一些在傳統數據庫領域難以解決的問題:首先是存儲容量問題,當單機磁盤容量達到必定程度時,就會對業務帶來相應的麻煩。第二個是擴展性,熟悉數據庫運維的朋友應該知道,典型的場景是在業務有活動的時候咱們加機器,在業務活動結束以後要減機器,它的過程通常是通過備份、組件、實例,效率較差。第三是可用性,典型的就是災備,從DBA的角度來看,災備發生HA的時候,這個時間點是不可控的。第四是可靠性,由於單機傳統的MySQL架構,它的一主一備,而且存儲是在本地存儲,當咱們本地磁盤損壞的時候,它的數據可靠性會有問題,傳統的MySQL作數據備份以及數據恢復,若是出現了大數延遲或者DDL這種問題的時候,這個時候若是再發生HA,那麼此時數據庫服務其實是不可用的。數據庫
基於在傳統數據庫領域運維遇到的問題,再結合業內的一些架構,咱們自主研發了騰訊的一種存儲和分離的數據庫產品。緩存
這是咱們總體TDSQL-C的架構圖,它和傳統的MySQL相似,支持一個讀寫節點、多個備庫節點,備庫節點最多能夠支持15個讀節點。它分爲計算和存儲兩部分,計算節點主要負責數據庫的傳統業務邏輯領域,包括像事務、鎖以及經常使用的DML,傳統數據庫領域裏全部在數據庫的操做,除了兩部分不在計算層之外,其餘都在計算層,計算層不負責數據的持久化操做,數據的持久化操做會下發到存儲層,存儲層來負責數據的持久化操做。存儲層是 HiStore (網絡存儲),自己最大支持的存儲規模如今有1PB。而主備之間和原生MySQL不一樣的是它使用Redo log進行主備數據同步,Redo log發送到備庫以後只負責同步備庫之間的BP。性能優化
咱們來看總體原生的MySQL一主一備的架構和如今TDSQL-C的架構。原生的MySQL裏的存儲是在本地進行的,依賴於本地的Dict存儲,受限於本地的存儲空間;TDSQL-C裏的存儲是網絡雲盤,它分爲兩級存儲,上面是HiStore,負責存儲數據,下面負責存儲備份。網絡
它的計算和存儲分離,可是計算節點的主備節點會共享存儲,就是下面這個HiStore。和傳統MySQL架構不一樣,它是一個可計算存儲,體現了兩點:主節點的計算節點會把產生的Redo日誌下發到存儲層,存儲層會依賴於它的Base page以及所產生的Redo log來負責數據的持久化操做,存儲層在收到Redo log後纔會向計算層反饋信息,說明Redo log已經持久化,證實如今的事務已經結束,可讓業務邏輯繼續進行。業務邏輯在進行的同時,存儲層會異步處理Redo log,計算中存儲下來的Redo log共同生成新的,由這個新的持久化到HiStore裏負責,從而將數據持久化操做。因此它和傳統的CDB或傳統的MySQL架構下面沒有數據的持久化操做,也就不會有WAL帶來的一些性能抖動問題。架構
在HiStore把數據持久化以後,會把以前Redo log所佔的內存空間回收。而咱們的存儲也有如下特性:咱們在把本地磁盤映射到網絡存盤時,是根據它的物理地址映射到底下存儲空間的某一個cell中,因此它的日誌是按照頁面來進行分發,每個cell裏都有相應的數據頁和Redo log,由於子節點和主節點是共享存儲數據的,因此要求咱們的存儲支持數據多版本,它的數據多版本是由咱們的Base page加上從計算中傳遞下來的Redo log共同生成的一個具備指定版本的數據來進行的。框架
剛纔介紹了咱們自己的架構,而從總體上的架構來看,TDSQL-C有如下特性:第一是海量存儲、智能擴容。存儲由HiStore支持,網絡存儲最大可支持1PB,相對於如今單機容量幾十T或者幾T來講,不是一個級別的。第二是咱們總體的QPS存儲量能夠達到百萬級別,因此它的性能也獲得了線性擴充。第三是兼容MySQL和PG,也沒有分佈式事務鎖帶來的一些問題,不進行數據分片,因此是自然支持分佈式的。其次是擴展性,相對於傳統的CDB架構或者傳統RDS架構來講,它不依賴於本地的物理備份或者邏輯備份導數據來進行擴容,而是直接從文件系統作一個快照,快照加上Redo log來作擴容,因此整個擴容的時間基本在一分鐘之內,能夠說是秒級擴容。再次是和Serverless、備份以及故障切換相關的,咱們下面一一來看。less
這是總體上TDSQL-C的一些架構和所支持的特性,也是咱們的現狀。在實現TDSQL-C這款計算和存儲分離的分佈式產品裏,咱們爲解決用戶實際問題而作的一些特性:運維
首先是Serverless場景。在支持Serverless以前,咱們在作業務開發和運維時,會先購買一個計費的數據庫實例,包括存儲空間、網絡存儲空間和計算資源,都會從購買的這一刻起開始計費。可是在業務開發的時候確定是屬於低頻使用時期,那麼在咱們總體的開發場景,使用數據庫的場景較少,在Serverless場景下會根據你所使用的時間來進行計費,每5秒對這個實例打一個點,一分鐘內會有12個點,一小時以內有720個點,真正在打點的時候使用時間纔會做爲真正的計費時間。在Serverless場景之下買一個實例時,你會有一個計算資源和一個存儲空間,真正使用時是所有計費的,但你不使用時,它的計費空間只是存儲空間,因此能下降咱們的消費,而且用戶利潤能夠達到最大化。
也不用關心何時啓動和關閉Serverless,當對它沒有訪問的時候就自動關閉,當再一次發送請求時,咱們會有中間的方式來自動界定它須要再次訪問,那麼它會迅速的把這個實例拉起來。因此它有兩個特性,第一個是智能極致彈性:極速啓停,第二個是真正的按使用計費。
爲了實現Serverless,咱們作了如下事情。因爲咱們是本地網絡,因此網絡延遲會增長,爲了實現極速啓停,咱們把BP獨立在MySQL以外,在購買MySQL實例的或在建立BP的時候,實際上它是獨立於MySQL進程以外的。
由於分析到整個MySQL啓停過程當中耗時間,咱們也作了並行化處理,爲了可以知足真正的「所用即所費」。由於在MySQL裏建立一個表,這時會預先分配表的空間,不管用或不用,這些空間都會做爲使用空間,咱們在分配空間的時候是以exten或者1兆來進行分配的,若是你沒有使用這1兆的話,那麼這1兆就不會在你的計費空間之內,只有真正當你寫數據在1兆空間的某一頁時,纔會真正災容計費存儲量。因此從用戶的角度出發,把用戶的計費存儲量基本降到最低,後續咱們還會繼續優化,真正作到頁級別的使用計費。
咱們單機容量可能在幾G或幾十G,這個時候它的內存是比較小的,好比只有幾百個G的內存或者不到一個T,可是存儲空間可能會有幾百個T,這時屬於典型的IO Bound類型,爲了解決這個問題,咱們把這種BP內存放到本地作二級緩存,在IO Bound場景之下,實際上並非淘汰,而是把它淘汰到咱們本地的SSD存儲或者本地的AEP存儲,下次用的時候,能夠直接從本地讀取,這樣就能夠最大限度下降網絡IO的消耗。在咱們的測試場景裏,當命中率比較低,甚至在50%如下的時候,總體的性能是呈指數級性能提高的。
另外是咱們愈來愈本地的磁盤空間作二級緩存的時候,首先是容量可控的,能夠自動配置這一塊佔用多大的存儲空間做爲本地BP的二級緩存。內存規格以及內存管理也和BP的內存管理是相似的,淘汰的時候會首先淘汰本地的二級緩存,當本地文件不夠大的時候,它也會遵循一系列淘汰算法來進行淘汰。磁盤管理獨立於本地文件,因此它走的不是網絡IO,那麼用本地IO能夠彌補總體網絡IO的消耗,所以總體性能的收益比較明顯。這張圖就是咱們本地二級緩存的架構圖。
突破三是無感知備份。傳統CDB架構或傳統RDS架構,咱們在作備份時通常都使用邏輯備份或者物理備份,這裏面會有典型的兩個問題,不管是邏輯備份仍是物理備份,都涉及大量的IO操做,會極大佔用集體資源。爲了獲取位點作以後的增量備份,會有一把大鎖。
咱們在備份中追求兩個目標:第一是無感知備份,讓用戶沒有察覺;第二是極速回檔,由於在傳統的備份恢復時,恢復是基於本地的,若是是邏輯備份,要導數據,若是是物理備份,要拷貝數據,再加上增量備份。因此咱們的目標是無感知備份和極速回檔,真正作到這兩個才能實現秒級擴容。
這就是在TDSQL-C裏的備份和回檔,備份其實是依賴於HiStore作的文件系統的快照備份,至關於我若是發送一個備份命令,這時首先會對我以前的HiStore打一個快照,以前的寫操做會寫到新的數據存儲的地方,那麼在備份時就會直接拷貝我原先的數據,同時把它上傳到COS裏,由於咱們底層的備份是分散到多個cell裏,因此備份也是並行備份。在回檔的時候也屬於並行回檔,它得把Redo log下發到cell裏,那麼這個cell包含原始數據以及Redo log,它在回檔的時候每一個cell會自行來應用這些Redo log。因此不管是備份仍是回檔,咱們都是實現並行的,而且在回檔的時候不是像Binlog的邏輯修改,而是直接定位到一些物理修改,回檔速度也是GB級的。依賴於本地的可計算存儲以及HiStore的一系列特性,咱們能夠實現自動的無感知備份以及秒級回檔。
基於咱們如今所作的一系列事情,一方面是0-1,另外一方面是結合在運維過程當中遇到的問題,TDSQL-C後續的發展方向有兩點:第一點是極簡數據庫運維。從運維的角度來鑑定以後的發展方向,首先是智能挑戰,用過MySQL或CDB的人都應該會在MySQL的優化器上遇到一些問題,好比升級時發現它的執行計劃走錯,或者當數據量達到必定程度的時候執行計劃也會走錯,TDSQL-C的內核會在優化器裏優化總體的統計信息,而且對它的執行計劃進行斷定,動態調優。好比在升級的時候,若是發現它的執行計劃出錯,能夠自動對它進行糾正,而且發給運維。
由於在實現計算和存儲分離產品的時候咱們對內核的代碼修改量較大,而且要增長存儲量,在讀寫極致性能優化上咱們也作了相應的修改,因此咱們爲了保證它的邏輯嚴謹性也會作相應的事,包括會引入業界相關的設施,從原理上進行把控對於內核的修改。從成本的角度來看,在Serverless場景下成本大部分是存儲所帶來的,因此要下降用戶的成本。能夠從兩方面:一方面是用戶真正用的纔是他所須要付費的內容。這裏有一個存儲空間的概念,存儲空間咱們要真正作到頁級別,另一種如今是三副本,能夠經過數據壓縮存儲、糾刪碼等技術下降存儲空間,把自己的災容數據存儲空間下降在1/3左右,這也是咱們後續的一個發力方向。
第三點是效率問題,由於作DDL,當咱們單機單表容量達到上T級別的時候,在MySQL內部會首先掃描它的索引,來掃描全部這個索引相關的數據,每一個進行排序,再作歸併排序,再創建索引,這一系列的過程其實是很費時的。針對這種操做,咱們有兩方面的優化思路:第一方面是instant DDL,對於每一個字節所佔用大小之間的改變,會支持更多的instant DDL。第二是經過它建立索引的這個過程,會把剛纔所涉及到的像掃描B樹、排序、建B+樹這一系列過程所有並行化,若是可以走instant DDL的,能夠實現秒級 ddl 操做,若是不能走instant DDL的操做,會進行parallel index 處理。
面向業務的Low Database開發,特別是在TDSQL-C這款產品裏,數據存儲規模會比較大,好比上幾百個T或者相似於最大容量的P級別,那麼這個時候數據分析能力就要提高,首先咱們會提高它的最大存儲量,經過優化器以及並行執行框架,最大限度地使用機器的資源來提高單機存儲量。咱們在存儲方面會利用新的介質,好比AEP或者SSD,來極大提高本地的好比剛纔所介紹的二級緩存,或者是把一系列能夠在本地操做的作到最大加速。
從業務類型來看,好比金融或是政務容災合規這類業務,咱們會進行全鏈路審計,包括字段加密,同時也會就全球異地容災、就近訪問的原則優化 TDSQL-C 的產品能力。
最後是會在TDSQL-C產品裏集成AP的能力,咱們如今正在開發一款列存產品,內置到TDSQL-C裏,在本地用列存來啓動整個場景加速。
騰訊雲數據庫技術總監騰訊雲數據庫CDB、TDSQL-C數據庫內核研發負責人。騰訊雲數據庫技術總監,騰訊雲佈道師,MySQL架構師,現騰訊雲架構平臺部雲原生數據庫內核研發團隊技術負責人,Mariadb 基金董事會 & Mariadb 社區版本開發成員,專一於MySQL內核開發和相關架構、產品化工做。