億萬人搶10億紅包的數(shù)據(jù)監(jiān)控,如何實(shí)現(xiàn)業(yè)務(wù)零資損?
一、什么是HTAP
1、OLTP與OLAP
在介紹HTAP概念之前,請(qǐng)?jiān)试S我先介紹一下另外兩個(gè)概念——OLTP和OLAP,這兩者在數(shù)據(jù)庫領(lǐng)域是很重要的應(yīng)用場景的劃分。
OLTP數(shù)據(jù)庫承載的應(yīng)用通常是高并發(fā)、高吞吐、高可用的,應(yīng)用SQL很簡單(大部分都是點(diǎn)查點(diǎn)寫),但這種應(yīng)用對(duì)數(shù)據(jù)的實(shí)時(shí)性、一致性要求很高,對(duì)查詢時(shí)間延遲很敏感,一般要求是幾毫秒以內(nèi)。
相反地,OLAP數(shù)據(jù)庫承載的應(yīng)用的SQL通常會(huì)比較復(fù)雜(多含Join、GroupBy或SubQuery等復(fù)雜語法),所涉及到都是大范圍的數(shù)據(jù)讀取,數(shù)據(jù)量可能是百萬千萬,甚至億,所以這種SQL查詢延時(shí)比較大,但應(yīng)用并發(fā)不高。
由于OLTP與OLAP這兩類數(shù)據(jù)庫所應(yīng)對(duì)的場景的巨大差異,因此兩者在查詢優(yōu)化策略、數(shù)據(jù)組織方式與物理存儲(chǔ)結(jié)構(gòu)都會(huì)不一樣。在企業(yè)內(nèi)部,OLTP與OLAP一般都是獨(dú)立的兩套系統(tǒng)。所以,業(yè)務(wù)上常見的做法,就是配置一條數(shù)據(jù)同步鏈路,把OLTP數(shù)據(jù)庫每天產(chǎn)生新數(shù)據(jù)同步到OLAP數(shù)據(jù)庫,以方便進(jìn)行做統(tǒng)計(jì)分析的工作。
舉個(gè)例子,我們?cè)诤旭R鮮生用手機(jī)APP做商品查詢、下訂單和付款,這就是OLTP的業(yè)務(wù)。盒馬鮮生將MySQL產(chǎn)生的數(shù)據(jù)通過阿里集團(tuán)數(shù)據(jù)同步工具(精衛(wèi)同步、云梯等)導(dǎo)入到ODPS平臺(tái)(阿里集團(tuán)Hadoop平臺(tái)),進(jìn)行每天的庫存結(jié)算對(duì)賬、各渠道銷售額統(tǒng)計(jì)等,這都是業(yè)務(wù)里的OLAP業(yè)務(wù)。
業(yè)務(wù)上將OLTP數(shù)據(jù)復(fù)制一份并導(dǎo)入到給OLAP,達(dá)到OLTP與OLAP相互隔離的效果,這個(gè)方案很通用,但這有一個(gè)代價(jià)--應(yīng)用的開發(fā)人員要額外負(fù)責(zé)承擔(dān)這些數(shù)據(jù)同步鏈路穩(wěn)定性的保障性工作,那必然會(huì)帶來其它很多不可忽視的問題。
首當(dāng)其沖的是數(shù)據(jù)質(zhì)量的下降以及運(yùn)維成本的上升。業(yè)務(wù)以后每加一個(gè)新的數(shù)據(jù)庫或新增一張表,表就要新配一條數(shù)據(jù)的同步鏈路,像盒馬已經(jīng)有幾十個(gè)業(yè)務(wù)同步鏈路、幾百張表,這樣數(shù)據(jù)同步鏈路的維護(hù)成本很高。
比如,某個(gè)需求需要給某個(gè)表加個(gè)列、改列名等DDL操作,同步鏈路的工作都需要暫時(shí),等到完成了才能重新開始。這中間的過程容易遺漏導(dǎo)致故障。
一般來說,根據(jù)數(shù)據(jù)量的大小,同步系統(tǒng)會(huì)有分鐘級(jí)、小時(shí)級(jí)甚至天級(jí)的時(shí)間延遲。因此,同步后的數(shù)據(jù)的時(shí)效性是比較差的。
同步鏈路的上下游系統(tǒng)一般眾多,如果中間某一個(gè)系統(tǒng)因?yàn)槌绦駼ug導(dǎo)致數(shù)據(jù)丟失或不可用,就可能會(huì)直接產(chǎn)生嚴(yán)重的數(shù)據(jù)故障。這對(duì)業(yè)務(wù)的穩(wěn)定性帶來很大的風(fēng)險(xiǎn)。
此外,同步鏈路上下游各系統(tǒng)不一定兼容MySQL協(xié)議,這樣開發(fā)人員還可能要修改業(yè)務(wù)代碼適配這類系統(tǒng),從而帶來額外的開發(fā)成本。
為了解決這一系列的問題,HTAP數(shù)據(jù)庫就剛好可以派上用場。
2、HTAP簡介
HTAP數(shù)據(jù)庫簡單理解就是OLAP業(yè)務(wù)和OLTP業(yè)務(wù)都統(tǒng)一地在一套數(shù)據(jù)庫系統(tǒng)里內(nèi)完成。HTAP數(shù)據(jù)庫相對(duì)于傳統(tǒng)TP數(shù)據(jù)庫有TP所不具備的計(jì)算引擎,可以加快SQL執(zhí)行效率,而HTAP數(shù)據(jù)庫基于于傳統(tǒng)AP數(shù)據(jù)庫,又有AP所不具備的事務(wù)引擎,能做到所寫即可見,數(shù)據(jù)具有高時(shí)效性。
HTAP型數(shù)據(jù)庫可以具備哪些技術(shù)點(diǎn)呢?以下是我們對(duì)它的幾點(diǎn)總結(jié):
- TP/AP數(shù)據(jù)時(shí)效性:簡單說,就是業(yè)務(wù)的TP查詢和AP查詢看到總是“同一份數(shù)據(jù)”,不會(huì)有明顯的延遲。目前成熟的MySQL主備同步機(jī)制能保證數(shù)據(jù)延遲達(dá)到毫秒級(jí)或亞秒級(jí),用戶幾乎不會(huì)察覺,并且同步準(zhǔn)確性非常高,這比依賴于異步的外部數(shù)據(jù)同步系統(tǒng)的可靠性高很多;
- TP/AP 穩(wěn)定性與高可用:TP與AP兩者相互隔離,保證各自的穩(wěn)定可靠是HTAP的基本要求。要做到這一點(diǎn),可以基于獨(dú)立部署進(jìn)行物理隔離,也可以基于鏈路隔離以及備庫自動(dòng)容災(zāi)與切換方案進(jìn)行隔離;
- 跨業(yè)務(wù)庫的關(guān)聯(lián)查詢:跨業(yè)務(wù)庫關(guān)聯(lián)分析是HTAP常見場景,這要求HTAP查詢引擎能基于MySQL協(xié)議對(duì)接不同的類MySQL存儲(chǔ);
- 復(fù)雜SQL處理能力:除了要有強(qiáng)大的優(yōu)化器之外,MPP計(jì)算引擎和Streaming的計(jì)算引擎等加速SQL執(zhí)行的手段也必須要有的。
舉個(gè)HTAP的應(yīng)用例子。雙11主互動(dòng)及合伙人集能量的搶紅包活動(dòng),活動(dòng)在設(shè)計(jì)時(shí)已經(jīng)涉及到10多個(gè)業(yè)務(wù)的數(shù)據(jù)庫,活動(dòng)參與的任務(wù)有億萬紅包金額,所以這個(gè)活動(dòng)的業(yè)務(wù)邏輯是很復(fù)雜的。
在這樣復(fù)雜的場景中,業(yè)務(wù)如何做到快速的業(yè)務(wù)監(jiān)控以及資損防控是整個(gè)活動(dòng)***的技術(shù)挑戰(zhàn)。業(yè)務(wù)開發(fā)在進(jìn)行方案調(diào)研的時(shí)候發(fā)現(xiàn)DRDS HTAP這個(gè)產(chǎn)品,除了具有承載普通的OLTP的能力外,還具有跨多個(gè)數(shù)據(jù)庫做實(shí)時(shí)關(guān)聯(lián)分析的能力,非常符合業(yè)務(wù)的場景。
因此,開發(fā)同學(xué)直接將業(yè)務(wù)的監(jiān)控系統(tǒng)直接基于DRDS HTAP來搭建,***的結(jié)果超出他們期望。
DRDS HTAP不但幫助業(yè)務(wù)監(jiān)控平臺(tái)成功避免了10+起的資損故障的出現(xiàn),還具備了在1分鐘以內(nèi)完成多個(gè)業(yè)務(wù)庫實(shí)時(shí)對(duì)賬的能力,這相比于以前的離線方案,要將數(shù)據(jù)要上傳到數(shù)據(jù)倉庫里,像對(duì)賬這種操作需要在T+1、T+2的時(shí)間才能完成。
那么HTAP是如何達(dá)到這種效果的呢?下面一起來看一下DRDS HTAP的架構(gòu)和關(guān)鍵技術(shù)。
二、DRDS HTAP架構(gòu)與關(guān)鍵技術(shù)
下圖是DRDS HTAP的技術(shù)架構(gòu)圖,架構(gòu)圖分為兩層——引擎層和存儲(chǔ)層:
橙色的一層是存儲(chǔ)層,這層一般都是DRDS HTAP分庫分表的MySQL實(shí)例(云上就是RDS實(shí)例),通常每一個(gè)物理分庫都會(huì)配一主多備保證高可用。灰色的一層是引擎層, 引擎層使用集群提供高可用,集群的每一個(gè)節(jié)點(diǎn)都DRDS的無狀態(tài)的Server節(jié)點(diǎn)。Server里包含了用于處理MySQL協(xié)議的網(wǎng)絡(luò)模塊、查詢優(yōu)化器以及一整套TP引擎對(duì)應(yīng)的執(zhí)行算子。
通常業(yè)務(wù)OLTP類的SQL在Server的TP引擎內(nèi)完成全部執(zhí)行。但如果業(yè)務(wù)的SQL是OLAP類的復(fù)雜SQL,引擎層會(huì)將SQL對(duì)應(yīng)的物理查詢計(jì)劃發(fā)到右側(cè)Fireworks引擎進(jìn)行計(jì)算。
Fireworks是一個(gè)基于Spark 的具有DAG能力并行執(zhí)行引擎,它能夠進(jìn)行MPP計(jì)算及Streaming計(jì)算。Fireworks內(nèi)部的每一個(gè)Worker會(huì)主動(dòng)連用戶MySQL的備庫獲取數(shù)據(jù)并進(jìn)行計(jì)算。
DRDS HTAP 的Fireworks引擎的細(xì)節(jié)如下圖所示:
左右兩圖是一條SQL分別在TP引擎的對(duì)比圖。在TP引擎中,SQL采用單機(jī)單線程執(zhí)行策略。但是,在Fireworks引擎中,SQL的物理查詢計(jì)劃會(huì)被拆分為多個(gè)子任務(wù),然后分發(fā)到多臺(tái)Worker機(jī)器實(shí)施并行計(jì)算。
值得提及是,相比于開源Spark的Worker只能下推PROJECT/SELECT兩種算子,F(xiàn)ireworks的Worker接收到的物理執(zhí)行計(jì)劃是被DRDS優(yōu)化器進(jìn)行過優(yōu)化的。
因此,一些常見的PROJECT/SELECT/JOIN(分庫內(nèi)的JOIN)/AGGREATION(分庫內(nèi)的AGG)/SORT等算子操作,都會(huì)被DRDS優(yōu)化器盡可能下推到物理存儲(chǔ),這樣可以避免大量的中間數(shù)據(jù)的網(wǎng)絡(luò)開銷以及本地計(jì)算開銷,從而使MPP引擎執(zhí)行得到加速。
對(duì)于有一些需要跨多個(gè)分庫分表讀取數(shù)據(jù)才能完成的查詢, Worker機(jī)器都會(huì)采用多線程并行掃描單個(gè)分片數(shù)據(jù),以避免查詢時(shí)間大量耗在網(wǎng)絡(luò)IO上 。
再說一下DRDS HTAP Streaming的引擎,DRDS HTAP的Streaming引擎是在Spark Streaming的基礎(chǔ)上開發(fā)的。但我們?cè)趯park Streaming引入DRDS HTAP體系過程中,對(duì)Streaming的穩(wěn)定性與可靠性做了很多優(yōu)化工作。
例如,DRDS HTAP引入了RocksDB作為Streaming的State Store,并實(shí)現(xiàn)流計(jì)算任務(wù)中間關(guān)態(tài)的自動(dòng)容災(zāi)與恢復(fù)。又如,DRDS HTAP基于MySQL的Schema的時(shí)間戳列實(shí)現(xiàn)輸入流。
這樣用戶在DRDS HTAP可以使用標(biāo)準(zhǔn)的Streaming SQL語法完成諸如 Streaming-Streaming JOIN常見Streaming計(jì)算操作。業(yè)務(wù)開發(fā)也不再需要像使用開源的Streaming引擎(如Flink)那樣,需要自己配置復(fù)雜數(shù)據(jù)同步鏈路,從而能給用戶使用帶來極大的方便。
在HTAP里保證業(yè)務(wù)TP和AP查詢穩(wěn)定及高可用是非常重要的,DRDS為達(dá)到這個(gè)目標(biāo),采用了查詢鏈路隔離的技術(shù)方案。下圖是鏈路隔離方案的架構(gòu),分為引擎層和存儲(chǔ)層:
在存儲(chǔ)層默認(rèn)用MySQL的一主多備來實(shí)現(xiàn)。像TP引擎會(huì)默認(rèn)只訪問主庫,這樣數(shù)據(jù)可以保持是保持?jǐn)?shù)據(jù)一致性。而像Fireworks引擎默認(rèn)只允許訪問應(yīng)用的備庫,這樣業(yè)務(wù)在存儲(chǔ)層AP流量和TP是天然的物理隔離,保證相互不受干擾。
由于備庫承載的是OLAP類的SQL, SQL通常有相當(dāng)?shù)膹?fù)雜性,備庫被打垮是高概率事件,所以,DRDS HTAP能在多個(gè)備庫之間實(shí)施自動(dòng)的容災(zāi)和切換,這樣就算一個(gè)備庫宕機(jī)了,另一個(gè)備庫也可以繼續(xù)提供服務(wù),從而高可用。
在引擎層,DRDS通常建議業(yè)務(wù)將OLTP流量用DRDS主實(shí)例來承載,業(yè)務(wù)的OLAP流量用DRDS只讀實(shí)例來承載,這樣業(yè)務(wù)的AP和TP業(yè)務(wù)就能在引擎上也能實(shí)現(xiàn)物理隔離,從而保證各自的穩(wěn)定性和高可用。
接下來看一下DRDS HTAP的查詢優(yōu)化器,下圖是查詢優(yōu)化器的架構(gòu),優(yōu)化策略是以RBO為主,CBO為輔的策略。優(yōu)化過程可以分為三個(gè)階段:
- PreOptimizer,Sql的很多Rewrite操作(例如, SubQuery Unnesting/Constant Folding等)會(huì)在這個(gè)階段完成,產(chǎn)生出一份經(jīng)過簡單SQL改寫的邏輯計(jì)劃;
- Optimizer,這個(gè)階段優(yōu)化器會(huì)進(jìn)行很多常見算子優(yōu)化(例如,Predicate Inference /Operator Pushdown/Column Pruning/Join Cluster /Join Reorder等),然后再產(chǎn)生出一份經(jīng)過優(yōu)化后的邏輯計(jì)劃;
- PostOptimizer,這個(gè)階段DRDS HTAP作為分布式查詢引擎所特有的階段。這個(gè)階段中,優(yōu)化器會(huì)基于SQL的查詢條件進(jìn)行分庫分表的Sharding計(jì)算,然后再針對(duì)特定分片重做類似上一階段的Partition-aware的優(yōu)化操作。
原則上,優(yōu)化器會(huì)盡可能地算子下推到物理存儲(chǔ),這樣可以大大減少引擎成本的執(zhí)行壓力以及中間數(shù)據(jù)的網(wǎng)絡(luò)傳輸代價(jià),從而提升執(zhí)行效率。
對(duì)于一些諸如必須要跨多個(gè)物理分片的或跨多個(gè)邏輯庫才完成計(jì)算的算子(如跨庫JOIN), 它們沒法下推物理存儲(chǔ)的,優(yōu)化器會(huì)自動(dòng)采用MPP的執(zhí)行策略,直接將物理計(jì)劃發(fā)給Fireworks引擎做MPP計(jì)算。
三、DRDS HTAP功能演示
1、跨業(yè)務(wù)庫的MPP查詢
在電商場景,業(yè)務(wù)系統(tǒng)里為了降低耦合性, 通常被會(huì)拆分成很多子系統(tǒng)。下圖就是模擬電商場景分別對(duì)交易庫、商品庫、用戶庫進(jìn)行關(guān)聯(lián)查詢的示意圖,各個(gè)子系統(tǒng)會(huì)使用單獨(dú)MySQL實(shí)例(即RDS實(shí)例)進(jìn)行存儲(chǔ):
一旦業(yè)務(wù)要搞營銷活動(dòng),如雙11大促、發(fā)紅包等,應(yīng)用的邏輯必然會(huì)涉及到多個(gè)數(shù)據(jù)庫實(shí)例的讀寫,由于MySQL本身是不能支持跨實(shí)例級(jí)別的關(guān)聯(lián)聚合查詢的,這會(huì)對(duì)業(yè)務(wù)后臺(tái)的數(shù)據(jù)分析、監(jiān)控、對(duì)賬等場景會(huì)帶來很大的麻煩,而使用DRDS HTAP則可以解決這個(gè)問題。
DRDS對(duì)于每一個(gè)RDS數(shù)據(jù)庫會(huì)統(tǒng)一抽象成邏輯庫的概念,簡單理解,就是會(huì)為每個(gè)庫生成一份配置信息和元數(shù)據(jù),在整個(gè)過程中用戶本身并不需要做任何數(shù)據(jù)導(dǎo)入或數(shù)據(jù)同步的操作。
基于這一層邏輯庫的抽象,普通用戶可以如同在單機(jī)MySQL一般地隨意執(zhí)行跨DRDS數(shù)據(jù)庫的關(guān)聯(lián)分析查詢,并且不需要對(duì)業(yè)務(wù)的數(shù)據(jù)庫任何其它改造,帶來極大的使用便利。
業(yè)務(wù)將多個(gè)RDS的數(shù)據(jù)庫(不做分庫分表的拆分)接入DRDS后,當(dāng)其中某個(gè)業(yè)務(wù)數(shù)據(jù)庫因業(yè)務(wù)發(fā)展了,單機(jī)RDS無法承載并需要做分庫分表時(shí),那DRDS的所有拆分的細(xì)節(jié)會(huì)隱藏在一個(gè)邏輯庫之下。
這一過程本身應(yīng)用是透明的,因此,業(yè)務(wù)后臺(tái)的分析應(yīng)用的SQL也不需要做改造, 從而避免了大量的SQL改造成本。
為了演示方便我已經(jīng)提前將交易庫、用戶庫、商品庫的表信息建好。其中交易庫和用戶庫分別在RDS A上,商品庫在RDS B上。右邊的SQL是一條跨三個(gè)業(yè)務(wù)庫做JOIN SQL。
首先我分別登到RDS A和 RDS B的信息,可以看到上面數(shù)據(jù)庫的信息。RDS A有交易庫和用戶庫,RDS B有商品庫。再通過命令登錄到DRDS里,可以看到三個(gè)庫都在同一個(gè)地方。***會(huì)出現(xiàn)一個(gè)結(jié)果,這就是我要演示的跨多個(gè)業(yè)務(wù)庫進(jìn)行復(fù)雜查詢的場景。
在實(shí)際場景中SQL會(huì)更為復(fù)雜,比如說盒馬聚合查詢的SQL,如果要用以前那種方案,業(yè)務(wù)肯定要導(dǎo)到統(tǒng)一的數(shù)據(jù)倉庫才能執(zhí)行,現(xiàn)在在DRDS HTAP上只冉一條跨Schema的SQL查詢就可以完成,這樣在保證用戶子系統(tǒng)獨(dú)立性的同時(shí)給實(shí)時(shí)分析帶來了很大便利。
2、Streaming Join
再看一下Streaming引擎的功能演示,這里要演示的場景是大寬表。很多應(yīng)用在數(shù)據(jù)庫表設(shè)計(jì)的時(shí)候會(huì)遵守一些標(biāo)準(zhǔn)的設(shè)計(jì)范式。
比如,用戶購買下單的行為會(huì)將用戶的詳情、商品的詳情與用戶下單的行為用三張不同的表存儲(chǔ),用戶后臺(tái)做數(shù)據(jù)分析的時(shí)候會(huì)通過JOIN打成大寬表,這樣做方便做上鉆分析或下鉆分析。
我要模擬的場景是怎么使用流JOIN來打大寬表,Streaming很適用用于跟時(shí)間強(qiáng)相關(guān)的JOIN查詢。例如,每天都要查一下最近一天的交易量、訂單量的新增數(shù)目等。整個(gè)演示場景先是假設(shè)T1跟T2表是已經(jīng)存在的表,再額外建一張結(jié)果表,結(jié)果表是可以用來固化做流式業(yè)務(wù)的結(jié)果。
我開始模擬一個(gè)普通用戶在DRDS HTAP上使用Streaming JOIN。首先會(huì)在CERATE STREAM上建設(shè)T1和T2,***使用JOIN建T1 JION和T2 Stream。***將流結(jié)果寫入結(jié)果表中。
看一下SQL的具體操作,先使用命令執(zhí)行建了兩個(gè)流T1和T2,再建一個(gè)T1和T2 JOIN的流。現(xiàn)在模擬向T1、T2引入數(shù)據(jù),你會(huì)發(fā)現(xiàn)有JOIN的結(jié)果出來。這樣的好處在于這種結(jié)果突然固化業(yè)務(wù)做查詢可以非常快速,因?yàn)椴恍枰僮鲋虚g的計(jì)算。
四、DRDS HTAP使用場景與限制
沒有數(shù)據(jù)庫能適用所有的業(yè)務(wù)場景,DRDS HTAP同樣也是。DRDS HTAP適用AP類場景(TP類場景這里先忽略)主要有兩個(gè):
- 那些低并發(fā)且對(duì)時(shí)延要求不是特別高的應(yīng)用,特別有跨多個(gè)業(yè)務(wù)庫、跨多個(gè)表進(jìn)行實(shí)時(shí)分析的場景;
- 基于時(shí)間做流式JOIN的場景,例如事實(shí)表的流Join或者維表和事實(shí)表的流Join也適合用DRDS HTAP來使用。
但是OLAP的查詢場景是多種多樣的,還有很多查詢場景對(duì)于DRDS HTAP還不太適合, 比如,常見的全文快速檢索、AdHoc等查詢場景。
目前,DRDS HTAP在公有云已經(jīng)以分析型只讀實(shí)例的方式向用戶開放。但DRDS HTAP后續(xù)會(huì)在技術(shù)層繼續(xù)不斷優(yōu)化,以支持更多更復(fù)雜的在線場景與分析場景。
講師介紹
梁成輝(城璧),阿里數(shù)據(jù)庫事業(yè)部技術(shù)專家,阿里分布式數(shù)據(jù)層中間件TDDL、云產(chǎn)品分布式關(guān)系型數(shù)據(jù)庫服務(wù)DRDS技術(shù)負(fù)責(zé)人。曾多次擔(dān)任數(shù)據(jù)層穩(wěn)定性負(fù)責(zé)人并保障雙十一TDDL & DRDS的穩(wěn)定性,目前主要聚焦在DRDS HTAP的技術(shù)研發(fā),致力于提供云上OLTP與OLAP一體式解決方案。