TiDB 6.0 實戰分享丨冷熱存儲分離解決方案

語言: CN / TW / HK

結論先行

TiDB 6.0 正式提供了數據放置框架(Placement Rules in SQL )功能,用户通過 SQL 配置數據在 TiKV 集羣中的放置位置,可以對數據進行直接的管理,滿足不同的業務場景需要。如:

1.冷熱分離存儲,降低存儲成本

  • TiDB 6.0 正式支持數據冷熱存儲分離,可以降低 SSD 使用成本。使用 TiDB 6.0 的數據放置功能,可以在同一個集羣實現海量數據的冷熱存儲,將新的熱數據存入 SSD,歷史冷數據存入 HDD,降低歷史歸檔數據存儲成本。
  • 將熱數據從 ssd 遷移到 hdd,每小時可歸檔約 3000 萬行,總體來看效率還是比較高的
  • 將冷數據從 hdd 遷移到 ssd,每小時可遷移約 6300 萬行,大約是從 ssd 遷移到 hdd 速度的 2 倍
  • 分離存儲過程,ssd 和 hdd 用於歸檔的 IO 消耗都在 10%以內,集羣訪問 QPS 表現平穩,對業務訪問的影響較小
  • 在補寫冷數據場景,每小時寫入約 1500 萬行到 hdd,數據可正確地直接寫入 hdd,不會經過 ssd

2.業務底層物理隔離,實現同一集羣不同存儲

  • 通過放置規則管理將不同數據庫下的數據調度到不同的硬件節點上,實現業務間數據的物理資源隔離,避免因資源爭搶,硬件故障等問題造成的相互干擾
  • 通過賬號權限管理避免跨業務數據訪問,提升數據質量和數據安全

3.合併MySQL業務,降低運維壓力,提升管理效率

  • 使用少數 TiDB 集羣替換大量的 MySQL 實例,根據不同業務底層設置不同的物理存儲隔離需求,讓數據庫數量大大減少,原本的升級、備份、參數設置等日常運維工作將大幅縮減,在資源隔離和性價比上達到平衡,大幅減少 DBA 日常的運維管理成本

我們的 HTAP 集羣目前有一個數據歸檔需求,整個集羣共約 330TB,考慮到成本和訪問頻率、性能等各方面需求,要求至少存儲 3 個月共約 80TB 到 ssd,250TB 存到 hdd,現在基於我們的大數據冷熱分離歸檔業務場景,本文重點探討冷熱數據歸檔存儲的功能和特性,以方便下一步我們正式應用到生產環境。

概述

TiDB 集羣通過 PD 節點(Placement Driver 組件)在系統內基於熱點、存儲容量等策略自動完成 region 的調度,從而實現集羣數據均衡、分散存儲在各個節點的目標,這些調度操作是集羣的自身管理行為,對用户而已幾乎是透明的,在之前的版本用户無法精確控制數據的存儲方式和位置。

TiDB 6.0 正式提供了數據放置框架(Placement Rules in SQL )功能,用户通過 SQL 配置數據在 TiKV 集羣中的放置位置,可以對數據進行直接的管理,以滿足不同的業務場景需要。用户可以將庫、表和分區指定部署至不同的地域、機房、機櫃、主機。還支持針對任意數據提供副本數、角色類型等維度的靈活調度管理能力,這使得在多業務共享集羣、跨中心部署、冷熱數據歸檔存儲等場景下,TiDB 得以提供更靈活更強大的數據管理能力。

該功能可以實現以下業務場景:

  • 動態指定重要數據的副本數,提高業務可用性和數據可靠性
  • 將最新數據存入 SSD,歷史數據存入 HDD,降低歸檔數據存儲成本
  • 把熱點數據的 leader 放到高性能的 TiKV 實例上,提供高效訪問
  • 不同業務共用一個集羣,而底層按業務實現存儲物理隔離,互不干擾,極大提升業務穩定性
  • 合併大量不同業務的 MySQL 實例到統一集羣,底層實現存儲隔離,減少管理大量數據庫的成本

原理簡介

早期版本的 Placement rule 使用時需要通過 pd-ctl 工具設置和查看,操作繁瑣且晦澀難懂。經過幾個版本的迭代和優化,推出的 PlacementRules in SQL 對用户更加友好,到了 v6.0.0 總體來説還是很方便理解和使用的,避免了使用 pd-ctl 工具配置的複雜性,大大降低使用門檻。

放置策略的實現依賴於 TiKV 集羣 label 標籤配置,需提前做好規劃(設置 TiKV 的 labels)。可通過show placement labels查看當前集羣所有可用的標籤。

```sql mysql> show placement labels ; +------+-----------------------------------------------------------------+ | Key | Values | +------+-----------------------------------------------------------------+ | disk | ["ssd"] | | host | ["tikv1", "tikv2", "tikv3"] | | rack | ["r1"] | | zone | ["guangzhou"] | +------+-----------------------------------------------------------------+ 4 rows in set (0.00 sec)

```

使用時有基礎用法和高級用法兩種方式。

(1) 基礎放置策略

基礎放置策略主要是控制 Raft leader 和 followers 的調度。

```sql #創建放置策略 CREATE PLACEMENT POLICY myplacementpolicy PRIMARY_REGION="guangzhou" REGIONS="guangzhou,shenzhen";

#將規則綁定至表或分區表,這樣指定了放置規則 CREATE TABLE t1 (a INT) PLACEMENT POLICY=myplacementpolicy; CREATE TABLE t2 (a INT); ALTER TABLE t2 PLACEMENT POLICY=myplacementpolicy;

#查看放置規則的調度進度,所有綁定規則的對象都是異步調度的。 SHOW PLACEMENT;

#查看放置策略 SHOW CREATE PLACEMENT POLICY myplacementpolicy\G select * from information_schema.placement_policies\G

#修改放置策略,修改後會傳播到所有綁定此放置策略的對象 ALTER PLACEMENT POLICY myplacementpolicy FOLLOWERS=5;

#刪除沒有綁定任何對象的放置策略 DROP PLACEMENT POLICY myplacementpolicy;

```

(2) 高級放置策略

基礎放置策略主要是針對 Raft leader 、Raft followers 的調度策略,如果需要更加靈活的方式,如不區分 region 角色將數據指定存儲在 hdd,需要使用高級放置策略。使用高級放置策略主要有兩個步驟,首先創建策略,然後在庫、表或分區上應用策略。

```sql # 創建策略,指定數據只存儲在ssd CREATE PLACEMENT POLICY storeonfastssd CONSTRAINTS="[+disk=ssd]";

# 創建策略,指定數據只存儲在hdd CREATE PLACEMENT POLICY storeonhdd CONSTRAINTS="[+disk=hdd]";

# 在分區表應用高級放置策略,指定分區存儲在hdd或者ssd上,未指定的分區由系統自動調度 CREATE TABLE t1 (id INT, name VARCHAR(50), purchased DATE) PARTITION BY RANGE( YEAR(purchased) ) ( PARTITION p0 VALUES LESS THAN (2000) PLACEMENT POLICY=storeonhdd, PARTITION p1 VALUES LESS THAN (2005), PARTITION p2 VALUES LESS THAN (2010), PARTITION p3 VALUES LESS THAN (2015), PARTITION p4 VALUES LESS THAN MAXVALUE PLACEMENT POLICY=storeonfastssd );

```

高級放置策略具體內容,請看官網介紹https://docs.pingcap.com/zh/tidb/stable/placement-rules-in-sql#%E9%AB%98%E7%BA%A7%E6%94%BE%E7%BD%AE

環境

| 角色 | 機器數 | 內存 | 數據盤 | CPU | OS | | --------- | ------ | ---- | ------------------ | ------------------------- | ----------------------------------------------- | | TiDB&TiPD | 3 | 256G | 1TB hdd | 40 cpu (20 core2 thread) | Debian 4.19.208-1 (2021-09-29) x86_64 GNU/Linux | | TiKV | 3 | 256G | 800GB ssd,1TB hdd | 40 cpu (20 core2 thread) | Debian 4.19.208-1 (2021-09-29) x86_64 GNU/Linux |

冷熱歸檔存儲

  • 目標:對給定的表按日期分區,將最新分區的數據存入 SSD,歷史數據存入 HDD

功能驗證

1.部署集羣並建立放置策略

  • 部署 TiDB v6.0.0 集羣,具體參考部署集羣操作

  • 創建數據落盤策略,以備使用

```sql # 應用該策略的庫、表、分區,數據會存儲在ssd上 CREATE PLACEMENT POLICY storeonssd CONSTRAINTS="[+disk=ssd]" ;

# 應用該策略的庫、表、分區,數據會存儲在hdd上 CREATE PLACEMENT POLICY storeonhdd CONSTRAINTS="[+disk=hdd]";

#查看集羣已有策略 mysql> show placement \G ***** 1. row **** Target: POLICY storeonhdd Placement: CONSTRAINTS="[+disk=hdd]" Scheduling_State: NULL *** 2. row ****** Target: POLICY storeonssd Placement: CONSTRAINTS="[+disk=ssd]" Scheduling_State: NULL 2 rows in set (0.02 sec)

```

2.創建庫表並應有放置策略

建立目標表為TiDB分區表並且按 Range 分區。

```sql # 創建數據庫tidb_ssd_hdd_test,並設置該庫默認落盤策略,設置後新建的表都會默認繼承該策略 create database tidb_ssd_hdd_test PLACEMENT POLICY=storeonssd;

# 查看策略已經應用到指定庫上 mysql> show placement \G ***** 1. row **** Target: POLICY storeonhdd Placement: CONSTRAINTS="[+disk=hdd]" Scheduling_State: NULL *** 2. row *** Target: POLICY storeonssd Placement: CONSTRAINTS="[+disk=ssd]" Scheduling_State: NULL *** 3. row ****** Target: DATABASE tidb_ssd_hdd_test Placement: CONSTRAINTS="[+disk=ssd]" Scheduling_State: SCHEDULED 3 rows in set (0.02 sec)

# 建立分區表,可以看到表建立後默認繼承和庫一樣的落盤策略,關鍵標識為“/T![placement] PLACEMENT POLICY=storeonssd /” CREATE TABLE logoutrole_log ( doc_id varchar(255) NOT NULL, gameid varchar(255) DEFAULT NULL , -- some fields logdt timestamp DEFAULT '1970-01-01 08:00:00' , updatetime varchar(255) DEFAULT NULL , UNIQUE KEY doc_id (doc_id,logdt), -- some index KEY logdt_gameid (logdt,gameid) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /T![placement] PLACEMENT POLICY=storeonssd / PARTITION BY RANGE ( UNIX_TIMESTAMP(logdt) ) ( PARTITION p20220416 VALUES LESS THAN (UNIX_TIMESTAMP('2022-04-17 00:00:00')), PARTITION p20220417 VALUES LESS THAN (UNIX_TIMESTAMP('2022-04-18 00:00:00')), PARTITION p20220418 VALUES LESS THAN (UNIX_TIMESTAMP('2022-04-19 00:00:00')), PARTITION p20220419 VALUES LESS THAN (UNIX_TIMESTAMP('2022-04-20 00:00:00')), PARTITION p20220420 VALUES LESS THAN (UNIX_TIMESTAMP('2022-04-21 00:00:00')), PARTITION p20220421 VALUES LESS THAN (UNIX_TIMESTAMP('2022-04-22 00:00:00')), PARTITION p20220422 VALUES LESS THAN (UNIX_TIMESTAMP('2022-04-23 00:00:00')) );

```

3.寫入熱數據到 ssd 盤並擴容 hdd 存儲節點

  • 集羣只有 3 個 ssd 的 tikv 節點,啟動 flink 流往目標表導入數據,可以看到這 3 個 ssd 節點的 region 數和空間使用在不斷增長

1650964998281.png

1650965222072.png

  • 在原有基礎上再擴容 3 個 hdd tikv 實例

1650965633758.png

4.冷熱分離

為了方便模擬數據的遷移,flink 導入的數據是全部落在 2022-04-16 這一天:

```sql mysql> select date(logdt) as day,count(0) from logoutrole_log group by day order by day ;
+------------+----------+ | day | count(0) | +------------+----------+ | 2022-04-16 | 1109819 | +------------+----------+ 1 row in set (1.09 sec)

```

停止 Flink 寫入後,設置數據分離放置策略,將存儲在 ssd 上的 2022-04-16 這一天的數據,轉存到 hdd 上,模擬冷數據歸檔操作:

sql mysql> alter table tidb_ssd_hdd_test.logoutrole_log partition p20220416 placement policy storeonhdd; Query OK, 0 rows affected (0.52 sec)

在應用 hdd 轉存策略後,如下圖可以看到調度規則裏 2022-04-16 這一天的分區 Placement 由 ssd 變為了 hdd,即集羣已經知曉最新的調度策略是將這一天的分區數據調度到 hdd 去,Scheduling_State 處於 PENDING 狀態,表示 Follower 的 raft log 與 Leader 有較大差距,在這裏可以理解為是正在處於調度的過程。

1650341702179.png

隨着時間的推移,數據在不斷從 ssd 遷移到 hdd 上。從集羣 grafana 監控面板可以看到 ssd 節點上的 region 數據在不斷下降,直到降到接近於 0;相反,hdd 上的 region 數不斷上升,直到數據全部遷出 ssd 節點。110 萬行數據從 ssd 遷移到 hdd,大約耗時 3min 。

1650342094048.png

在數據全部遷如 hdd 節點後,查看調度進度,此時 Scheduling_State 處於 SCHEDULED 完成調度狀態:

1650342133243.png

結論:

  • 證明冷熱數據隔離存儲策略已經生效,ssd 上的數據完成遷移到 hdd 上,且 ssd 的空間得以釋放,符合數據歸檔的目標。

靜態集羣冷熱存儲分離(無外部訪問)

ssd->hdd

繼續通過 flink 寫入數據到 2022-04-17 分區,然後停流使集羣沒有外部訪問流量,將此分區上 ssd 數據遷移到 hdd。

alter table tidb_ssd_hdd_test.logoutrole_log partition p20220417 placement policy storeonhdd;

1650970144694.png

ssd 上的 region 全部遷移到 hdd 上,ssd 空間被釋放,hdd 空間使用逐漸增加,遷移過程中 ssd 和 hdd 的 IO 消耗都在 5%左右,內存和網絡帶寬使用不變、保持平穩。 約 6 千萬行 130GB 數據從 ssd 數據遷移到 hdd 大概需要 2 個小時

結論:

  • 在將大規模數據從 ssd 數據遷移到 hdd 過程,集羣資源消耗比較低,可以有效避免過多佔用集羣資源。
  • 在集羣沒有外部訪問壓力時,在默認配置下,集羣以每小時約 3000 萬行的速度從 ssd 遷移到 hdd 節點。

hdd->ssd

在沒有外部流量訪問時,將數據從 hdd 遷移回 ssd,從監控圖可以看到,hdd 節點的 tikv 的 leader 數、region 數在此期間都在下降,分別從 850、2500 逐漸下降直到為 0,磁盤空間也從 62GB 下降為 0,表示數據在持續遷移出 hdd 節點;

1652425488812.png

1652425944226.png

相反地,由於數據不斷遷入到 ssd 中,ssd 節點的 tikv 的 leader 數、region 數在此期間都在上升,分別從 1500、4200 逐漸上升到 2200、6700,直到數據遷入完成,然後保持數量不變,ssd 的磁盤空間消耗也從 100GB 上升到 161GB。

遷移的過程中,ssd 和 hdd 節點的 IO 使用率都比較低,如下圖:

1652426155311.png

結論:

  • 將冷數據從 hdd 遷移至 ssd,遷移 1.7 億行共約 200GB 數據,大約耗時 2 小時 40 分鐘,平均每小時遷移 6300 萬行,速度約為將熱數據從 ssd 遷到 hdd 的 2 倍(每小時約 3000 萬行)
  • 將數據從 hdd 遷移至 ssd 的過程,不管是對 ssd 還是 hdd,其平均 IO 使用率都不高,不會佔用過多集羣的資源,可以認為數據遷移過程對集羣正在運行的業務影響不大

熱集羣冷熱存儲分離(外部持續訪問)

繼續持續寫入數據到 2022-04-18 和 2022-04-19 的 ssd 分區,然後不停流保持持續的寫入壓力,遷移 2022-04-18 數據從 ssd 到 hdd,觀察集羣表現。

```sql

應用放置策略將2022-04-18數據從ssd歸檔到hdd

alter table tidb_ssd_hdd_test.logoutrole_log partition p20220418 placement policy storeonhdd; ```

在歸檔過程,flink 同時持續以 2100 的 QPS 寫入熱數據,期間 ssd IO 接近 100%,hdd 的 IO 消耗在 10%以下,各節點 CPU 在 500%以下,網絡帶寬在 200MB/s 以下,內存使用保持平穩。

從 region 數變化的角度來看:

  • 在歸檔數據時,ssd 的 tikv region 數從 6300 下降到 3500 左右,當遷移完成後是淨寫入數據,此時 ssd 節點的 region 數量又持續上升;
  • hdd 節點的 region 數從開始的 2600 上升到 6500 左右,隨着數據遷移完成,hdd 的 region 數不再增加,一直保持 6500 不變。

1650971789523.png

從磁盤使用空間變化的角度來看:

  • 歸檔數據時,ssd 節點的磁盤使用空間從 152GB 下降到 88GB,當遷移完成後,此時是淨寫入數據,ssd 空間開始上升;
  • 數據在不斷寫入到 hdd 節點,所以其使用空間從 61GB 上升到 154GB,隨着數據遷移完成,一直保持不變

1650593578630.png

1650593565818.png

1650593789799.png

結論:

  • 在有外部幾乎是滿 IO 的寫入壓力時,歸檔約 2 億行、400GB 數據從 ssd 到 hdd 節點,大概需要 6 個小時,即約 3300 萬行/小時,可以説冷數據的歸檔效率還是比較高的
  • 集羣后台在進行數據歸檔時,flink 的 sink QPS 變化不大,可以認為歸檔的過程對集羣正常寫入影響不大

歸檔數據補寫

業務上有補全歷史數據的場景,比如數據重算等,這裏模擬補全歷史冷數據,寫入到 hdd。

  • 2022-04-16 這一天的數據已經全部轉存到 hdd 冷盤中。啟動 flink 流,繼續對 2022-04-16 分區寫入數據,這些只會寫 hdd,不會寫入 ssd。flink 流以 2000 左右的 sink QPS 補全冷數據,hdd tikv 節點 IO 打滿,SSD 的 IO 使用率比較低。

1650969265594.png

從下圖可以看到,在補全冷數據的時候, hdd 節點的 region 數在不斷上升,hdd tikv 的空間消耗也在不斷增加,而 ssd 的空間使用和 region 數均保持不變,説明數據並不會寫入 ssd 中,符合預期。

1650969430703.png

結論:

  • 説明 TiDB 冷熱數據分離存儲功能,在補全歷史冷數據的場景,即歸檔數據補寫,數據可以正確地直接寫入到 hdd,期間數據不會經過 ssd
  • 補全冷數據,hdd tikv 節點 IO 打滿,ssd 的 IO 使用率比較低,也説明數據不會經過 ssd

同一集羣業務隔離

除了冷熱數據歸檔外,我們線上不同的業務線通常採用一套或多套 MySQL 來管理,但因為業務多導致 MySQL 有數百個,日常的監控、診斷、版本升級、安全防護等工作對運維團隊造成了巨大的壓力,且隨着業務規模越來越大,管理的成本不斷上升。

使用 Placement rule 功能可以很容易靈活的集羣共享規則。可以將不同 MySQL 上的業務遷移到同一個 TiDB 集羣,實現多個不同業務的共用一個集羣而底層提供物理存儲隔離,有效減少大量 MySQL 的管理成本。這個也是我們接下來會繼續推進優化的地方。

舉例説明,業務 A和B 共享資源,降低存儲和管理成本,而業務 C 和 D 獨佔資源,提供最高的隔離性。由於多個業務共享一套 TiDB 集羣,升級、打補丁、備份計劃、擴縮容等日常運維管理頻率可以大幅縮減,降低管理負擔提升效率

1651723818212.png

```sql CREATE PLACEMENT POLICY 'shared_nodes' CONSTRAINTS = "[+region=shared_nodes]"; CREATE PLACEMENT POLICY 'business_c' CONSTRAINTS = "[+region=business_c]"; CREATE PLACEMENT POLICY 'business_d' CONSTRAINTS = "[+region=business_d]";

ALTER DATABASE a POLICY=shared_nodes; ALTER DATABASE b POLICY=shared_nodes; ALTER DATABASE c POLICY=business_c; ALTER DATABASE d POLICY=business_d; ```

基於 SQL 接口的數據放置規則,你僅僅使用少數 TiDB 集羣管理大量的 MySQL 實例,不同業務的數據放置到不同的 DB,並通過放置規則管理將不同 DB 下的數據調度到不同的硬件節點上,實現業務間數據的物理資源隔離,避免因資源爭搶,硬件故障等問題造成的相互干擾。通過賬號權限管理避免跨業務數據訪問,提升數據質量和數據安全。在這種部署方式下,集羣數量大大減小,原本的升級,監控告警設置等日常運維工作將大幅縮減,在資源隔離和性價比上達到平衡,大幅減少日常的 DBA 運維管理成本

總結

1.冷熱分離存儲,降低存儲成本

  • TiDB 6.0 正式支持數據冷熱存儲分離,可以降低 SSD 使用成本。使用 TiDB 6.0 的數據放置功能,可以在同一個集羣實現海量數據的冷熱存儲,將新的熱數據存入 SSD,歷史冷數據存入 HDD,降低歷史歸檔數據存儲成本。
  • 將熱數據從 ssd 遷移到 hdd,每小時可歸檔約 3000 萬行,總體來看效率還是比較高的
  • 分離存儲過程,ssd 和 hdd 用於歸檔的 IO 消耗都在 10%以內,集羣訪問 QPS 表現平穩,對業務訪問的影響較小
  • 在補寫冷數據到 hdd 場景,數據可正確地直接寫入 hdd,不會經過 ssd。flink 補寫冷數據時滿 IO 每秒寫入約 4000 行,每小時寫入約 1500 萬行。

2.業務底層物理隔離,實現同一集羣不同存儲

  • 通過放置規則管理將不同數據庫下的數據調度到不同的硬件節點上,實現業務間數據的物理資源隔離,避免因資源爭搶,硬件故障等問題造成的相互干擾
  • 通過賬號權限管理避免跨業務數據訪問,提升數據質量和數據安全

3.合併MySQL業務,降低運維壓力,提升管理效率

  • 使用少數 TiDB 集羣替換大量的 MySQL 實例,根據不同業務底層設置不同的物理存儲隔離需求,讓數據庫數量大大減少,原本的升級、備份、參數設置等日常運維工作將大幅縮減,在資源隔離和性價比上達到平衡,大幅減少 DBA 日常的運維管理成本

4.放置策略應用操作步驟

  • 對已有集羣應用 Placement Rules
  • 將集羣升級到 6.0.0 版本
  • 創建默認 SSD 策略
  • 打開放置策略默認開關,使得集羣已有庫表都默認存儲在 ssd 上 (該功能依賴官方發佈新版本支持)
  • 目前只能用腳本 alter 全部庫設置這個默認策略,如果有新增的庫也需要提前進行設置
  • 申請新機器並擴容新的 hdd tikv
  • 創建 hdd 放置策略
  • 在目標表的目標分區上指定 ssd 或 hdd 策略
  • 定期將過期分區聲明 hhd 放置策略

  • 對新建的集羣應用 Placement Rules

  • 部署 6.0.0 集羣版本
  • 創建默認 SSD 策略
  • 創建的全部庫都先設置這個默認策略
  • 申請新機器並擴容新的 hdd tikv
  • 創建 hdd 放置策略
  • 在目標表或目標分區上指定 ssd 或 hdd 策略
  • 定期將過期分區聲明 hhd 放置策略