1. TiDB概述
TiDB 是一款開源 分散式關係型資料庫,同時支援 線上事務處理(OLTP) 與 線上分析處理(OLAP) 的混合型(Hybrid Transactional and Analytical Processing, HTAP) 分散式資料庫,具備水平擴容或縮容、金融級高可用、實時 HTAP、Kubernetes 雲原生的分散式資料庫、相容 MySQL 5.7 協議和 MySQL 生態等重要特性,支援在本地和雲上部署。
與傳統的單機 MySQL 資料庫相比,TiDB 具有以下優勢:
-
分散式架構: 純分散式架構,擁有良好的擴充套件性,支援彈性的擴縮容
-
相容MySQL: 支援 SQL,對外暴露 MySQL 的網路協議,併相容大多數 MySQL 的語法,在大多數場景下可以直接替換 MySQL
-
高可用部署: 預設支援高可用,在少數副本失效的情況下,資料庫本身能夠自動進行資料修復和故障轉移,對業務透明
-
支援強一致性: 符合CAP理論的CP,支援 ACID 事務,對於一些有強一致需求的場景友好,例如:銀行轉賬
-
豐富的開源生態鏈: 具有豐富的工具鏈生態,覆蓋資料遷移、同步、備份等多種場景
2. TiDB元件
在核心設計上,TiDB 分散式資料庫將整體架構拆分成了多個模組,各模組之間互相通訊,組成完整的 TiDB 系統。對應的架構圖如下:
計算引擎層:TiDB/TiSpark
儲存引擎層:TiKV/TiFlash
3. TiKV鍵值對資料是如何組織的
1. 表資料對映到KV
由於 TiDB 底層基於鍵值對儲存資料,TiDB 表中的 行資料 需要按照一定格式對映轉換為 鍵值對:
-
為了保證同一張表的資料放在一起,方便查詢,TiDB 會為每個表分配一個 表 ID,用 TableID 表示。表 ID 是一個整數,在整個 叢集內唯一。
-
TiDB 會為表中每行資料分配一個 行 ID,用 RowID 表示。行 ID 也是一個整數,在表內唯一。對於行 ID,TiDB 做了一個小最佳化,如果某個表有整數型的主鍵,TiDB 會使用主鍵的值當做這一行資料的行 ID。
每行資料按照如下規則編碼成 (Key, Value) 鍵值對:
Key: tablePrefix{TableID}_recordPrefixSep{RowID}
Value: [col1, col2, col3, col4]
2. 表索引對映到KV
TiDB 同時支援 主鍵索引 和 二級索引。與表資料對映方案類似,TiDB 為表中每個索引分配了一個 索引 ID,用 IndexID 表示。
-
對於 主鍵索引 和 唯一索引,需要根據鍵值快速定位到對應的 RowID,因此,按照如下規則編碼成 (Key, Value) 鍵值對:
Key: tablePrefix{TableID}_indexPrefixSep{IndexID}_indexedColumnsValue
Value: RowID
-
對於非唯一性約束的 普通二級索引,一個鍵值可能 對應多行,需要根據 鍵值範圍 查詢對應的 RowID。因此,按照如下規則編碼成 (Key, Value) 鍵值對:
Key: tablePrefix{TableID}_indexPrefixSep{IndexID}indexedColumnsValue{RowID}
Value: null
3. KV對映示例
資料與 KV 的對映關係,定義如下:
tablePrefix = []byte{'t'}recordPrefixSep = []byte{'r'}indexPrefixSep = []byte{'i'}1.2.3.
假設表結構如下:
CREATE_TABLE User ( ID int, Name varchar(20), Role varchar(20), Age int, UID int, PRIMARY KEY (ID), KEY idxAge (Age), UNIQUE KEY idxUID (UID));1.2.3.4.5.6.7.8.9.10.
假設表資料如下:
1, "TiDB", "SQL Layer", 10, 100012, "TiKV", "KV Engine", 20, 100023, "PD", "Manager", 30, 100031.2.3.
-
表資料對映到KV如下:
t10_r1 --> ["TiDB", "SQL Layer", 10, 10001]t10_r2 --> ["TiKV", "KV Engine", 20, 10002]t10_r3 --> ["PD", "Manager", 30, 10003]1.2.3.
-
唯一索引對映到KV如下:
t10_i1_10001 --> 1t10_i2_10002 --> 2t10_i3_10003 --> 31.2.3.
-
非唯一索引對映到KV如下:
# 假設 IndexID 為 1t10_i1_10_1 --> nullt10_i1_20_2 --> nullt10_i1_30_3 --> null1.2.3.4