TiDB 異構資料庫複製最佳實踐

TiDB_Robot發表於2020-06-19

作者簡介:秦天爽,PingCAP 解決方案事業部架構總監。

縱觀現有業務系統的分散式改造,其中一個難點在於資料庫的遷移:

  • 遷移使用全量還是增量?
  • 線上還是離線?
  • 使用現成的工具還是開發作業?
  • ……

使用者往往面對多種選擇。下面將為大家分享 PingCAP 團隊在多年的實踐中積攢的大量異構平臺遷移經驗,以及資料庫複製技術的更多應用場景。

典型的資料庫遷移流程

說到異構資料庫複製,沒辦法避開的一個話題就是異構資料庫的遷移,我們先看一下典型的異構資料庫遷移的流程:

典型的資料庫遷移有以下流程:

1. 應用適配開發

早期的 TiDB 使用者或多或少都經歷過這個過程,比如 TiDB 在比較早期的版本是僅有樂觀鎖,僅有 RR 隔離級別,事務大小限制大約是 100MB ,在應用適配這方面確實要有一些投入,但是在 TiDB 4.0 版本 中悲觀鎖也走向了成熟,另外配合 RC 隔離級別的支援,還有大事務的加持,事務量有了 100 倍的擴大,應用適配方面會讓使用者投入的成本變得更低。

2. 業務驗證測試

先介紹第一個維度,用生產的資料進行測試。這裡需要先用資料庫複製的技術(後文會詳細介紹)把生產庫複製到 TiDB 中之後,在上面加一個測試的應用就可以做一些壓測,甚至可以做高於真正的生產流量 10 倍、20 倍的壓力對 TiDB 進行壓力測試,來確保你上線的時候 TiDB 是穩定的。為什麼要一定複製一份到 TiDB 裡呢?原因相信很多朋友也碰到過,比如有一條 SQL,在測試環境的時候我把這條 SQL 已經調的非常優化了,但是業務上了線,偏偏這條 SQL 成為了「慢 SQL」,這是由於測試資料跟生產資料偏差太大所導致的,所以這裡我們必須用資料庫複製的技術來做。

第二個維度是使用生產的流量來測,這裡就要藉助一種類似於銀行的 ESB 這種服務匯流排或者像 MQ 技術,比如使用 Kafka 這樣的訊息佇列的機制來實現生產流量的多路複製,也就是說生產環境的一筆業務的成功與失敗,是取決於你現有的生產庫,這個我們就叫做生產業務的主路;還有一個生產業務的旁路,我們在旁路上載入了一個適配過 TiDB 的應用,下面掛著 TiDB 來做一個旁路的驗證工作。以上兩種方式相結合,就可以做一個比較充分的業務驗證。

3. 遷移測試

這部分可能是更多的驗證在停機視窗這段時間裡面做的一些操作,要提前走一遍流程來驗證一下你的遷移手冊是不是可行的、遷移視窗是不是足夠,比如遷移的回退測試,假如這次上線由於什麼原因失敗了,你可能要回退到之前的資料庫,這部分也需要做充分的測試準備。

4. 資料遷移、切換資料庫上線

這兩個步驟屬於上線的階段,我們很多使用者的業務都是 24×7 執行,或者每年內只有一個很短的停機視窗來允許你進行切庫的操作,所以我們的資料遷移要在停機視窗之前來完成,儘早開始來做資料遷移,這裡也用到了異構資料庫複製的技術。在停機視窗時間段內,我們只要把業務停下來,追平增量的資料,然後進行一個資料的比對,再經過一些測試業務的驗證就可以進行切庫上線的動作,一旦切庫上線成功之後,就進入了一個把 TiDB 切為主庫的生產的模式了。

資料庫複製技術的應用場景

從上面的流程可以看到,異構資料庫複製遷移的一個非常重要的場景。還有一些場景也可以用到異構資料庫複製的技術,如下圖所示:

比如建立一個異構的災備庫、逃生庫,假設你的主庫是 Oracle,然後你想用 TiDB 給這個 Oracle 做一個災備庫是完全可行的,“逃生庫” 更多的是指我們新上線了 TiDB,我對 TiDB 可能沒有過多的驗證,可能缺乏一些信心,所以想把 Oracle 接在 TiDB 後面做一個逃生庫,就是說當 TiDB 萬一由於什麼原因崩潰了,我能及時的遷回之前的生產庫。這個情況下也要用到異構資料庫複製技術。

另外,就是建立歸檔庫、只讀庫這種型別的場景,比如我們有一些銀行客戶,銀行核心是執行在封閉系統,可能短期內是沒辦法遷移到開放平臺、遷移到分散式資料庫,但是有一些只讀的業務,比如我在手機 App 上去查我個人的流水、個人賬單,甚至月度的彙總這些操作,沒必要去訪問我的生產核心庫(生產核心只接著那些真正的交易的流量),這些只讀的流量可以通過資料庫複製的技術同步到 TiDB 裡面,然後在 TiDB 裡做只讀操作,這個場景也要用到異構資料庫複製的技術。

另外有一些使用者是生產庫,由於是傳統單機資料庫容量是比較有限的,但是使用者的業務增量又很大,使用者判斷短期內沒辦法遷移到分散式資料庫裡面,考慮一個方案就是:這麼重要的業務,我能不能在我的生產庫裡只儲存一段時間的資料(比如只儲存 30 天、40 天),超期的資料就在生產庫裡面刪掉,但是這些資料在後面掛著的 TiDB 裡是可以查到的,換句話說,這些刪除操作只在生產庫中執行,而用 TiDB 來構建一個歸檔庫。

除此之外,還有一些使用者是把 TiDB 作為一個類似於資料中臺的角色,使用者可能很多業務的交易系統都是 OLTP 的,希望通過資料庫複製的技術來把這些多元的資料匯聚到同一個 TiDB 裡面,之後使用者可以在 TiDB 的基礎上做一些深度分析,或者一些只讀查詢,最主要是將資料匯聚到 TiDB 之後解決跨庫查詢的問題。這些資料庫可能是異構的,沒辦法做像 Oracle 那樣的 DBLink,因為 DBLink 只能做 Oracle 到 Oracle 的,把這些資料彙總到一起之後,有一種類似於我們傳統的 ODS 這樣一個角色。

異構資料庫複製方式

接下來我們看一下常見的異構資料庫複製的方式。

1. 通過介面檔案傳輸資料

通過介面檔案傳輸資料被大量應用於 OLTP 跟 OLAP 之間的資料流轉,也被大量的應用於不同的組織之間的資料傳輸。比如現在有一種模式,網際網路可以作為一個流量的入口,承載了很多針對終端使用者的比如貸款之類的應用,這個是批量生成一個檔案的方式把這個檔案通過定義好的規則,定義好的格式傳送給真正承載這些貸款的銀行,就是通過介面檔案的方式來進行的。因為涉及兩個不同的組織之間的資料傳輸,我們很難打通這兩者之間的資料庫的網路,而且資料庫畢竟還是比較偏後臺的系統,從安全上講也不合適直接打通資料庫之間的連線。

CSV 就是一種典型的介面檔案,但是我們這裡說的並不是資料庫本身的 CSV 匯入匯出功能,比如像 TiDB 4.0 裡支援了 select into outfile 這種匯出 CSV 的能力。這裡面的介面檔案實際上指的是通過應用,比如你的 java 程式碼通過 select 語句把資料讀出來,滿足按照定義好的格式、定義好的分隔符、定義好的換行來生成一個檔案,在接收端因為大家已經協定好了檔案的格式,接收端就是根據這個規則來解析這個檔案,然後轉成 insert 語句來匯入到目標資料庫裡面,可以看出這個方案具有無視資料庫的通用性,只要上下游資料庫支援標準的 SQL 介面就可以使用介面檔案來做資料的傳輸。

缺點也顯而易見:

  • 需要額外的開發,這個開發是需要一定的工作量在你的應用程式碼裡面的,比如你之前是用 java 開發的,就要增加一部分邏輯,如果上游增加一部分生成這個檔案的邏輯,下游就要增加一部分匯入這個檔案的邏輯,而且為了效能,可能還要考慮怎麼去控制併發,以提升效能。

  • 介面檔案的方式難以獲取 update 和 delete 操作的變化,也就是說要不然是全量重新整理,要不然就是追加的寫操作,比如 append 寫這種。

  • 時效性比較差,現今時代,尤其是 5G 也逐漸普及,大家的終端裝置對於延遲的要求都很高,像我們瞭解到銀行,逐漸從傳統的 T+1 的分析方式再往 T+0 甚至準實時分析去靠攏,這種介面檔案的方式很難去控制時效性,因為他是通過檔案或者通過時間來觸發的,頻度包括效率都不是特別高。

  • 資料匯出的時候由於走了 SQL 介面,所以要大範圍的掃描上游的資料庫造成一定的效能影響,因此一般的做法是上游會從從庫上來開放 SQL 介面做只讀匯出檔案傳給下游。

2. 開發 ETL 作業,定時排程作業進行資料傳輸

第二種方式是 ETL,比如開發 ETL 作業,定時的排程這個作業來進行資料傳輸,這個也是普遍應用於 TP 跟 AP 系統之間的一個資料的流轉及加工。

如果是需要長時間執行的話,而不只是一次性的把資料庫讀出來寫到一個目標庫裡,那麼就可能需要長時間的去獲取一些增量,寫到目標庫裡面,這個時候就需要一個作業排程的能力了,會涉及一些額外的開發。這個方式的優點跟介面檔案類似,因為都是 SQL 介面,所以這個方案也具有無視資料庫的通用性,只要上下游資料庫支援 SQL 就可以用 ETL 方式來開發。另外這個方式有一個獨到的地方,因為 ETL 中間有一個 transform,就是說中間可以對這個資料做一些加工,假設你的上游跟你的下游表結構不一樣,甚至有一些需要邏輯加工的東西在這裡面,這時候可能 ETL 就是一個不二之選了。這個方案的缺點跟前面的介面檔案的方式也比較類似:

  • 首先是要額外開發,但大家需要注意的是這其中的開發並不是在你的應用程式碼裡面,而是獨立出一套單獨的作業,這作業多是以 SQL 形式來體現的,然後要獨立完成一個排程系統,相當於對你的系統做了一個外接的東西,架起來這一套外接的東西並讓他同時能訪問到上游、下游庫,才可以執行起來。

  • 使用 ETL 的方式也是難以獲取 update 和 delete 的資料變化的,另外時效性比介面檔案略好,但也不是特別好,這取決於你排程的頻率。而排程的頻率實際上也是依賴每一次排程之後這些作業處理的時間,比如這個作業每一次匯入資料的時候,可能要處理五分鐘,那延遲最高的時候可能要到達 5 分鐘甚至 10 分鐘。

  • 另外通過 SQL 介面去訪問資料,會大範圍的掃描上游資料庫來造成一定的效能影響。

3. CDC 工具

接下來再看看第三種方式,也是我們比較推薦的方式,就是 CDC 工具,它的全稱是增量資料捕獲工具,比如 Oracle  OGG,IBM Inforsphere CDC,還有 TiDB DM 都是這類產品。

CDC 工具的原理是通過讀取上游的 redo log 來生成 SQL 語句返給下游,他可以獲取所有的 DML 的變化,像 delete、update 都是可以獲取的,另外他的效能相對於前兩種方式會比較高,因為只要上游生成了 redo log 下游就可以進行輸出,延遲也是比較低的,具有準實時的特點

這種產品多為商業產品,需要額外的採購。另外這些產品大多數只支援單一的資料庫作為上游,比如僅支援 Oracle 本身,僅支援 MySQL 或者支援開放平臺的 Db2 作為上游,其他型別的資料庫可能沒辦法用 OGG 來傳輸資料給 TiDB,當使用者的上游的資料庫種類特別多的時候,就需要引入多種 CDC 產品。

最佳實踐

最後再來分享一下最佳實踐,如下圖所示:

實際上,當你需要增量複製的時候,而且需要獲得像 delete 和 update 這樣的增量資料的時候,CDC 是不二之選;當你僅需要全量複製,那麼用 ETL 這種工具,比如 Kettle 或者 DataX 這種專門用於資料遷移的 ETL 工具會輕量很多,因為你不需要去採購 CDC,不需要去搭建其他架構來完成這個複製,只需要讓 DataX 等能同時訪問上下游的資料庫,寫好這個作業之後就可以做全量資料傳輸了。

在 “構建災備、逃生資料庫”,“構建歸檔、只讀資料庫”、“多源資料匯聚” 的場景下,我們更建議使用 CDC 來做,因為不管是災備、逃生、歸檔、只讀還是多源資料的匯聚,通過 ETL 作業完成所有 DML 資料的獲取,整個開發成本是非常高的。

順便提一下,TiDB DM 工具可以做到的是:只要你的上游是類 MySQL 的資料庫或者基於 MySQL 開發的資料庫(比如很多公有云上的 RDS,包括 Aurora,還有一些基於 MySQL 開發的分庫分表的產品),都可以使用 TiDB DM 來作為一個資料傳輸工具,關於 DM 更多詳情可以參考這篇文章《TiDB Data Migration(DM) 架構設計與實現原理

本文整理自秦天爽在 TiDB DevCon 2020 上的演講,大會相關視訊回顧可以關注官方 Bilibili 賬號 TiDB_Robot

更多原創文章乾貨分享,請關注公眾號
  • TiDB 異構資料庫複製最佳實踐
  • 加微信實戰群請加微信(註明:實戰群):gocnio

相關文章