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