騰訊云原生數(shù)據(jù)庫TDSQL-C(Cloud Native Database TDSQL-C,TDSQL-C)是騰訊云自研的新一代高性能高可用的企業(yè)級分布式云數(shù)據(jù)庫。融合了傳統(tǒng)數(shù)據(jù)庫、云計算與新硬件技術(shù)的優(yōu)勢,100%兼容MySQL和PostgreSQL,實現(xiàn)超百萬級QPS的高吞吐,128TB海量分布式智能存儲,保障數(shù)據(jù)安全可靠。
本文由騰訊云數(shù)據(jù)庫高級工程師唐颋為大家詳細(xì)解讀TDSQL-C PostreSQL的高可用特性。
TDSQL-C PG版產(chǎn)品簡介
TDSQL-C PG版是一款基于計算、存儲分離的云原生數(shù)據(jù)庫產(chǎn)品。相比于傳統(tǒng)的PG,我們將PG數(shù)據(jù)庫集群分為計算節(jié)點和存儲節(jié)點兩部分來進(jìn)行獨立的管理和部署。其中在計算節(jié)點方面,一個集群內(nèi)所有計算節(jié)點會共用同一份遠(yuǎn)程數(shù)據(jù)存儲,主備之間日志只會用于更新緩存,從而擺脫傳統(tǒng)PG下主備日志同步時影響集群可用性的問題。
在存儲方面,TDSQL-C PG版獨立部署的存儲服務(wù)以Segment Group為基本單元來管理數(shù)據(jù)庫對應(yīng)的數(shù)據(jù)存儲,一個集群下的數(shù)據(jù)會拆分到多個Segment Group,Group中的Segment又可以分布到多個不同存儲服務(wù)上進(jìn)行管理,從而實現(xiàn)通過擴展存儲服務(wù)來完成數(shù)據(jù)庫存儲空間擴展,擺脫傳統(tǒng)PG數(shù)據(jù)庫在存儲數(shù)據(jù)容量上受限于單機磁盤空間大小的問題。
另外,在數(shù)據(jù)庫備份回檔功能上也是拆分到Segment Group維度上來實現(xiàn),Segment Group可以并發(fā)進(jìn)行備份和數(shù)據(jù)回檔,從而極大的縮短數(shù)據(jù)庫備份回檔耗時。
TDSQL-C PG版
高可用性能改進(jìn)
基于上述架構(gòu)在產(chǎn)品特性上,我們的遠(yuǎn)程存儲使用多副本機制解決了數(shù)據(jù)可靠性問題,同時計算節(jié)點相互不依賴日志同步,從而解決了可用性問題,最終達(dá)到可靠性和可用性兼顧效果。在使用成本上,一個集群下不管多少個實例,都是共用同一份存儲,并且按照存儲實際使用量收費。相比于常規(guī)主備集群下每個實例都需要單獨占用存儲空間,我們極大的降低了集群的使用成本。
在最大存儲數(shù)據(jù)量上,存儲服務(wù)可以實現(xiàn)單獨水平擴展,從而使整個集群數(shù)據(jù)存儲量得到大幅度提升。另外,在數(shù)據(jù)庫集群計算能力擴展上,新增備實例都無需同步數(shù)據(jù),可以實現(xiàn)秒級快速擴展。最后,在數(shù)據(jù)庫的回檔操作中,我們是基于Segment Group并行回檔,可以將回檔速度可以提升到GB每秒。
基于此產(chǎn)品架構(gòu),我們在高可用方面又有哪些相應(yīng)改進(jìn)?
我們先看看在常規(guī)主備模式下的常見高可用方案。在常規(guī)主備模式下,主備都是通過數(shù)據(jù)流復(fù)制方式來完成數(shù)據(jù)同步,其中同步數(shù)據(jù)流復(fù)制模式下,主實例的每一次提交都要等到備實例完成日志落盤之后才能夠返回,這樣才能夠強行保證主備數(shù)據(jù)一致性。但同樣也帶來了,備實例異常時,會影響主實例可用性的問題。而在異步數(shù)據(jù)流復(fù)制模式下,主實例是可以不擔(dān)心備實例的日志落盤情況。這樣雖然可以避免可用性問題,但也會造成主備實例數(shù)據(jù)的一致性問題。
基于此,我們會使用額外的Warm Standby,和主實例之間保持同步數(shù)據(jù)流復(fù)制。同時我們的Warm Standby不會對外提供服務(wù),盡量減少Warm Standby實例影響主實例的情況發(fā)生,而其他提供對外服務(wù)的備實例則通過異步數(shù)據(jù)流復(fù)制方式來實現(xiàn)和主實例數(shù)據(jù)同步。當(dāng)主實例出現(xiàn)異常時,可以使用和主實例保持?jǐn)?shù)據(jù)強一致的Warm Standby實例來進(jìn)行備提主,快速恢復(fù)主實例可用性。之后我們會再異步進(jìn)行Warm Standby實例重建,最終將整個集群恢復(fù)成正常狀態(tài)。這種處理流程雖然盡可能保障了可用性,但仍然存在一些問題是沒有辦法解決的,例如Warm Standby實例雖然沒有提供對外服務(wù),但還是可能會存在比如機器、網(wǎng)絡(luò)等硬件故障導(dǎo)致不可用的風(fēng)險,從而影響主實例的可用性。
另外,Warm Standby實例重建也需要時間,當(dāng)其沒有完成重建時,如果新的主實例再次出現(xiàn)異常,就沒辦法快速恢復(fù)可用性。除此之外,一個不提供對外服務(wù)的Warm Standby實例也要占用資源,所以必不可少會帶來多余的成本開銷。
那么在TDSQL-C PG版計算存儲分離架構(gòu)下,這個問題是否有更好解決方式?得益于我們做了計算存儲分離,主備實例會使用同一份遠(yuǎn)端存儲數(shù)據(jù),它們之間不存在數(shù)據(jù)同步的前置依賴。而在數(shù)據(jù)可靠性方面,我們交由單獨存儲服務(wù)來實現(xiàn)。當(dāng)在主實例上進(jìn)行數(shù)據(jù)寫入時,我們會把日志發(fā)給存儲服務(wù),存儲服務(wù)完成日志落盤后,就可以返回響應(yīng)給客戶端,同時存儲服務(wù)再自己以異步日志回放方式去更新磁盤數(shù)據(jù),而備實例接收主實例日志只用于更新緩存,在異常時也可以直接使用遠(yuǎn)端存儲服務(wù)數(shù)據(jù)。這樣下來主備之間就沒有數(shù)據(jù)同步依賴,從而也就不存在備實例異常影響主實例情況。
另外在這個架構(gòu)下,也不需要額外Warm Standby實例。集群當(dāng)中,每個備實例都可以在既提供給業(yè)務(wù)使用的同時,也成為主實例異常時的備份。同時每增加一個備實例,不僅能夠提升集群整體讀取性能,也能夠更高地保證整個集群的高可用。當(dāng)主實例出現(xiàn)異常時,會選取任意備實例來做備提主操作,快速恢復(fù)主實例可用性。在備實例被提成主之后,得益于存儲計算分離架構(gòu),我們無需數(shù)據(jù)同步就能夠快速完成新的備實例補充。最后,會通過上層負(fù)載均衡的路由切換,來保證業(yè)務(wù)訪問數(shù)據(jù)鏈路正常,在極短時間內(nèi)將整個集群恢復(fù)成故障之前的樣子。
在產(chǎn)品能力方面,業(yè)務(wù)使用方也可以按照自己流量分布來設(shè)置備實例切換優(yōu)先級,從而盡可能減少異常時對于業(yè)務(wù)的影響。在內(nèi)部管控實現(xiàn)上,原來的高可用管控也就拆分成了獨立兩部分,其中存儲管控是負(fù)責(zé)存儲節(jié)點的高可用,它會負(fù)責(zé)對于基礎(chǔ)的存儲組件Store Node、內(nèi)部Segment存儲單元、以及備份回檔等模塊進(jìn)行健康狀態(tài)檢查及異常處理??傮w來說,其會站在存儲角度,來保證整個分布式存儲服務(wù)的可用性。在實例管控方面,更多是負(fù)責(zé)計算節(jié)點的可用性,它會通過多種手段去實時檢測計算節(jié)點健康狀態(tài)。當(dāng)出現(xiàn)某些涉及到存儲讀寫異常場景時,會結(jié)合存儲管控健康信息來綜合決策我們的高可用HA執(zhí)行邏輯,結(jié)合起來保證整個數(shù)據(jù)庫產(chǎn)品服務(wù)的高可用。
除了上述優(yōu)化,接下來還有已經(jīng)計劃的優(yōu)化空間,比如當(dāng)前做HA切換時,必不可免會涉及到時間重啟、主從切換這些操作,這些操作都會導(dǎo)致業(yè)務(wù)對實例的連接斷開。雖然目前通過上層負(fù)載均衡服務(wù)來避免切換影響業(yè)務(wù)訪問地址問題。但單一的負(fù)載均衡服務(wù)是沒辦法做到連接保持,所以需要驗方來做重連機制,才能夠在HA發(fā)生之后恢復(fù)對數(shù)據(jù)庫的訪問。現(xiàn)在有計劃在增加Proxy模塊來實現(xiàn)連接保持,從而解決HA時用戶連接斷開問題。再往前一步,Proxy加入也為后續(xù)實現(xiàn)自動讀寫分離等特性提供基礎(chǔ)。另外,跨可用區(qū)、跨地域容災(zāi)也在計劃中進(jìn)一步提升數(shù)據(jù)庫服務(wù)可用性特性。
保障業(yè)務(wù)高可用
在介紹完利用計算存儲分離架構(gòu)優(yōu)勢帶來的高可用優(yōu)化之后,接下來聚焦快速擴展這個產(chǎn)品特性給業(yè)務(wù)高可用帶來的價值。
在通常的在線業(yè)務(wù)服務(wù)上,最容易碰到的場景是超出預(yù)期的流量突增,從而給整個系統(tǒng)帶來非預(yù)期的請求壓力,這種壓力很容易會傳導(dǎo)到數(shù)據(jù)庫服務(wù)上,從而造成數(shù)據(jù)庫性能的瓶頸。出現(xiàn)這樣場景時,對于業(yè)務(wù)方來說,可能最迫切的需求就是快速加大數(shù)據(jù)庫實例規(guī)格,或者增加備實例來應(yīng)對數(shù)據(jù)庫壓力,解決業(yè)務(wù)可用性問題。這個時候數(shù)據(jù)庫實例擴展的耗時就會極大影響業(yè)務(wù)的可用性。
在常規(guī)主備模式下,加入一個新備實例或進(jìn)行主實例跨機遷移時,是需要串行完成兩個步驟:第一個是通過basebackup去同步數(shù)據(jù),另一個是同步后的數(shù)據(jù)恢復(fù)。這兩個步驟,尤其是同步數(shù)據(jù)耗時是和數(shù)據(jù)量的大小呈正比。例如用1TB數(shù)據(jù)量的一個數(shù)據(jù)庫來舉例,在機器帶寬為25G前提下,需要至少5分鐘才能完成數(shù)據(jù)同步,而伴隨著數(shù)據(jù)庫數(shù)據(jù)量越大,這一步花費時間會變得更長。另外在云上,一個宿主機上往往不只會部署一個數(shù)據(jù)庫實例,考慮到對于整個宿主機的影響,我們不可能滿帶寬進(jìn)行數(shù)據(jù)同步,所以真實時間往往會變得更長,這樣同時也就意味著我們恢復(fù)業(yè)務(wù)可用性的耗時會變得更長。
在TDSQL-C PG版產(chǎn)品下,這里會有什么樣改善?在TDSQL-C PG版產(chǎn)品下,我們的主備實例會共用遠(yuǎn)端存儲,這意味著新增實例時,只需要增加計算節(jié)點,而無需經(jīng)歷耗時最長的數(shù)據(jù)同步過程。同時不需要數(shù)據(jù)同步,就意味著集群數(shù)據(jù)量增長并不會導(dǎo)致整個耗時增加。整個新增實例耗時等同于啟動一個新的PG實例進(jìn)程。我們可以將整體的耗時縮小到秒級,以最快的速度來滿足業(yè)務(wù)對于快速擴展的需求。另外,TDSQL-C PG版最大是支持15個備實例,備實例可以按照業(yè)務(wù)需要分配到不同負(fù)載均衡組提供給業(yè)務(wù)使用,最大滿足業(yè)務(wù)對讀取性能的靈活要求。
基于以上特性,可以快速滿足業(yè)務(wù)對數(shù)據(jù)庫的性能調(diào)整要求,但在整個過程中,還需要依賴于業(yè)務(wù)方對于數(shù)據(jù)庫使用情況的監(jiān)控以及時的介入操作來完成擴容,從整體上來說,還是要靠人工來保證可用性。那么是否有更好方案可以在無需人工介入操作的情況來解決這種問題?答案就是Serverless。
Serverless是云原生發(fā)展的一種高級形態(tài),能夠充分展現(xiàn)云原生能力,讓用戶更專注于業(yè)務(wù)上,而無需關(guān)心資源情況。在Serverless模式下,我們計算節(jié)點性能會跟隨業(yè)務(wù)流量進(jìn)行自動調(diào)整,當(dāng)業(yè)務(wù)流量上升,對于數(shù)據(jù)庫計算資源需求增加時,會自動提高計算節(jié)點資源規(guī)格。而當(dāng)業(yè)務(wù)流量下降時,對于資源需求減少的時候,會自動降低計算節(jié)點的資源規(guī)格。
在存儲方面,TDSQL-C PG本身就是按Segment Group來分配存儲資源,當(dāng)發(fā)現(xiàn)現(xiàn)有的存儲資源不夠用時,就會自動新分配Segment Group來滿足業(yè)務(wù)對于數(shù)據(jù)存放的需求。從而在整個數(shù)據(jù)庫服務(wù)上,實現(xiàn)了資源自適應(yīng),用戶完全無需關(guān)注資源情況,避免需要人為介入才能保證業(yè)務(wù)高可用場景。另外在使用成本上面,Serverless是完全按需使用收費的。流量低時,實際規(guī)格低,費用自然也就跟著下降。相比于人為去調(diào)整實際規(guī)格,在費用上面也會有大幅度節(jié)省。