TiDB上百T資料拆分實踐

2022-12-30 06:00:27

背景

提高TiDB可用性,需要把多點已有上百T TiDB叢集拆分出2套

挑戰

  • 1、現有需要拆分的12套TiDB叢集的版本多(4.0.9、5.1.1、5.1.2都有),每個版本拆分方法存在不一樣
  • 2、其中5套TiDB,資料量均超過10T、最大的TiDB叢集目前資料量62T、單TiDB叢集備份集大,消耗大量磁碟空間和頻寬資源

空間最大3套叢集

  • 3、tidb使用方式多樣(每種方式拆分方法不同),有直接讀寫tidb,也有mysql->tidb彙總分析查詢,也有tidb->cdc->下游hive
  • 4、全量備份TiDB在業務高峰期是否會產生效能影響
  • 5、巨量資料量的拆分資料的一致性保證

方案

目前TiDB官方提供的同步工具有:

  • DM全量+增量(該方法無法用於tidb->tidb,適用於MySQL->TiDB)
  • BR全量物理備份+CDC增量同步(CDC同步在tidb、tikv節點OOM後修復成本高https://github.com/pingcap/tiflow/issues/3061)
  • BR全量物理備份+binlog增量(類似於MySQL記錄所有變更的binlog紀錄檔,TiDB binlog由Pump(記錄變更紀錄檔)+Drainer(回放變更紀錄檔)組成,我們採用該方法進行全量+增量同步拆分)

備份與恢復工具 BR

TiDB Binlog

因TiDB拆分BR全量物理備份+binlog增量涉及週期長,我們分為4個階段進行

第一階段

1、清理現有TiDB叢集無用資料

按月分表tidb庫有無用的表,如3個月前的xxxx 紀錄檔表

2、升級GZ現有15套TiDB叢集(12套TiDB叢集需要1分為2)版本至5.1.2

趁這次拆分統一GZ tidb版本,解決挑戰1

set @@global.tidb_analyze_version = 1;

#tidb_analyze_version為2時出現OOM機率大,5.4版本開始該預設值從2改為1

https://github.com/pingcap/tidb/issues/31748

第二階段

1、新機器部署好相同版本5.1.2TiDB叢集

set @@global.tidb_analyze_version = 1;

2、目的端,源端所有tikv tiflash掛載好NFS,pd節點上安裝好BR

Exteral storge採用騰訊雲NFS網路硬碟,保障tikv備份目的端和還原全量來源端都能在同一目錄,NFS網路硬碟空間自動動態增加+限速備份以應對挑戰2

3、獨立3臺機器部署好12套TiDB叢集pump收集binlog(埠區分不同TiDB叢集)

pump,drainer採用獨立16C, 32G機器保障增量同步最大效能

注意:為保障tidb計算節點的可用性,需設定ignore-errorbinlog關鍵引數

server_configs:

  tidb:

    binlog.enable: true

    binlog.ignore-error: true

4、修改pump元件 GC時間為7天

binlog保留7天保障全量備份->到增量同步過程能接上

pump_servers:

  - host: xxxxx

    config:

      gc: 7

#需reload重啟tidb節點使記錄binlog生效

5、備份TiDB叢集全量資料至NFS Backup & Restore 常見問題

注意:每個TiDB叢集在同一個NFS建不同備份目錄

注意:源老TiDB叢集分別限速(備份前後對讀寫延遲時間基本無影響)進行錯峰全量備份(存在之前多個TiDB叢集同時備份把NFS 3Gbps網路頻寬打滿情況)以減輕對現有TiDB讀寫、NFS的壓力以應對挑戰2

mkdir -p /tidbbr/0110_dfp

chown -R tidb.tidb /tidbbr/0110_dfp

#限速進行全業務應用庫備份

./br backup          full \

    --pd "xxxx:2379" \

    --storage "local:///tidbbr/0110_dfp" \

    --ratelimit 80 \

    --log-file /data/dbatemp/0110_backupdfp.log

#限速進行指定庫備份

 ./br backup db \

    --pd "xxxx:2379" \

    --db db_name \

    --storage "local:///tidbbr/0110_dfp" \

    --ratelimit 80 \

    --log-file /data/dbatemp/0110_backupdfp.log

    

12.30號45T TiDB叢集全量備份耗時19h,佔用空間12T

[2021/12/30 09:33:23.768 +08:00] [INFO] [collector.go:66] ["Full backup success summary"] [total-ranges=1596156] [ranges-succeed=1596156] [ranges-failed=0] [backup-checksum=3h55m39.743147403s] [backup-fast-checksum=409.352223ms] [backup-total-ranges=3137] [total-take=19h12m22.227906678s] [total-kv-size=65.13TB] [average-speed=941.9MB/s] ["backup data size(after compressed)"=12.46TB] [BackupTS=430115090997182553] [total-kv=337461300978]

6、每個新建TiDB叢集單獨同步老TiDB叢集使用者密碼資訊

注意:BR全量備份不備份tidb mysql系統庫,應用、管理員使用者密碼資訊可用開源pt-toolkit工具包pt-show-grants匯出

7、恢復NFS全量備份至新TiDB叢集

注意:新TiDB叢集磁碟空間需充裕,全量備份還原後新TiDB叢集佔用空間比老TiDB叢集多幾個T,和官方人員溝通是由於還原時生成sst的演演算法是lz4,導致壓縮率沒有老TiDB叢集高

注意:tidb_enable_clustered_index,sql_mode 新老TiDB叢集這2引數必須一致

8、tiup擴容drainer進行增量同步

擴容前確認下游checkpoint資訊不存在或已清理

如果下游之前接過drainer,相關位點在目標端tidb_binlog.checkpoint表中,重做的時候需要清理

注意:因源最大TiDB叢集長期平均寫入TPS在6k左右,在增大worker-count回放執行緒數後,儘管目的端域名解析到3個tidb節點,單個drainer增量還是無法追上延遲(回放速度最高在3k TPS),後和TiDB官方溝通改成按3個drainer(不同drainer同步不同庫名)並行增量同步延遲追上(3個drainer增量讓「漏斗」沒有堆積,源流入端資料能及時到達目標流出端)

注意:多個drainer並行增量必須指定目的端checkpoint.schema為不同庫 drainer設定說明



#從備份檔案中獲取全量備份開始時的位點TSO

grep "BackupTS=" /data/dbatemp/0110_backupdfp.log

430388153465177629



#第一次一個drainer進行增量同步關鍵設定

drainer_servers:

  - host: xxxxxx

    commit_ts: 430388153465177629      

    deploy_dir: "/data/tidb-deploy/drainer-8249"

    config:

      syncer.db-type: "tidb"

      syncer.to.host: "xxxdmall.db.com"

      syncer.worker-count: 550



      

#第二次多個drainer進行並行增量同步

drainer_servers:

  - host: xxxxxx

    commit_ts: 430505424238936397  #該位點TSO為從第一次1個drainer增量停止後目的端checkpoint表中的Commit_Ts

    config:

      syncer.replicate-do-db: [db1,db2,....]

      syncer.db-type: "tidb"

      syncer.to.host: "xxxdmall.db.com"

      syncer.worker-count: 550

      syncer.to.checkpoint.schema: "tidb_binlog2"

      

1個drainer進行增量延遲越來越大

3個drainer進行並行增量同步最慢一條增量鏈路:9h追了近1天資料

3個drainer並行同步目的端寫入1.2w TPS > 源端6k寫入TPS

9、設定新建tidb grafana&dashboard 域名

建grafana、dashboard的域名指向生產nginx代理,由nginx代理grafana 埠,dashboard 埠

第三階段

1、check新老TiDB叢集資料同步一致性情況

TiDB在全量和增量時會自行進行資料一致性校驗,我們主要關注增量同步延遲情況,並隨機count(*)源目的端表



#延遲檢查方法一:在源端TiDB drainer狀態中獲取最新已經回覆TSO再通過pd獲取延遲情況

mysql> show drainer status;

+-------------------+-------------------+--------+--------------------+---------------------+

| NodeID            | Address           | State  | Max_Commit_Ts      | Update_Time         |

+-------------------+-------------------+--------+--------------------+---------------------+

| xxxxxx:8249   | xxxxxx:8249   | online | 430547587152216733 | 2022-01-21 16:50:58 |





tiup ctl:v5.1.2 pd -u http://xxxxxx:2379 -i

» tso 430547587152216733;

system:  2022-01-17 16:38:23.431 +0800 CST

logic:   669





#延遲檢查方法二:在grafana drainer監控中觀察

tidb-Binlog->drainer->Pump Handle TSO中current值和當前實際時間做延遲比較

曲線越陡,增量同步速率越快

2、tiflash表建立&CDC同步在新TiDB叢集建立&新mysql->tidb彙總同步鏈路閉環(DRC-TIDB)

tiflash

源端tidb生成目的端 新建tiflash語句



SELECT * FROM information_schema.tiflash_replica WHERE TABLE_SCHEMA = '<db_name>' and TABLE_NAME = '<table_name>'

SELECT concat('alter table ',table_schema,'.',table_name,' set tiflash replica 1;') FROM information_schema.tiflash_replica where table_schema like 'dfp%';

CDC鏈路閉環

在老TiDB CDC同步中選取1個TSO位點在新TiDB中建立CDC至kafka topic同步

DRC-TIDB鏈路閉環(自研mysql->tidb合庫合表同步工具)

上圖左右為DRC-TIDB拆分前後狀態

1、左老drc-tidb同步規則copy到右新drc-tidb,不啟動drc-tidb同步(記錄當前時間T1)

2、drainer同步現有TiDB資料至新建TiDB鏈路啟用安全模式replace(syncer.safe-mode: true)插入

3、修改左drc-tidb同步源目的地址為閉環,並啟動drc-tidb(記錄當前時間T2)

4、右tidb grafana drainer監控中check當前同步時間checkpoint是否>=T2(類似於tikv follower-read),若沒有則等待延遲追上

5、右tidb叢集增量同步修改edit-config drainer組態檔,去掉mysql-tidb同步的庫名(所有庫同步增加指定庫名同步)並reload drainer節點

 commit_ts: 431809362388058219

  config:

    syncer.db-type: tidb

    syncer.replicate-do-db:

    - dmall_db1 該DB為直接讀寫

    - dmall_db2 該DB為從mysql同步而來,需去掉

6、修改右drc-tidb同步源目的地址為閉環,並啟動右drc-tidb(drc-tidb採用冪等同步,會重複消費copy同步規則T1時間到現在now的mysql binlog)

3、每個新TiDB叢集ANALYZE TABLE 更新表統計資訊

不是必須,更新統計資訊為最新可以避免查詢sql索引選擇走錯

第四階段

1、左tidb叢集應用域名解析至新建tidb計算節點

2、批次kill右TiDB叢集左應用的連線

存在指令碼多次批次kill tidb pid;在右tidb節點依然有大量左應用的連線,因此左應用捲動重啟後右tidb節點左應用連線釋放

3、移除老TiDB叢集->新TiDB叢集增量同步drainer鏈路

注意:因多個TiDB叢集共用的1臺高配drainer機器,node_exporter(採集機器監控agent)也是多個TiDB叢集共用,當A TiDB叢集停止drainer鏈路,B C TiDB叢集會報node_exporter不存活告警

總結

  • 不同TiDB版本的升級統一版本很有必要,一是拆分方法的通用,減少拆分的複雜度,二是享受新版本的特性,減低運維管理成本
  • 目標TiDB叢集磁碟空間需足夠充裕
  • 在源TiDB寫入壓力大時增量同步binlog到目的端的延遲保障需要drainer按庫名進行並行增量同步
  • TiDB拆分涉及步驟多,能提前做的步驟就提前錯,真正總拆分的時間視窗很短
  • 感謝TiDB官方社群對我們的技術支援,路漫漫其修遠兮,我們將上下而求索