賀TDSQL喜提286萬QPS!本文回顧了它的十年鍛造之路

導讀:2017年,在英特爾、騰訊金融分佈式數據庫TDSQL團隊的共同見證下,TDSQL採用英特爾提供的高端平臺,跑出了創造歷史的最快性能數據——峯值286萬QPS。相比於上一代處理器,性能提升了近4倍,是32核/220GB實例的38倍,TDSQL正在打造數據庫領域的“超音速戰機”。2017年12月3日,騰訊TEG計費平臺部技術總監潘安羣在【DBAplus數據庫年終盤點大會】上分享了TDSQL的十年鍛造與開創之路。

 

今天在座的大部分嘉賓都是Oracle的專家,在Oracle的高可用、數據安全性等方面有着非常深厚的經驗,而我所在的騰訊公司,在關係型數據庫的使用場景下,基本還是以MySQL這套開源產品爲主。

 

而MySQL這套開源產品,與Oracle這類成熟的商業產品在使用上或者說理念上有着很大的不同,所以我在這裏會分享一下我所負責的分佈式數據庫產品TDSQL的十年研發運營之路,希望能給大家帶來不一樣的思路。


分享大綱:

  • 騰訊十年數據庫技術發展之路

  • TDSQL核心特性

  • 分佈式水平擴展

  • 騰訊內部及部分客戶的部署實踐

 

騰訊數據庫技術發展之路


我來自騰訊TEG計費平臺部,一開始負責公司整個計費體系的存儲系統研發,現在主要負責TDSQL數據庫的研發。這是我們產品的幾個發展階段:

01.jpg


我是2007年進入公司的,在此之前公司業務是一個野蠻生長階段,所以騰訊在數據庫的高可用、安全性方面考慮不多,到了2007年左右,業務經歷了第二次騰飛之前的一個平穩階段。

 

趁這個時機,團隊啓動了一個7*24高可用服務項目,目標就是保證計費等公司級別敏感業務高可用、核心數據的零流失、核心交易的零錯賬。這也是TDSQL的前身。

 

當時提出的解決方案更多還是在應用層解決,兩個DB之間數據如果不同步,則會在業務層鎖定,在出現故障時做主備切換,並讓沒有同步完數據的用戶交易不可用,其它用戶正常交易。按照CAP原理來理解就是:當故障(P)出現時,我們犧牲少數用戶的可用性(A),來保證100%的數據一致性(C)。

 

在業務層做有一個非常大的好處——能夠知道鎖什麼樣的數據,但如果當時在數據庫層面做的話,必須考慮到業務會涉及到很多張表的數據,非常不好做。

 

這裏面最大的弊端就是——對應用層來說耦合度太高了,包括數據層的容災,比方說主DB異常了要去切換到備機時,什麼時候檢測故障?什麼時候是真的故障了?什麼時候切換?怎麼做切換邏輯?這個邏輯是業務開發人員控制的,所以落地時間週期很長。因爲一個系統完成改造,並通過多次現網演練最終到達穩定且符合預期,需要非常長的時間才能搞定,而我們系統又非常多,是一個非常艱難的過程。

 

到了2009年,考慮到這樣的高一致性解決方案易用性並不好,我們基於類似思路做了一套KeyValue系統,這比研發一套SQL系統要簡單很多,但依然有一個問題,KV系統不像SQL是標準化的東西,而且功能沒有SQL豐富,所以業務系統從SQL遷移到KV存儲,相當於存儲架構都改了。而我們線上業務是7*24服務的,所以改造及遷移工作量也比較大,推廣時間週期依然長。


所以很自然地,在2012年左右,我們就想做一套基於SQL的分佈式數據庫,取名TDSQL,目標就是讓數據庫來解決高可用、數據一致性、水平伸縮這些問題,而讓業務系統只需要關注業務邏輯。

 

2014年騰訊投資了微衆銀行籌備,它的定位是要做一家互聯網金融科技銀行,所以一開始確定架構是基於互聯網架構去做的。在對比了很多公司內外多個數據庫產品方案後發現,TDSQL剛好跟他們的場景是比較符合的,在高可用、數據一致性方面比較切合金融行業的需求,所以整個微衆銀行的核心交易系統所有的數據庫全部都是基於TDSQL,在銀行核心交易系統裏用這樣的架構在無論在當時還是現在來看,都還是開創性的。

 

在微衆成功落地投產後,我們希望我們的產品能爲更多金融機構提供服務,所以在15年在騰訊雲上也發佈該產品,現在我們提供公有云PaaS服務,也提供私有云產品。

 

以上就是騰訊十年的數據庫技術發展之路,接下來是今天分享的重點,我會先從TDSQL核心特性開始,然後講講分佈式水平擴展,最後分享在騰訊內部以及在部分客戶的部署實踐。


一、核心特徵


開源MySQL的玩法跟Oracle的確實有很大的差距,Oracle看起來就是一個高富帥,而MySQL看起來怎麼也是一個經濟適用男。例如我們支撐的業務以及客戶,清一色的X86服務器,網絡也是普通的專線網絡,還是很經濟實惠的。

 

所以有些傳統企業的客戶跟我們交流,問如果一臺機器掛了怎麼辦?誇張一點來說,就是這臺服務器咱就不要了,但這在Oracle生態下是不可能發生的事情。所以基於機器壞了就不要了的理念,在容災方面上的設計就很不一樣了。

 

此外,Oracle的功能確實非常強大,所以很多傳統的運營商、×××過於依賴數據庫,把大部分的邏輯都放在數據庫層面,讓數據庫搞定,但MySQL很多時候搞不定這樣的事情,所以互聯網對數據庫的依賴沒有那麼重,很多功能還是在業務層面做。

 

那像開源體系比較突出的一個問題是什麼?就是坑特別多,在規模小的時候,可能問題不突出,一旦規模上去了,各種問題就蜂擁而至。官方團隊對問題或Bug的響應是比較慢的,所以很多問題得需要自己去解決;而Oracle作爲一家商業公司,相對來說就要好很多,基本上客戶出了什麼問題,都能比較快速的響應並協助解決。

 

所以這也是我們爲什麼將TDSQL在騰訊雲上開發出來的一個目的,就是希望TDSQL在近十年在騰訊海量數據運營下走過的彎路、以及解決的問題,在其它團隊不要再走一遍。

 

剛開始我們是定位金融這一塊,這當中有幾個問題必須要解決,一是高可用問題,二是數據可靠性、零丟失的問題。因爲之前在行業內做分佈式數據庫的人認爲,MySQL體系做不到數據零丟失或者是主備之間數據的一致性,但其實這個東西是沒什麼問題的,是完全可以做到的,看看我們是怎麼做這個點的。

02.jpg

圖:TDSQL核心架構

 

這是TDSQL的架構,現在分佈式架構一般分爲三個核心模塊,第一模塊是數據節點(上圖右下角),通常是一主兩備的方式。上面的兩個模塊組成調度系統,暫時是用ZooKeeper來做元數據管理。第三模塊是接入計算層,當發生故障時主備切換和對路由的更新都在網關層面上做。上面的調度系統還包括負責監測故障、故障切換的操作,以及分佈式場景下的擴縮容任務管理等,此外包括一些複雜SQL的重新以及計算工作。這是大體的核心架構。

 

1.複製

主備數據複製方式

我們再從右下角的Set講起,通常是一主兩備的方式。現在MySQL是兩種複製模式,一種是異步複製,一種是半同步複製。但我們實測時會發現問題,當主備之間同步超時時,半同步複製會由超時時間退化爲異步,這在金融場景下風險是比較大的。

 

按照CAP的原理,寧願犧牲一定的可用性也不願意把數據丟失,假設備機異常了,退化爲異步了,主機繼續交易。

 

如果此時主機再發生故障,數據庫層面很可能出現數據丟失,一旦數據庫層面出現數據丟失,事後要去修復是非常困難的,所以這種時候我們是不讓它退化,繼續強同步(可能交易失敗),當然在具體實現時會做調整,根據業務特性去做配置設定是否退化異步。兩個備機裏只一個備機成功出現故障的概率會低很多,但不是說完全不會出現故障,但概率會低很多。

03.jpg


強同步更新流程

04.jpg


此外,在實際測試時做同城跨數據中心,這時的性能損耗會非常大,在MySQL 5.6版本性能損耗要降到原來的十分之一左右。現在5.7版本,在同步這裏官方做了一些異步化處理,性能下降問題已經好很多了,但依然會有性能損耗。所以在複製這塊,我們主要是去解決這兩個問題。剛纔講的一主兩備,兩個備機是都做強同步複製的。

 

半同步複製的不足

05.jpg


這是我們自己實測的結果,TPS下降非常快,所以我們做了兩個異步化處理。

06.jpg


經過這些異步化改造,在性能方面我們目前可以做到同城跨數據中心,5毫秒以內的延遲的情況下,能夠保證數據強同步和異步之間TPS不會下降,網絡單筆時耗可能會增加,但增加網絡延遲這是很正常的一種情況。也正是因爲有了強同步TPS不會下降的問題,所以我們也敢在業務大規模推行同城三中心架構,這個架構我在下面會再具體展開講。

07.jpg


SET結構

 

08.jpg


一般在同城三個數據中心之間一主兩備,這三個數據節點放在三個數據中心。在這種情況下,做強同步任何一個數據中心異常都能夠自動地切換過去,切換到另外的數據中心。所以這種可用度是非常高的。現在能夠承諾的是同城做強同步的話可以到RTO 40秒,RPO爲0。

 

在跨城通常還是做異步的同步,這裏如果需要強行切換到跨城異地的備份中心,會有數據丟失的風險。當然這也是概率的問題,我們認爲只有像在整個深圳三個數據中心全都掛掉了,或地震級別的災難纔會出現到這種情況,所以如果真要做跨城切換的情況下,有少量的數據丟失是可以接受的。

 

當然我們跟上海也可以做強同步,但有兩方面的因素:

第一是做了強同步以後單筆請求的網絡延遲就太大了,原來在同城做強同步可能只需要2-3毫秒的請求訪問,但跨城的話至少要30-40毫秒。而且一筆交易往往涉及上百次數據庫操作,這將是指數級的放大,會對前端業務系統的資源消耗非常嚴重,所以沒有必要爲了這樣非常小概率的事情讓平時的資源有這麼大浪費。

 

第二是跨城網絡穩定性會差很多,在騰訊同城內部數據中心是環形的專線網絡,三個數據中心當中任何一條專線斷了基本上不會有影響,所以同城的網絡穩定性非常高,但跨城的網絡穩定性就要差一些,而且經常有波動,所以我們也沒有必要爲了小概率事件做這樣的操作,所以跨城做異步,依然是成本與系統可用性之間的一個平衡。

 

剛纔我們在同城跨數據中心切換承諾的是40秒,爲什麼說是40秒呢?我們是分成了兩部分,第一部分20秒是故障檢測階段,第二部分是服務恢復階段,服務恢復階段主要是根據Raft協議選主、等待數據回放完成等工作,我們保守一點承諾是20秒完成,不過在我們實際運營環境中,通常3-4秒就可以完成這些工作。相對來說,服務恢復階段在業界是比較成熟的,理論也比較完備。

 

在這裏我想重點要提一下故障檢測階段。其實故障檢測是非常難的事情,首先我們都是基於X86的服務器,雖然現在服務器硬件一年比一年往上翻,性能越來越好,但實際上依然會有很多業務在上線時設計得不合理,每個用戶來的時候都會做全表掃描,有時你根本防不勝防,如果稍微沒注意放過去了就一下子把系統給沖垮了,整個數據庫節點表現就是不可用了。

 

那麼,在資源被消耗光的情況下要不要做切換?在業務看來,數據庫基本上是不可用的,理論上是需要切換的,但是你切換後,發現沒啥用,SQL請求裏面又把新主機壓垮了。

 

此外,我們現在普遍使用的SSD盤,SSD有一個問題是壽命的問題,壞也不是一下子突然壞了,這中間有一條曲線,IOPS和磁盤響應時間有一個逐漸變差的過程。那這種情況下怎麼切,在什麼時間點切換呢?

 

在故障檢測這個點上,目前來看很難有統一的一個理論說怎麼發現故障、怎麼去切換,這是非常難的事情,更多還是經驗方面的積累,我們秉承的原則還是:切換後,如果系統可用性能提升,才切,否則免切。這確實可以避免很多沒有意義的切換。


2.主備高一致性保障

數據高可用性的保障機制(恢復)

故障檢測時間是可以配置的,我們配置3秒鐘一次監測,大概要連續6次出現異常情況纔會去觸發切換,而且連續6次的情況下還要匹配到自己內部的邏輯——是不是切換過去就能夠解決問題,如果像剛纔那種因爲業務使用不當導致了系統數據庫不用的話切過去也沒什麼用,在這種情況下不會做無謂的切換。

 

如果有時候系統出了問題可能會引發連續的切換,連續切換對系統也沒什麼好處,比如說我們切換了一次後,配置在未來的一段時間不會做切換,用這樣的邏輯做判斷。

09.jpg


這裏是我們在服務恢復階段的示例演示。剛開始A是主機,B、C作爲備機,而且B稍微延遲一些,C備機數據更新一點,此時a+3這個事務,依舊是未提交成功的,此時如果A主機故障了,那麼調度系統會選擇C作爲新主機,B作爲C的備機,組成一主一備的Set。

 

此時,我們會優先考慮,A節點是否能快速恢復(如MySQL bug,或者網絡閃斷等),如果能,則對a+3事務Rollback後,作爲備機,繼續提供服務;如果A節點不能快速恢復(如磁盤故障,服務器故障),則需要重新找一臺服務器,通過物理備份+追Binlog的方式,快速構建一個新備機,儘可能地快速恢復爲一主兩備的三節點Set提供服務。

 

高一致性容災:如何保證沒有髒數據

10.jpg


整個切換流程是一個嚴謹的操作,每個操作是有順序的,否則可能會出現雙寫的情況,這都是靠切換流程來保障。

 

通常同城三中心架構,每個數據中心都是對等平等的。一旦因爲故障,導致主備發生切換,除非再次發生故障,我們不會主動切換回來,這是同城三中心高度對等架構的好處。

 

任何一箇中心的節點都可以提供主服務,這種更加標準化的部署,運維可以做到自動化操作,對運維管理的複雜程度要稍微低些。

 

可靠性保障體系

11.jpg

這是冷備系統,每天會做全量的鏡像,並實時做Binlog的增量備份,這些都會經過壓縮後存儲在分佈式文件系統上,以便客戶可以恢復到歷史某一個時刻的數據點。目前我們在公有云上默認提供30天的任意時間點回檔。

 

爲什麼需要每天做鏡像呢?還是爲了恢復的速度問題。比如說遊戲出現了重大Bug需要快速回檔,第二是DBA誤操作刪除數據了,這些情況都需要從冷備恢復。當然,每天一個鏡像在一些情況下恢復時間也會比較長,假設每天凌晨4點鐘做備份,但剛好在備份前一兩個小時數據被刪掉了,那這種恢復就需要用前一天凌晨4點的鏡像數據,外加追一天的Binlog日誌恢復,這個時間是比較長的。

 

在內部有類似事件的時候會有幾個點從流程上優化:

第一點,一旦發現出現刪數據的情況,無論是DBA誤刪還是因爲系統內部Bug,一旦報了故障過來,立馬申請新實例,並行開始恢復數據,不管最終會不會用上。

第二點,我們會有一個冷備驗證環境,專門用於驗證冷備系統及冷備數據的可用性。騰訊會有大量的數據庫實例,每天隨機挑選一些實例自動恢復,並跟現有生產環境去比對數據。我們要確保冷備備份出來的數據是可用的,我們通過這種隨機抽查的冷備驗證機制,確保整個冷備系統的可用性。


3.性能

性能指標:單節點

性能絕對數值本身沒什麼太大意義,不同的廠商可以用不同測試場景,發佈對自己產品有利的數據。這裏我想補充一點就是關於硬件。

 

硬件發展其實很快。大概兩年前,我們自己內部用一個代號爲Z3的服務器,大概1.3T SSD FusionIO卡。到了2017年年初,我們現在已經開始用上了TS85服務器,這種機型已經相當厲害了,是24個物理核,512G內存,4塊1.8T NVME SSD卡,我們把它做成RAID 0,在數據庫裏很少有人說數據盤是用RAID 0的,但在我們架構裏通常都是RAID 0。前提就是數據三副本,我們系統的可靠性及可用性不依賴單個副本,一個副本故障了就重新構建一個副本。

12.jpg


讀寫分離

  • 基於數據庫賬號的讀寫分離

13.jpg


  • 基於Hint的讀寫分離

14.jpg


二、分佈式集羣


1.水平擴展性

15.jpg


下面講一下分佈式實踐。TDSQL一開始是定位在騰訊內部做計費、金融支付這類場景,是常見的OLTP場景。考慮到OLTP場景,一個系統的實時交易數據量並不會超級大,所以我們採用預分片的策略,一開始把數據幫你做好邏輯分片,例如設置爲64個分片或者是128個分片,當然要做到1024個分片甚至更多都沒什麼問題,但通常來說用不了那麼多分片。

 

你想想,單節點基於當前硬件可用是6T存儲空間,如果達到128分片,就將近有大幾百個T,對交易系統來說數據量是絕對夠的。

 

爲什麼要做預分配呢?現在有很多數據庫是自動擴容的,或者一開始做了哈希,但這類也會面臨一個問題——數據大量地刪除,如果僅僅刪除一部分數據的話空間不一定會釋放。所以一開始做好預分配在運營管理上會有非常大的方便,比如說你刪除分區的話速度是非常快的,另外就是空間會立馬得到釋放,所以在運營層面會非常友好。

 

此外,有些表的數據沒有必要做分佈式,可能是配置表,所以會有廣播小表或者是NoSharding表,這樣做交易事務會非常方便。

 

三種數據Sharding方式

16.jpg


SQL支持

17.jpg


MySQL本身在複雜SQL場景下處理會比Oracle差一些,尤其是在數據分析方面。但通常來說,標準的聚合函數都是沒什麼問題,我們現在也支持基於兩階段提交的分佈式事務,但Join是有不同的。。

 

有很多場景下不讓做Join,直接禁止一些複雜Join SQL。這裏主要從系統可用性健壯性方面考慮,我們擔心一旦放開限制,客戶在自己測試環境測試,因爲數據量小,所以性能啥都完全OK,但在實際生產環境中,數據量一旦上去了,數據庫就扛不住,導致生產環境系統可用性降低,這是非常嚴重的問題。

 

如果後面萬兆網卡普及的話,情況可能會有變化,但目前情況下,複雜關聯查詢SQL帶來網絡帶寬消耗以及對中間節點存儲內存消耗是需要去考慮的,絕對不能因爲這些導致生產環境出現事故,所以我們前面限制非常嚴,存在風險的話都會限制住,讓你在開發、測試的時候就能夠發現、杜絕風險,避免承諾給你是可用的結果到最後發現不可用、線上容易出問題,否則對我們來說,承擔的風險是非常大的。

 

所以我們更加偏向於保守一些,而且儘量地把錯誤在前面開發測試階段發現,而不是到生產的時候才處理,當然我們也在逐步放開一些限制,在系統層面去做好控制、確保安全。


2.分佈式事務

18.jpg


分佈式事務最核心的點是異常處理。我們的分佈式事務是基於兩階段提交的。做分佈式系統最複雜的一個問題就是當出現網絡故障、網絡超時的情況時如何處理。

 

任何一筆網絡請求可能有三種結果:正確、失敗、超時。對於超時怎麼處理是最關鍵的,所以我們有一套測試環境,專門隨機模擬各種異常,包括網絡、服務器各種情況下,用於驗證我們分佈式事務機制的健壯性。

 

第二點是分佈式事務的死鎖檢測。我們在MySQL的鎖信息裏面增加上了分佈式事務ID,在出現一定超時時間後,會主動去測試整個集羣裏面是否有多個事務之間佔用的鎖構成了環,也就是死鎖,一旦出現死鎖,我們會根據我們的策略,Kill掉某個事務,確保其它事務正常執行。

19.jpg


分佈式事務性能對比

20.jpg


分佈式事務不可避免是對性能的對比,目前我們的性能是損失大概是在30%左右,這是一個相當不錯的性能了。而且TDSQL也是通過TPCC測試驗證的。

 

兩種模式

我們也提供了兩個版本,一個是分佈式版本,一個是No-sharding版本,如前面提到的在分佈式版本里SQL會有一些限制,No-sharding提供的是完全SQL兼容的高可用方案。

21.jpg


TDSQL整體視圖

前面也提到了MySQL和Oracle對比生態系統不夠完善,Oracle的配套工具相當完善,此外就像Oracle有很多專家,客戶出了什麼問題,ITPUB發個帖子說有沒有專家過來幫我解決問題,就會有很多專家過來解決,在MySQL體系下還沒有這樣的方法去處理。

 

確實周邊配套、內部監控的處理包括本身的優化沒有提供很好的工具,所以在這方面我們也投入了很大的精力。如果做產品化的話,這是非常重要的過程,無論是公有云還是私有云,目前提供給騰訊內部的其它業務也是雲方式,整個這一套東西部署進去就能實現DBaaS服務,你可以直接購買TDSQL的實例應用。

22.jpg


三、部署實踐


最後講一下我們經常用的部署實踐。

 

1.同城主從雙中心

23.jpg


同城雙中心沒有什麼很大的借鑑,這是微衆銀行最開始的架構。微衆銀行是全國第一家互聯網新籌民營銀行,所以是從零開始建構的,最開始的時候同城只有兩個數據中心,最大的問題是出了故障時彼此都不知道到底是誰出了故障。


比如說網絡數據中心的網絡斷了不知道誰出現了故障,所以同城不能自動切換,系統不知道誰出了問題,就需要人工去判斷的。

 

但同一個數據中心內是可以做到切換的,像微衆銀行每個季度會做演練,因爲兩邊都有數據中心、應用程序,所以每季度會跟監管機構申請窗口時間,比如說5分鐘把業務停掉,等到數據全部傳輸到備中心以後驗證是不是完整可用的。通過演練的方式確保備中心是可用的。

 

但今年微衆銀行已經徹底換成同城三中心架構,任一中心都可以切換,數據的架構看起來比較簡單,可用性會好很多。這確實對成本的要求比較高,建設一個符合監管規範的金融級數據中心成本相當高,所以很多客戶不願意爲了你再去搞多一個數據中心,只有微衆是做類似金融科技纔會搞三中心的架構。

 

微衆當時評估成本,當它的賬戶量達到2000萬以上時,單用戶成本能夠達到原來傳統IOE架構的十分之一左右,越到後面用戶量越增加就越划得來。

 

2.兩地三中心

24.jpg


考慮到客戶當前的數據中心及成本情況,更多的是客戶會做兩地三中心的架構,比如說深圳兩個中心一主兩備,通常在主數據中心會加一個備機,這個備機是爲了做異步複製。

 

因爲異步複製跟強同步複製本身上來說沒有區別,所以異步大部分情況下數據也是最新的,如果真的主機出現故障要切換時會去優先選擇本地備機,避免跨數據中心切換,如果數據確實跟其它的強同步節點最新的數據是一致的,當然沒有異步節點也是沒有什麼問題的。

 

3.兩地四中心(自動化切換的強同步架構)

25.jpg


在騰訊內部通常就是這種部署架構,基本上能夠滿足大部分客戶的需求。同城三個數據中心對等,任何數據中心及故障都能40秒內切換,數據零丟失,性能也穩定可靠,所以對業務來說是非常友好的。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章