摘要:設計從年開始提供全量導入工具,它以多線程操作錯誤重試斷點續傳以及修改一些專屬配置來提升數據導入速度。此外,多線程的線上導入也代表資料是亂序插入的,新的數據范圍會與舊的重疊。現時只支持經導出的備份。此外亦同時將文件分割為大小差不多的區塊默認。
作者:Kenny Chan簡介
TiDB-Lightning Toolset 是一套快速全量導入 SQL dump 文件到 TiDB 集群的工具集,自 2.1.0 版本起隨 TiDB 發布,速度可達到傳統執行 SQL 導入方式的至少 3 倍、大約每小時 100 GB,適合在上線前用作遷移現有的大型數據庫到全新的 TiDB 集群。
設計TiDB 從 2017 年開始提供全量導入工具 Loader,它以多線程操作、錯誤重試、斷點續傳以及修改一些 TiDB 專屬配置來提升數據導入速度。
然而,當我們全新初始化一個 TiDB 集群時,Loader 這種逐條 INSERT 指令在線上執行的方式從根本上是無法盡用性能的。原因在于 SQL 層的操作有太強的保證了。在整個導入過程中,TiDB 需要:
保證 ACID 特性,需要執行完整的事務流程。
保證各個 TiKV 服務器數據量平衡及有足夠的副本,在數據增長的時候需要不斷的分裂、調度 Regions。
這些動作確保 TiDB 整段導入的期間是穩定的,但在導入完畢前我們根本不會對外提供服務,這些保證就變成多此一舉了。此外,多線程的線上導入也代表資料是亂序插入的,新的數據范圍會與舊的重疊。TiKV 要求儲存的數據是有序的,大量的亂序寫入會令 TiKV 要不斷地移動原有的數據(這稱為 Compaction),這也會拖慢寫入過程。
TiKV 是使用 RocksDB 以 KV 對的形式儲存數據,這些數據會壓縮成一個個 SST 格式文件。TiDB-Lightning Toolset使用新的思路,繞過SQL層,在線下將整個 SQL dump 轉化為 KV 對、生成排好序的 SST 文件,然后直接用 Ingestion 推送到 RocksDB 里面。這樣批量處理的方法略過 ACID 和線上排序等耗時步驟,讓我們提升最終的速度。
架構TiDB-Lightning Toolset 包含兩個組件:tidb-lightning 和 tikv-importer。Lightning 負責解析 SQL 成為 KV 對,而 Importer 負責將 KV 對排序與調度、上傳到 TiKV 服務器。
為什么要把一個流程拆分成兩個程式呢?
Importer 與 TiKV 密不可分、Lightning 與 TiDB 密不可分,Toolset 的兩者皆引用后者為庫,而這樣 Lightning 與 Importer 之間就出現語言沖突:TiKV 是使用 Rust 而 TiDB 是使用 Go 的。把它們拆分為獨立的程式更方便開發,而雙方都需要的 KV 對可以透過 gRPC 傳遞。
分開 Importer 和 Lightning 也使橫向擴展的方式更為靈活,例如可以運行多個 Lightning,傳送給同一個 Importer。
以下我們會詳細分析每個組件的操作原理。
LightningLightning 現時只支持經 mydumper 導出的 SQL 備份。mydumper 將每個表的內容分別儲存到不同的文件,與 mysqldump 不同。這樣不用解析整個數據庫就能平行處理每個表。
首先,Lightning 會掃描 SQL 備份,區分出結構文件(包含 CREATE TABLE 語句)和數據文件(包含 INSERT 語句)。結構文件的內容會直接發送到 TiDB,用以建立數據庫構型。
然后 Lightning 就會并發處理每一張表的數據。這里我們只集中看一張表的流程。每個數據文件的內容都是規律的 INSERT 語句,像是:
INSERT INTO `tbl` VALUES (1, 2, 3), (4, 5, 6), (7, 8, 9); INSERT INTO `tbl` VALUES (10, 11, 12), (13, 14, 15), (16, 17, 18); INSERT INTO `tbl` VALUES (19, 20, 21), (22, 23, 24), (25, 26, 27);
Lightning 會作初步分析,找出每行在文件的位置并分配一個行號,使得沒有主鍵的表可以唯一的區分每一行。此外亦同時將文件分割為大小差不多的區塊(默認 256 MiB)。這些區塊也會并發處理,讓數據量大的表也能快速導入。以下的例子把文件以 20 字節為限分割成 5 塊:
Lightning 會直接使用 TiDB 實例來把 SQL 轉換為 KV 對,稱為「KV 編碼器」。與外部的 TiDB 集群不同,KV 編碼器是寄存在 Lightning 進程內的,而且使用內存存儲,所以每執行完一個 INSERT 之后,Lightning 可以直接讀取內存獲取轉換后的 KV 對(這些 KV 對包含數據及索引)。
得到 KV 對之后便可以發送到 Importer。
Importer因異步操作的緣故,Importer 得到的原始 KV 對注定是無序的。所以,Importer 要做的第一件事就是要排序。這需要給每個表劃定準備排序的儲存空間,我們稱之為 engine file。
對大數據排序是個解決了很多遍的問題,我們在此使用現有的答案:直接使用 RocksDB。一個 engine file 就相等于本地的 RocksDB,并設置為優化大量寫入操作。而「排序」就相等于將 KV 對全寫入到 engine file 里,RocksDB 就會幫我們合并、排序,并得到 SST 格式的文件。
這個 SST 文件包含整個表的數據和索引,比起 TiKV 的儲存單位 Regions 實在太大了。所以接下來就是要切分成合適的大小(默認為 96 MiB)。Importer 會根據要導入的數據范圍預先把 Region 分裂好,然后讓 PD 把這些分裂出來的 Region 分散調度到不同的 TiKV 實例上。
最后,Importer 將 SST 上傳到對應 Region 的每個副本上。然后通過 Leader 發起 Ingest 命令,把這個 SST 文件導入到 Raft group 里,完成一個 Region 的導入過程。
我們傳輸大量數據時,需要自動檢查數據完整,避免忽略掉錯誤。Lightning 會在整個表的 Region 全部導入后,對比傳送到 Importer 之前這個表的 Checksum,以及在 TiKV 集群里面時的 Checksum。如果兩者一樣,我們就有信心說這個表的數據沒有問題。
一個表的 Checksum 是透過計算 KV 對的哈希值(Hash)產生的。因為 KV 對分布在不同的 TiKV 實例上,這個 Checksum 函數應該具備結合性;另外,Lightning 傳送 KV 對之前它們是無序的,所以 Checksum 也不應該考慮順序,即服從交換律。也就是說 Checksum 不是簡單的把整個 SST 文件計算 SHA-256 這樣就了事。
我們的解決辦法是這樣的:先計算每個 KV 對的 CRC64,然后用 XOR 結合在一起,得出一個 64 位元的校驗數字。為減低 Checksum 值沖突的概率,我們目時會計算 KV 對的數量和大小。若速度允許,將來會加入更先進的 Checksum 方式。
總結和下一步計劃從這篇文章大家可以看到,Lightning 因為跳過了一些復雜、耗時的步驟使得整個導入進程更快,適合大數據量的初次導入,接下來我們還會做進一步的改進。
提升導入速度現時 Lightning 會原封不動把整條 SQL 命令拋給 KV 編碼器。所以即使我們省去執行分布式 SQL 的開銷,但仍需要進行解析、規劃及優化語句這些不必要或未被專門化的步驟。Lightning 可以調用更底層的 TiDB API,縮短 SQL 轉 KV 的行程。
并行導入另一方面,盡管我們可以不斷的優化程序代碼,單機的性能總是有限的。要突破這個界限就需要橫向擴展:增加機器來同時導入。如前面所述,只要每套 TiDB-Lightning Toolset 操作不同的表,它們就能平行導進同一個集群。可是,現在的版本只支持讀取本機文件系統上的 SQL dump,設置成多機版就顯得比較麻煩了(要安裝一個共享的網絡盤,并且手動分配哪臺機讀取哪張表)。我們計劃讓 Lightning 能從網路獲取 SQL dump(例如通過 S3 API),并提供一個工具自動分割數據庫,降低設置成本。
在線導入TiDB-Lightning 在導入時會把集群切換到一個專供 Lightning 寫入的模式。目前來說 Lightning 主要用于在進入生產環境之前導入全量數據,所以在此期間暫停對外提供服務還可以接受。但我們希望支持更多的應用場景,例如回復備份、儲存 OLAP 的大規模計算結果等等,這些都需要維持集群在線上。所以接下來的一大方向是考慮怎樣降低 Lightning 對集群的影響。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/17861.html
摘要:合庫合表數據同步在使用支撐大量數據時,經常會選擇使用分庫分表的方案。但當將數據同步到后,通常希望邏輯上進行合庫合表。為支持合庫合表的數據同步,主要實現了以下的一些功能。 作者:張學程 簡介 TiDB-DM(Data Migration)是用于將數據從 MySQL/MariaDB 遷移到 TiDB 的工具。該工具既支持以全量備份文件的方式將 MySQL/MariaDB 的數據導入到 Ti...
閱讀 1790·2021-11-24 10:21
閱讀 1202·2021-09-22 15:25
閱讀 3165·2019-08-30 15:55
閱讀 704·2019-08-30 15:54
閱讀 3456·2019-08-30 14:20
閱讀 1653·2019-08-30 14:06
閱讀 635·2019-08-30 13:11
閱讀 3135·2019-08-29 16:43