天天看點

TiDB 4.0 基于 Binlog 的跨機房叢集部署

作者:靳獻旗,汽車之家 DBA

【目錄】

1.背景介紹

2.跨機房方案概述

3.工作原理

4.叢集架構

5.部署步驟

6.線上使用情況

7.展望

【正文】

1. 背景介紹

公司要求對 0 級應用做跨機房部署,當 A 機房整體故障時,業務可以快速切到 B 機房繼續提供服務。恰好也涉及到了幾套 TiDB 叢集相關業務,這裡做一下總結和回顧,希望能夠幫助需要的使用者。本文主要涉及下面幾項内容:

● 幾種基于 TiDB 的跨機房部署方案及優缺點

● 基于 Binlog 跨機房雙向複制的詳細部署步驟

● 線上 TiDB 跨機房使用情況及展望

2. 跨機房方案概述

下面介紹下 TiDB 幾種跨機房叢集部署方案的優缺點:

| 序号 | 方案 | 優點 | 缺點 | | -- | ------------------------------- | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | | 1 | 同城三中心 | 是完美适配TiDB的部署方式 1.提供單一中心故障的自動故障轉移能力 2.同城多活,資源最大化利用,所有副本都能參與計算 3.較低的成本(同城裸光纖) | 絕大多數使用者不具備同城三中心條件 | | 2 | 同城雙中心可用區方案(同中心的多個可用區在一定程度上實體隔離) | 1.提供單一可用區故障的自動故障轉移能力 2.同城多活,資源最大化利用,所有副本都能參與計算 3.較低的成本(同城裸光纖) | 無法容忍包含多個可用區的機房整體故障 | | 3 | 兩地三中心 | 1.提供單一可用區故障的自動故障轉移能力 2.同城雙活 | 1.成本過高 2.收益低(高網絡延遲,異地中心的部分不參與計算) 3.隻依賴異地的副本無法恢複一緻性(RPO=0)的資料,其異地容災能力與主從叢集方案差别不大 | | 4 | 同城雙中心 Raft 複制 | 1.提供災備中心故障的自動故障轉移能力 2.同城雙活 3.資源最大化利用,所有副本都能參與計算 4.較低的成本(同城裸光纖) | 隻能容忍災備機房故障,缺乏實際意義 | | 5 | 同城雙中心自适應同步複制 | 1.提供災備中心故障的自動故障轉移能力 2.提供主中心故障時的災備機房資料手工恢複的能力 3.同城雙活 4.資源最大化利用,所有副本都能參與計算 5.較低的成本(同城裸光纖) | 方案還外部試點測試中,預計2021年下半年達到生産級别可用 |

目前公司是同城雙中心,是以上述方案排除掉1、2、3方案,4方案缺乏實際意義,5方案還不成熟,是以4、5也排除掉。難道沒有方案可用?下面還有兩種方案沒提到,這裡從技術層面分析下兩種方案的優缺點。

| 序号 | 方案 | 優點 | 缺點 | | -- | -------------- | --------------- | -------------------------- | | 6 | 基于 Binlog 雙向複制 | 1.成熟穩定 | 1.Drainer 不具備高可用 2.并發處理不足 | | 7 | 基于 TiCDC 雙向複制 | 1.具備高可用 2.并發處理強 | 1.官方未 GA 2.記憶體使用較大 3.複制中斷問題 |

經過分析,我們最終選擇了過度方案 6 :基于 Binlog 雙向複制部署跨機房叢集。後續時間成熟,我們會更新到方案 7 或者 5。

3. 工作原理

下面簡單描述下基于 Binlog 雙向同步的工作原理

TiDB 4.0 基于 Binlog 的跨機房叢集部署

在 A 和 B 兩個叢集間開啟雙向同步,則寫入叢集 A 的資料會同步到叢集 B 中,然後這部分資料又會繼續同步到叢集 A,這樣就會出現無限循環同步的情況。如上圖所示,在同步資料的過程中 Drainer 對 Binlog 加上标記,通過過濾掉有标記的 Binlog 來避免循環同步。詳細的實作流程如下:

(1)為兩個叢集分别啟動 TiDB Binlog 同步程式。

(2)待同步的事務經過 A 的 Drainer 時,Drainer 為事務加入 _drainer_repl_mark 辨別表,并在表中寫入本次 DML event 更新,将事務同步至叢集 B。

(3)叢集 B 向叢集 A 傳回帶有 _drainer_repl_mark 辨別表的 Binlog event。叢集 B 的 Drainer 在解析該 Binlog event 時發現帶有 DML event 的辨別表,放棄同步該 Binlog event 到叢集 A。

● 注意事項:

叢集間雙向同步的前提條件是,寫入兩個叢集的資料必須保證無沖突,即在兩個叢集中,不會同時修改同一張表的同一主鍵和具有唯一索引的行。

更詳細的内容請參考官方文檔

​​https://docs.pingcap.com/zh/TiDB/stable/bidirectional-replication-between-TiDB-clusters#%E9%9B%86%E7%BE%A4%E9%97%B4%E5%8F%8C%E5%90%91%E5%90%8C%E6%AD%A5​​

4. 叢集架構

叢集資訊如下:

叢集 A (位于機房 A,ip 做了脫敏處理)

IP 版本 元件 配置
192.168.1.1 4.0.9 TiDB/PD/Pump/Drainer 記憶體:256G 硬碟:SATA SSD CPU:48核 網卡:萬兆
192.168.1.2 4.0.9 TiDB/PD/Pump
192.168.1.3 4.0.9 TiDB/PD/Pump
192.168.1.4 4.0.9 2個TiKV 記憶體:256G 硬碟:SATA SSD CPU:64核 網卡:萬兆
192.168.1.5 4.0.9 2個TiKV
192.168.1.6 4.0.9 2個TiKV
192.168.1.7 4.0.9 2個TiKV

叢集 B (位于機房 B,ip 做了脫敏處理)

IP 版本 元件 配置
192.168.2.1 4.0.9 TiDB/PD/Pump/Drainer 記憶體:256G 硬碟:SATA SSD CPU:48核 網卡:萬兆
192.168.2.2 4.0.9 TiDB/PD/Pump
192.168.2.3 4.0.9 TiDB/PD/Pump
192.168.2.4 4.0.9 2個TiKV 記憶體:256G 硬碟:SATA SSD CPU:64核 網卡:萬兆
192.168.2.5 4.0.9 2個TiKV
192.168.2.6 4.0.9 2個TiKV
192.168.2.7 4.0.9 2個TiKV

叢集架構如下

TiDB 4.0 基于 Binlog 的跨機房叢集部署

5. 部署步驟

本節詳細介紹基于 Binlog 的跨機房部署步驟,這裡以 TiDB 4.0.9 版本為例,對一個線上未開啟 Binlog 的叢集配置跨機房複制。主要分為兩部配置設定置:A 叢集配置,B 叢集配置。

● A 叢集配置步驟概要

(1)A 叢集部署 Pump

(2)A 叢集開啟 Binlog

(3)A 叢集導出全量資料,将全量資料導入 B 叢集

(4)A 叢集配置 drainer ,實作增量複制

● B 叢集部署步驟概要

(1)B 叢集部署 Pump

(2)B 叢集開啟 Binlog

(3)B 叢集配置 drainer ,實作反向複制

5.1 A 叢集部署步驟

【 A 叢集部署 Pump 】

  1. 編寫 Pump 擴容拓撲配置
vim scale_out_pump.yaml
pump_servers:
- host: 192.168.1.1
  ssh_port: 22
  port: 8250
  deploy_dir: /data/pump-8250
  data_dir: /data/pump-8250/data.pump
  log_dir: /data/pump-8250/log
  config:
    gc: 3  #指定 binlog 可在本地存儲的天數,超過指定天數的 binlog 會被自動删除
- host: 192.168.1.2
  ssh_port: 22
  port: 8250
  deploy_dir: /data/pump-8250
  data_dir: /data/pump-8250/data.pump
  log_dir: /data/pump-8250/log
  config:
    gc: 3
- host: 192.168.1.3
  ssh_port: 22
  port: 8250
  deploy_dir: /data/pump-8250
  data_dir: /data/pump-8250/data.pump
  log_dir: /data/pump-8250/log
  config:
    gc: 3      
  1. 執行下面指令擴容 Pump
tiup cluster scale-out a_cluster scale_out_pump.yaml      
  1. 檢視 Pump 狀态
tiup cluster display a_cluster      
  1. 登入 TiDB 檢視 Pump 狀态
show pump status;      

【 A 叢集開啟 Binlog 】

  1. 編輯 A 叢集配置檔案開啟 Binlog
tiup cluster edit-config a_cluster
server_configs:
  TiDB:
    binlog.enable: true        # 設定為 true 開啟 Binlog
    binlog.ignore-error: true  # 建議設定為 true ,否則 Binlog 無法寫入時會導緻整個叢集無法寫入資料                            
  1. 滾動重新開機 TiDB-server
tiup cluster reload a_cluster -R tidb      
  1. 登入 TiDB 确認目前叢集是否開啟 Binlog
show global variables like 'log_bin'; # 1 表示開啟      

【 A 叢集導出全量資料,将全量資料導入 B 叢集 】

1.A 叢集導出全量資料

/data/tidb-tools/bin/dumpling -h 192.168.1.1 -P 4000 -u username -p password --params="TiDB_isolation_read_engines=tikv" --filetype sql --tidb-mem-quota-query 8589934592 --threads 2 -r 500000 -F 200MiB -o /data/bak_4000_20210522 -f 'sms_send.*' -f 'rcm_pool.*' --loglevel debug --logfile dumpling_20210522.log      

2.将全量資料導入 B 叢集

/data/tidb-tools/bin/loader -h 192.168.2.1 -P 4000 -u username -p password -t 4 -d /data/bak_4000_20210522      

【 A 配置 Drainer 實作增量複制 】

  1. 編寫 Drainer 擴容拓撲配置
vim scale_out_drainer.yaml
drainer_servers:
- host: 192.168.1.1
  ssh_port: 22
  port: 8249
  commit_ts: 425112071610302470    #從上一步的 /data/tmp/bak_20210522/metadata 檔案擷取
  deploy_dir: /data/drainer-8249
  data_dir: /data/drainer-8249/data
  log_dir: /data/drainer-8249/log
  config:
    syncer.loopback-control: true
    syncer.channel-id: 123456      #互相同步的兩個叢集配置相同的 ID
    syncer.sync-ddl: true          #需要同步 DDL 操作
    syncer.db-type: tidb
    syncer.ignore-schemas: INFORMATION_SCHEMA,METRICS_SCHEMA,PERFORMANCE_SCHEMA,mysql,test
    syncer.ignore-table:           #忽略 checkpoint 表
    - db-name: tidb_binlog
      tbl-name: checkpoint
    syncer.to.host: 192.168.2.1          #下遊 TiDB 叢集 ip
    syncer.to.port: 4000                 #下遊 TiDB 叢集 port
    syncer.to.sync-mode: 1
    syncer.to.password: password         #下遊使用者的密碼
    syncer.to.user: drainer_user         #下遊使用者,需要提前在下遊 TiDB 叢集建立
    syncer.txn-batch: 200   #将 DML 分批執行,用于設定每個事務中包含多少個 DML
    syncer.worker-count: 4  #指定并發數      
  1. 執行下面指令擴容 Drainer
tiup cluster scale-out a_cluster scale_out_drainer.yaml      
  1. 檢視 Drainer 狀态
tiup cluster display a_cluster      

4.登入 TiDB 檢視 Drainer 狀态

show drainer status;      

5.2 B 叢集部署步驟

【 B 叢集部署 Pump 】

  1. 編寫 Pump 擴容拓撲配置
vim scale_out_pump.yaml
pump_servers:
- host: 192.168.2.1
  ssh_port: 22
  port: 8250
  deploy_dir: /data/pump-8250
  data_dir: /data/pump-8250/data.pump
  log_dir: /data/pump-8250/log
  config:
    gc: 3
- host: 192.168.2.2
  ssh_port: 22
  port: 8250
  deploy_dir: /data/pump-8250
  data_dir: /data/pump-8250/data.pump
  log_dir: /data/pump-8250/log
  config:
    gc: 3
- host: 192.168.2.3
  ssh_port: 22
  port: 8250
  deploy_dir: /data/pump-8250
  data_dir: /data/pump-8250/data.pump
  log_dir: /data/pump-8250/log
  config:
    gc: 3      
  1. 執行下面指令擴容 Pump
tiup cluster scale-out b_cluster scale_out_pump.yaml      
  1. 檢視 Pump 狀态
tiup cluster display b_cluster      
  1. 登入 TiDB 檢視 Pump 狀态
show pump status;      

【 B 叢集開啟 Binlog 】

  1. 編輯 B 叢集配置檔案開啟 Binlog
tiup cluster edit-config b_cluster
server_configs:
  TiDB:
    binlog.enable: true        # 設定為 true 開啟 Binlog
    binlog.ignore-error: true  # 建議設定為 true ,否則 Binlog 無法寫入時會導緻整個叢集無法寫入資料       
  1. 滾動重新開機 TiDB-server
tiup cluster reload b_cluster -R TiDB      
  1. 确認目前叢集是否開啟 Binlog
show global variables like 'log_bin'; # 1 表示開啟      

【 B 配置 Drainer 實作反向複制 】

  1. 編寫 Drainer 擴容拓撲配置
vim scale_out_drainer.yaml
drainer_servers:
- host: 192.168.2.1
  ssh_port: 22
  port: 8249
  deploy_dir: /data/drainer-8249
  data_dir: /data/drainer-8249/data
  log_dir: /data/drainer-8249/log
  config:
    syncer.loopback-control: true
    syncer.channel-id: 123456   #互相同步的兩個叢集配置相同的 ID
    syncer.sync-ddl: false      #不需要同步 DDL 操作
    syncer.db-type: tidb
    syncer.ignore-schemas: INFORMATION_SCHEMA,METRICS_SCHEMA,PERFORMANCE_SCHEMA,mysql,test
    syncer.ignore-table:                 #忽略 checkpoint 表
    - db-name: tidb_binlog
      tbl-name: checkpoint
    syncer.to.host: 192.168.1.1          #下遊 TiDB 叢集 ip
    syncer.to.port: 4000                 #下遊 TiDB 叢集 port
    syncer.to.sync-mode: 1
    syncer.to.password: password         #下遊使用者的密碼
    syncer.to.user: drainer_user         #下遊使用者,需要提前在下遊 TiDB 叢集建立
    syncer.txn-batch: 200
    syncer.worker-count: 2      
  1. 執行下面指令擴容 Drainer
tiup cluster scale-out b_cluster scale_out_drainer.yaml      
  1. 檢視 Drainer 狀态
tiup cluster display b_cluster      

4.登入 TiDB 檢視 Drainer 狀态

show drainer status;      

5.3 測試雙向複制

我們重點對下面幾種場景做了測試:

| 序号 | 測試内容 | 測試結果 | | -- | --------------------- | ---- | | 1 | A 叢集資料同步到 B 叢集是否正常 | 正常 | | 2 | B 叢集資料同步到 A 叢集是否正常 | 正常 | | 3 | A 叢集 DDL 同步到 B 叢集是否正常 | 正常 | | 4 | B 叢集 DDL 不能同步到 A 叢集 | 無法同步 |

6. 線上使用情況

目前線上有3套 TiDB 叢集做了跨機房部署,如下表所示:

叢集資訊 業務說明 跨機房部署說明 運作時間
叢集1 短信業務 庫級别雙向複制 2020/10 — 至今
叢集2 使用者中心登入注冊相關接口 庫級别雙向複制 2021/05 — 至今
叢集3 資源池 叢集級别雙向複制 2021/05 — 至今

7. 展望