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