天天看點

DTS 及其在PG 資料庫生态中的應用

一、PostgreSQL 資料傳輸通道關鍵技術

(一)什麼是資料傳輸通道?

資料通道并不是一個很新的概念,很早以前就已經有人或者企業提出了。從資料庫的視角來看,資料通道是要去解決各個資料庫、資料平台還有資訊系統之間的資料連通性的題,然後來支援資料高速自由的流動。

資料通道建立之後,可以從TP 資料庫流轉到AP 資料庫進行分析;或者流轉到大資料平台,進行實時計算;或流轉到kv 上去做的cache;或從AP 資料庫再将分析結果流回到TP 資料庫,以便于支撐業務對統計資訊的查詢。

在一條資料通道上,流動的資料類型大概有兩種:

第一種,存量資料,存量資料不是實時産生的,比如說一些基礎的資訊資料。

第二種,增量資料, 增量資料是實時産生的資料。

DTS 及其在PG 資料庫生态中的應用

從另一個次元去劃分,資料通道上的資料會分成真實的資料和對資料描述的資料。拿資料庫來講,表結構或者說DDL 資訊,以及這張表對應的真實資料,作為資料傳輸通道,它就像我們的路一樣,越快越好,“快”就是資料傳輸通道的傳輸效率問題。

解決了在資料通道上的傳輸,傳輸效率之後,我們在資料通道上也應該提供一些ETL的能力,ETL 的能力可以做資料的清洗(比如非法的資料,把它清洗成合法的資料,寫入到這個目标端去)。或者對一些敏感的資料進行脫敏,再放到大資料的系統裡面進行分析。或者若幹張表的資料,在資料通道内部進行多表合并,然後再把它放到AP 的庫裡面分析。

做為一條資料通道,在資料品質産生了問題或者資料的鍊路出現了擁塞的時候,一定要有較強的資料保障能力。

(二)PostgreSQL 内置資料類型

PG 内置的資料類型:

資料通道要解決資料的傳輸問題,那麼就一定要有具體資料。

對于不同的DB 庫來講會有不同的類型, PG 提供了幾種基礎類型:數值型、字元型、二進制型、時間型、貝爾型、比特型等。

PG 除此之外還提供了增強的類型,比如地理位置、資訊類型、網絡型等。

系統ID 類型——tid ,tid 對PG 來講,是PG 的内置字段。在使用上,往往會對ctid 的錯誤使用,通過PK 或UK 或索引字段,查出來ctid,緊接着使用ctid 對表進行操作。這個使用方式其實是不太靠譜的,因為ctid 它代表的是這一行資料所屬的頁以及在頁内的偏移。PG 是通過copy of direct 實作的macc 機制,在查詢出來之後,這行資料的ctid 可能發生變化,如果我們固化了使用ctid,就會産生資料不一緻的問題。

在大部分的時候,因為我們是通過PG 的driver 實作的資料的讀取,是以不需要關注各種資料類型内部的存儲情況。如果要去看,比如說對Wal 的日志進行細膩度的分析,或者對一頁的資料進行細膩度的分析,可能就會需要了解每一個不同的類型在PG 内部的存儲的格式。

DTS 及其在PG 資料庫生态中的應用

(三)PostgreSQL 分區表

在讀取PG 資料的時候,資料通道裡面有兩種不同的資料的類型,一種是存量資料,一種是增量資料。

在PG 的資料庫裡面,對于存量資料的讀取分區表是一個非常獨特的case,分區表從PG10 開始,有兩個截然不同的表現,在PG10 以前,分區表是基于PG 的CHECK-IN HERIT 文法來實作,同時需要手動的在主表上建立trigger,這種方式實作比較脆弱。

實體表和邏輯表其實沒有明确的區分。

從PG10 之後,我們可以看得到PG 引入了partition by range 這樣的支援,支援

分區表的文法,在此之後PG 的原資料庫部分能夠明确的區分出來,哪張表是主表,哪張表是實體表。

比如下圖的例子,可以看得到logical table 它的relation kind 是p 它代表的是分區表,也就是說主表; physical table 1 它的relation kind 是r,代表的是實體表,就是一張正常的、普通的表。

DTS 及其在PG 資料庫生态中的應用

為什麼要區分主表和實體表?

因為在讀取全量資料的時候,對于一張分區表,我們希望讀取它實體表的資料,這樣會讀的快,而不去讀取主表的資料。

如果不能區分實體表和主表,那就既讀取了主表的資料還有實體表的資料,這個資料就會有大量的重複,相當于我們讀取了兩次。

(四)PostgreSQL 增量資料擷取

怎樣擷取到增量的資料?

PG 的增量擷取方式有三個大的版本:

1. 在PG 的9.3 之前,它是不支援Stream Replictaion 的,一般常用的做法都是基于trigger 的方式進行增量的擷取。當然也可以進行業務的侵入,比如說使用業務的

GMT modify,要求業務有GMT modify 的字段,通過這個字段,我們可以拿出某一

個時間點之後的資料,這個也是一個比較間接的來擷取增量資料的方式。

2. 從PG9.3 之後,PG 支援了叫做stream replication 這樣的方式,基于此我們就可以通過這種方式來擷取到增量資料。擷取增量資料有兩種不同的類型,一種叫做logical slot;還有一種是physical slot。在業内目前都是居于logical slot 的方式進行擷取。在PG9.3 之後,在PG10 之前, logical slot 的decoding 是沒有一個能夠正式應用于生産環境的decoding 的,是以我們提供出一個叫做ali decoding 的基于讓logical slot 使用的解碼器。通過它我們可以把PG 的wal 資料,解碼成string類型的邏輯資料,再給到增量擷取的子產品。

3. 在PG10 之後提供了PGoutput slot 的解碼器,通過它可以實作ali decoding 相似的功能,在PG10 之後提供了一個叫做訂閱的概念,能夠從下圖最右邊的語句上看出來,在最右邊的語句上展示了在PG10 或10 以後是怎麼樣去建立一個邏輯訂閱的。

DTS 及其在PG 資料庫生态中的應用

首先會通過叫做PG_create_logical_reputation_slot 的方式來建立出邏輯slot,然後會建立出來一個訂閱,這個訂閱能夠指定訂閱哪張表,或是訂閱所有的表給邏輯slot,這裡的“%s”是需要填充的上個階段建立的邏輯slot 的名稱。

對于較少的表,可以指定具體的表名字,如果表很多,就可以寫成FOR ALL TABLES,訂閱所有表的增量資料,随後使用start replication 開啟讀取訂閱資料。

在這裡需要注意的是PG 的REPLICA IDENTIFY 是表級别的,在這個表級它有不同的級别,比如說default 是預設的級别; using index 是PK 或者是UK;FULL 是所有的; nothing 是什麼都沒有。

從PG10 開始支援邏輯訂閱,在邏輯訂閱中有一個限制,對無主鍵、無唯一鍵的表,如果針對這張表開啟邏輯訂閱,要求這個表的REPLICA IDENTIFY 是負才可以。否則的話,這張表是不能夠進行delete 和update 操作的,關于這點要特别注意。

(五)PostgreSQL Stream Replication

PG 的stream,application 内部的實作原理

PG backend 是PG 的一個服務,接受使用者的TP 資料,形成WAL 寫入到WAL 日志裡面去,并且通知walsender 讀取wal 的資料,walsender 根據接收到的signal 的通知之後,讀取wal 的資料。walsender 根據目前slot 注冊情況,如果logical_slot,那就讀取一個完整的Excel record,然後通過logicaldecode 的方式進行解碼,擷取到解碼後的資料。

如果是physical_slot,那就是通過physical_decode 進行簡單的xlog 的資料讀取,然後擷取到待發送的資料之後,最後由Walsender 将待發送的資料發送給增量的訂閱用戶端。

從這兒可以看得到,無論是logical 的還是physical 的,其實資料都是wal 的日志,隻不過logical 的資料它要求是一個完整的xlog 的記錄,而physical 的隻要是一個完整的xlog 資料塊就可以了。

在這裡面的關鍵點, logical slot 它是通過logical_decode 這樣的一個架構進行解碼,架構裡面會調用具體的output_plugin,進行整行資料的輸出與格式的轉換。

Logical_decode 架構,對于每行資料是要求知道這行資料的relation 資訊,要求PG 知道資訊的具體狀态。關于這一塊如果logical slot 是以曆史的點位進行資料拉取,PG 這邊是沒辦法保證一定能夠找得到當時點位所對應的表的結構資訊。

是以這就是為什麼PG 的logical slot 在建立的時候,隻能以目前的點位進行建立,而不能以曆史的點位。一旦PG 的logical slot 建立出來之後, PG 的backend 會根據各個logical slot 裡曆史最早的點位進行資料儲存。通過這種方式能夠保證所有的logical slot在需要matter 資訊的時候,PG 這邊都能夠得到,都沒有被釋放掉。

DTS 及其在PG 資料庫生态中的應用

(六)PostgreSQL 資料導入

如何讓鍊路的效率更快?

PG 有兩種資料的寫入方式的:

第一種是batch lnsert,是把一些資料整合成一條sql,進行插入;

第二種方式就是PG copy,經過測試, PG copy 的性能要遠超于batch lnsert,大概是batch lnsert 的4 倍左右,是PG 線路裡面一個重要的提升傳輸效率的一種方式。

DTS 及其在PG 資料庫生态中的應用

二、DTS PostgreSQL 資料傳輸通道實作

了解了PG 資料庫對資料通道能夠提供的基礎能力後,下面以DTS 資料傳輸服務為例來看一下,怎麼樣基于這些基礎能力進行整合,打造出來一條資料通道。

(一)DTS 是什麼——異地多活的資料通道

DTS 是阿裡雲的服務,中文名稱是資料傳輸服務,DTS 是資料通道的具體的實作。DTS 的一個重要的屬性是異地多活的資料通道。

什麼叫異地多活呢?

比如,解決杭州到北京之間資料庫之間的資料傳輸;多活是杭州和北京之間的兩邊都支援資料的寫入。DTS 在阿裡巴巴集團内部已經是重要的資料資料傳輸通道,支援了阿裡巴巴曆年的雙11。

看下圖,在2019 年雙11 的時候,整個的TP 的資料洪峰大概是54.4 萬米每秒,在DTS 異地多活的資料通道的強力保障之下,我們做到了毫秒記的延遲,DTS 同時也是阿裡雲内部、阿裡雲上客戶資料同步的重要的利器。

從下圖可以看出,DTS 支撐了全球的資料同步。

DTS 及其在PG 資料庫生态中的應用

(二)DTS 是什麼——使用者上雲的高速公路

DTS 是雲下的使用者和其他雲廠商的使用者上阿裡雲的高速通道。

雲下的使用者可以很友善地使用dts 的服務,将自己雲下的資料搬到雲上的資料庫中,享受不停機資料遷移的能力,并且能夠基于DTS 的雙向同步能力,在發現雲上資料庫出現問題時,能夠快速将自己的業務切換到本地。

DTS 支援雲下的專線連接配接,支援公網連接配接,支援VPN 連接配接等多種連接配接方式。

可以讓雲下的使用者,很友善的享受到雲上的資料庫能力。比如,雲上強大的IP 資料庫的分析能力,大資料的計算能力。

DTS 及其在PG 資料庫生态中的應用

(三)DTS 是什麼——高價值資料的分發源頭

DTS 支援各種TP 資料庫的增量資料。

DTS 在擷取到這些增量資料之後,可以把這些附加值很高的資料分發到,比如ES、Redis、Kafka、Flinkt 等這種大資料平台,進行各種資料計算,将資料的價值最大化。

DTS 及其在PG 資料庫生态中的應用

(四)DTS 邏輯架構概覽

DTS 是雲上的分布式資料傳輸通道,在源端的DTS 支援各種TP 資料庫、Redis、SQL 資料庫,以及分布式資料庫,在目标端DTS 可以把這種資料寫入到TP 資料庫,mango 或者說大資料平台、Kafka、訂閱用戶端去。

DTS 自身給使用者提供了兩個基礎接口,使用者可以通過控制台操作DTS 相應的任務,也可以通過這種open API 進行批量化的建立與管理。

DTS 是自身的分成預檢查子產品、結構遷移子產品、全量遷移子產品、日志解析子產品以及資料寫入子產品。DTS 通過這個資料校驗,提供資料品質的保證能力。

DTS 的資料都存儲在DStore 中,我們可以通過DTS 的ETL 子產品,對DStore 中的資料進行資料清洗、資料轉換,并且最終由writer 同步到目标端,或者由資料訂閱的用戶端消費。

在原端的DTS 支援兩種資料,一種是存量資料,包括資料還有表結構;另一種是增量日志,這一部分可能包括具體的資料以及DDL。

DTS 有三大功能:

第一個就是資料遷移,資料遷移這一塊主要用來解決使用者的資料庫遷移;

第二個是資料同步,資料同步主要的場景是異地多活的場景;

第三個是資料訂閱,資料訂閱是将增量的資料交給用戶端,進行大資料分析,或者使用者自定義的業務。

DTS 提供Numan 運維平台,在運維平台之上可以完成任務的告警監控,可以完成使用者的任務管理、任務告警、資源管理以及對源庫和目标端的異常情況監控。

DTS 的分布式能力主要展現在它的排程服務。DTS 将資源池化之後,對各個使用者的鍊路提供了HA 能力,保證了99.99%的服務能力。

DTS 及其在PG 資料庫生态中的應用

(五)DTS 高效讀寫PostgreSQL

DTS 如何提升存量資料的傳輸效率?

除了使用前面提到的PG 自身的PG copy 之外,我們對全量采用了表兼并發的能力。首先會對一張PG 表進行切片,将其切分成若幹個小片段,針對每個片段使用并發讀取、并發寫入的方式,将存量資料高效的同步到目标表。

右邊是DTS 針對PG 增量資料進行的高效寫入。對于增量資料,DTS 會将其拆分成原始的一個事物,對于沒有沖突的事物, DTS 會采用并發寫入的方式。對于有沖突的事物,DTS 會采用串行寫的方式。通過這種方式在提升效率的同時,也保證了資料的最終一緻性。

關于這一塊的增量和全量的并發寫入DTS 是有相應的專利的。

還有一部分資料就是針對一張表的某一個字段的頻繁的熱點的更新,這種情況之下因為都是沖突的資料,沒辦法進行并發寫入,DTS 是采用熱點合并的方式進行解決。

DTS 及其在PG 資料庫生态中的應用

(六)DTS 捕獲PostgreSQL 增量資料

DTS 有着非常豐富的手段擷取到PG 增量資料。

第一個就是dml trigger,針對PG 9.3 以前的版本, DTS 可以通過在原庫建立trigger 的方式,拉取到增量資料。針對9.3 之後的版本, GTS 是通過logical slot 的方式來擷取到dml 資料。

由于PG 自身是不支援DDL 的原始語句寫入到wal 中的,是以DTS 通過在PG 源庫建立DDL Trigger 的方式,來捕獲到DDL 的原始資料,再進行同步。

基于logical slot 的方式有一定的限制,比如說logical slot 它不能夠支援以曆史的點位進行資料拉取,logical slot 必須針對無PK/UK 的表,設定成IDENTITY FULL,是以現在DTS 也在公關physical slot 的增量擷取技術,目前已經進入到了測試階段,在不久的将來能夠在DTS 的雲上上線。

DTS 及其在PG 資料庫生态中的應用

(七)DTS 解決長鍊路高RT問題

在異地多活的場景裡面,要跨Region 同步資料,必然涉及到高RT 的問題。DTS 解決問題的基本思想就是近DB 的部署原則。以增量的資料同步舉例,在增量裡面,我們的DTS reader 就是拉取增量資料的子產品和源庫部署在同一個Region。

DTS Writer 就是增量資料寫入子產品和目标庫部署在同一個Region,通過這兩個子產品近DB 的部署,最高限度的提升資料的拉取和資料的寫入效率。

DTS Reader 是要把拉取到的資料投遞到DTS Store,而DTS Writer 是要從DTS Store 裡面拉取到同步資料,在這一塊DTS Store 可以部署在源庫的位置,也可以部署在目标庫的位置,甚至可以部署在中間位置。

DTS Reader 到DTS Store,DTS Store 到DTS writer,資料傳輸通道是DTS自身經過高度優化的,通過高度優化過的一個資料通道,我們就解決了高RT的問題。

在這裡面的優化點有兩個:

第一個,盡可能的減少資料傳輸量,在這塊我們主要是通過壓縮,以及源端的資料重删達到的目标。

第二個,因為長鍊路高RT 長,但是資料的Throughpu 是大的,是以我們就盡可能的使用資料推,而不采用Ping-pong 的方式,以盡可能的降低長鍊路RT的問題。

DTS 及其在PG 資料庫生态中的應用

(八)DTS 提供ETL 能力

DTS 的資料傳輸通道裡面,它實作了幾個ETL 能力:

第一個就是表級别的,它可以針對庫、表、列進行映射。比如,下圖例子裡面,它是把原庫的Schema 為a.religion_source 這個Relation 映射成b.relation_target 這樣的一個表。在原表的c1、c2 列,通過DTS 可以映射成d1、d2 列。

第二個次元就是資料次元。舉個例子裡資料清洗,比如說它對c2 列null 字段的清洗成good。同時DTS 的ETL 能力也提供了資料的多表合并。

DTS 及其在PG 資料庫生态中的應用

三、DTS PostgreSQL 經典案例

在了解了DTS 基于PG 的基礎能力,所做的資料通道鍊路之後,基于這個資料通道能夠解決哪些問題。

(一)不停機上雲

所謂的不停機上雲就是源庫的業務不需要停,可以很平滑的将源庫遷移到雲上。我們有一個比較成功的大型應用案例:

東南亞的一個電商,我們支撐了電商大概8tb 的核心資料,然後涉及到11000 個Oracle 資料庫對象的不停機上雲。在這個方案裡面,我們提供的是雙向同步的方案。

先來說正向的方式,首先DTS 會做結構遷移1 動作,在這個階段主要是負責把源庫的庫、表、列資訊以及PK、UK 資訊,遷移到目标庫去。在這個階段完成之後會進行全量資料的遷移,也就是存量資料的遷移。

在存量資料完成之後,我們會進行結構遷移2 階段的這樣的一個遷移動作。在這個階段主要是去遷移原庫的索引。

為什麼結構遷移要分成兩個階段呢?

因為經過大量的測試,發現在資料完成之後,建立索引的效率要遠高于資料完成之前建立索引,是以把結構遷移拆成了兩個階段。在資料完成之後,我們使用結構牽引二的方式建立索引。

在結構遷移整個的完成之後,我們就開始進行增量遷移。

增量遷移的起始位置是從全量遷移之前開始的,這樣能夠保證整個資料一緻性,當增量遷移整個的資料追平之後(就是增量遷移的内容沒有延遲),初步的認為這條鍊路達到了可以切流的階段。為了進一步的驗證資料品質,可以做全鍊校驗的動作。

全鍊校驗是通過拉取源庫的資料,以及拉取目标庫的資料進行全字段的比較,驗證兩邊的資料是一緻的。

當全鍊校驗沒有問題之後,就可以進行切流的動作。在切流之前還會搭建出來一條反向鍊路,所謂的反向鍊路,我們去啟動增量資料的拉取服務,去拉取目标庫增量資料,增加增量資料的寫入子產品,将增量拉取的資料寫入到源庫。

通過反向鍊路的建立,如果在切流的過程之中,目标庫出現了一些不适配,或者業務有一些不适配,我們可以快速的回切到源庫。

這個不停機上雲的方案,我們在雲上已經服務了很多這樣的使用者了,有着非常廣泛的應用。

DTS 及其在PG 資料庫生态中的應用

(二)異地災備

來看下圖中的例子,這個案例是基于DTS 資料傳入通道來實作的異地災備。

使用者兩邊都是自建庫,但是這兩邊自建庫它是在兩地的,通過DTS 雲上的高效資料傳輸能力,幫助使用者搭建了一條從杭州到青島的災備鍊路。

DTS 及其在PG 資料庫生态中的應用

(三)資料內建

下圖是一個資料內建的例子,DTS 将TP 資料庫,把這樣的資料拉取到DTS 的DTSStore 裡面,通過DTS 的同步鍊路,可以寫到如ADB、Kafka 這樣的AP 的資料分析平台裡面去。

也支援使用者使用資料訂閱的用戶端,拉取增量的資料出來,按照使用者自己的場景進行靈活的應用。

DTS 及其在PG 資料庫生态中的應用

(四)大資料下遊

下圖是大資料下遊的案例, 首先使用者是在雲下,通過專線上雲,通過資料同步鍊路使用者在雲上的Ecs 上也有一個資料庫,通過專線完成線下到雲上的一個同步。

在上雲之後,使用者在異地又建立了一個災備庫,通過DTS 完成在災備庫同步。對于災備庫自身,使用者為了盡可能的發揮災備庫的價值,又在災備庫上建立了一條訂閱的鍊路。通過DTS 把資料同步到Kafka,然後再由使用者大資料的下遊,從Kafka 托舉資料進行消費。同時在雲上的庫,使用者通過DTS 建立了一條反向鍊路,通過這條反向鍊路,再回流到使用者雲下的資料庫裡面去。

DTS 及其在PG 資料庫生态中的應用

四、總結

總結來說,我們以資料傳輸通道的視角,講述了PG 在資料傳輸通道上的能力,以及以DTS 為例,說明了基于這些能力,如何建構一條資料傳輸通道,并且例舉了資料上雲、資料災備、資料訂閱等經典的使用案例,希望對大家有所幫助。