小試國產開源HTAP分散式NewSQL資料庫TiDB-v5.3.0

itxiaoshen發表於2021-12-30

概述

定義

TiDB官網 https://pingcap.com/zh/ 最新版本為5.3.0

TiDB GitHub原始碼 https://github.com/pingcap/tidb

TiDB是由國內PingCAP公司自主設計、研發的開源分散式關係型資料庫,是一款同時支援線上事務處理與線上分析處理 (Hybrid Transactional and Analytical Processing, HTAP,混合事務和分析處理,在同一個資料庫系統同時支援OLTP和OLAP) 的融合型分散式資料庫產品,具備水平擴容或者縮容、金融級高可用、實時 HTAP、雲原生的分散式資料庫、相容 MySQL 5.7 協議和 MySQL 生態等重要特性,遷移便捷,運維成本極低。

目前國產分散式資料庫排名前三資料庫有TiDB、OceanBase、PolarDB-X;OceanBase為螞蟻集團完全自主研發,誕生較久早在2010年就開始建設;PolarDB-X則為阿里巴巴自主研發的雲原生分散式資料庫。TiDB是採用Go語言編寫,越來越多開源專案選擇Go,TiDB目標是為使用者提供一站式 OLTP (Online Transactional Processing-線上事務處理)、OLAP (Online Analytical Processing-線上資料分析)、HTAP 解決方案。TiDB官方提供社群版(開源)和企業版(付費)。

與傳統單機資料庫對比優勢

  • 純分散式架構,擁有良好的擴充套件性,支援彈性的擴縮容。
  • 支援 SQL,對外暴露 MySQL 的網路協議,併相容大多數 MySQL 的語法,在大多數場景下可以直接替換 MySQL。
  • 預設支援高可用,在少數副本失效的情況下,資料庫本身能夠自動進行資料修復和故障轉移,對業務透明。
  • 支援 ACID 事務,對於一些有強一致需求的場景友好,例如:銀行轉賬。
  • 具有豐富的工具鏈生態,覆蓋資料遷移、同步、備份等多種場景。

官方工具

  • 安裝部署
    • TiUP
    • TiDB Operator
  • 資料流轉
    • 資料遷入 - TiDB Data Migration
    • 增量資料遷出 - TiCDC
    • 資料匯入 - TiDB Lightning
    • 資料匯出 - Dumpling
  • 叢集容災
    • Backup & Restore
  • 運維和視覺化
    • TiDB Dashboard

核心特性

  • 一鍵水平擴容或者縮容:得益於 TiDB 儲存計算分離的架構的設計,可按需對計算、儲存分別進行線上擴容或者縮容,擴容或者縮容過程中對應用運維人員透明。
  • 金融級高可用:資料採用多副本儲存,資料副本通過 Multi-Raft 協議同步事務日誌,多數派寫入成功事務才能提交,確保資料強一致性且少數副本發生故障時不影響資料的可用性。可按需配置副本地理位置、副本數量等策略滿足不同容災級別的要求。
  • 實時 HTAP:提供行儲存引擎 TiKV、列儲存引擎 TiFlash 兩款儲存引擎,TiFlash 通過 Multi-Raft Learner 協議實時從 TiKV 複製資料,確保行儲存引擎 TiKV 和列儲存引擎 TiFlash 之間的資料強一致。TiKV、TiFlash 可按需部署在不同的機器,解決 HTAP 資源隔離的問題。
  • 雲原生的分散式資料庫:專為雲而設計的分散式資料庫,通過 TiDB Operator 可在公有云、私有云、混合雲中實現部署工具化、自動化。
  • 相容 MySQL 5.7 協議和 MySQL 生態:相容 MySQL 5.7 協議、MySQL 常用的功能、MySQL 生態,應用無需或者修改少量程式碼即可從 MySQL 遷移到 TiDB。提供豐富的資料遷移工具幫助應用便捷完成資料遷移。

產品特點

  • 融合的資料平臺:打破資料壁壘,合而為一。事務性與分析型處理完全基於一體化的資料基座。
  • 實時的商業分析:線上資料分析與決策,分秒必爭。強一致性保障基於資料的決策,分毫不差。
  • 敏捷的業務創新:資料庫,亦服務;雲原生,高彈性;金融級高可用。
  • 開放的生態系統:基於 CNCF 專案的中國領先開源社群。無縫支援多雲架構對接豐富的資料工具生態。

應用場景

  • 對資料一致性及高可靠、系統高可用、可擴充套件性、容災要求較高的金融行業屬性的場景。
  • 對儲存容量、可擴充套件性、併發要求較高的海量資料及高併發的 OLTP 場景。
  • Real-time HTAP 場景。
  • 資料匯聚、二次加工處理的場景。

部署

部署規劃

單臺 Linux 伺服器, TiDB最小規模的 TiDB 叢集拓撲,模擬生產環境下的部署步驟。

例項 個數 IP 配置
TiKV 3 192.168.50.95、192.168.50.95、192.168.50.95 避免埠和目錄衝突
TiDB 1 192.168.50.95 預設埠 全域性目錄配置
PD 1 192.168.50.95 預設埠 全域性目錄配置
TiFlash 1 192.168.50.95 預設埠 全域性目錄配置
Monitor 1 192.168.50.95 預設埠 全域性目錄配置

單機部署叢集

# 下載並安裝 TiUP
curl --proto '=https' --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh
# 宣告全域性環境變數,本人使用的是root安裝
source /root/.bash_profile
# 安裝 TiUP 的 cluster 元件
tiup cluster
# 由於模擬多機部署,需要通過 root 使用者調大 sshd 服務的連線數限制,修改 /etc/ssh/sshd_config 將 MaxSessions 調至 20。重啟 sshd 服務
service sshd restart
# 建立啟動叢集的yaml配置檔案,內容如下
vi topo.yaml
global:
 user: "tidb"
 ssh_port: 22
 deploy_dir: "/tidb-deploy"
 data_dir: "/tidb-data"

# # Monitored variables are applied to all the machines.
monitored:
 node_exporter_port: 9100
 blackbox_exporter_port: 9115

server_configs:
 tidb:
   log.slow-threshold: 300
 tikv:
   readpool.storage.use-unified-pool: false
   readpool.coprocessor.use-unified-pool: true
 pd:
   replication.enable-placement-rules: true
   replication.location-labels: ["host"]
 tiflash:
   logger.level: "info"

pd_servers:
 - host: 192.168.50.95

tidb_servers:
 - host: 192.168.50.95

tikv_servers:
 - host: 192.168.50.95
   port: 20160
   status_port: 20180
   config:
     server.labels: { host: "tikv-host-1" }

 - host: 192.168.50.95
   port: 20161
   status_port: 20181
   config:
     server.labels: { host: "tikv-host-2" }

 - host: 192.168.50.95
   port: 20162
   status_port: 20182
   config:
     server.labels: { host: "tikv-host-3" }

tiflash_servers:
 - host: 192.168.50.95

monitoring_servers:
 - host: 192.168.50.95

grafana_servers:
 - host: 192.168.50.95

儲存內容後下面進行正式部署和啟動

# 執行叢集部署命令,叢集的名稱和我們配置檔案一致tidb-cluster,叢集版本可以通過 tiup list tidb 命令來檢視當前支援部署的 TiDB 版本
tiup cluster deploy tidb-cluster v5.3.0 ./topo.yaml --user root -p
# 執行上面的命令出現下面的提示後按照引導,輸入”y”及 root 密碼,來完成部署

image-20211225180219626

# 啟動叢集:
tiup cluster start tidb-cluster
#檢視當前已經部署的叢集列表
tiup cluster list
# 檢視叢集的拓撲結構和狀態
tiup cluster display tidb-cluster

image-20211225182548773

# 由於我本機已安裝mysql,所以可以直接執行mysql客戶端,訪問 TiDB 資料庫,密碼為空
mysql -h 192.168.50.95 -P 4000 -u root

image-20211225181723827

訪問TiDB的Grafana監控監控頁面,預設使用者名稱和密碼均為admin, http://192.168.50.95:3000
訪問TiDB叢集Dashboard監控頁面, 預設使用者名稱為root,密碼為空,http://192.168.50.95:2379/dashboard

image-20211225184951040

體驗HTAP

基本概念

  • HTAP 儲存引擎:行存 (Row-store) 與列存 (columnar-store) 同時存在,自動同步,保持強一致性。行存為線上事務處理 OLTP 提供優化,列存則為線上分析處理 OLAP 提供效能優化。
  • HTAP 資料一致性:作為一個分散式事務型的鍵值資料庫,TiKV 提供了滿足 ACID 約束的分散式事務介面,並通過Raft協議保證了多副本資料一致性以及高可用。TiFlash 通過 Multi-Raft Learner 協議實時從 TiKV 複製資料,確保與 TiKV 之間的資料強一致。
  • HTAP 資料隔離性:TiKV、TiFlash 可按需部署在不同的機器,解決 HTAP 資源隔離的問題。
  • MPP 計算引擎:從 v5.0 版本起,TiFlash 引入了分散式計算框架MPP,允許節點之間的資料交換並提供高效能、高吞吐的 SQL 演算法,可以大幅度縮短分析查詢的執行時間。

體驗

# 啟動 TiDB 叢集
tiup playground
# 使用以下命令安裝資料生成工具
tiup install bench
# 使用以下命令生成資料,當命令列輸出Finished時,表示資料生成完畢。
tiup bench tpch --sf=1 prepare

適用場景

TiDB HATP 可以滿足企業海量資料的增產需求、降低運維的風險成本、與現有的大資料棧無縫結合,從而實現資料資產價值的實時變現,以下是三種 HTAP 典型適用場景:

  • 混合負載場景:當將 TiDB 應用於線上實時分析處理的混合負載場景時,開發人員只需要提供一個入口,TiDB 將自動根據業務型別選擇不同的處理引擎。
  • 實時流處理場景:當將 TiDB 應用於實時流處理場景時,TiDB 能保證源源不斷流入系統的資料實時可查,同時可兼顧高併發資料服務與 BI 查詢。
  • 資料中樞場景:當將 TiDB 應用於資料中樞場景時,TiDB 作為資料中樞可以無縫連線資料業務層和資料倉儲層,滿足不同業務的需求。

架構

總體架構

image-20211225195741729

  • TiDB Server:SQL 層,對外暴露 MySQL 協議的連線 endpoint,負責接受客戶端的連線,執行 SQL 解析和優化,最終生成分散式執行計劃。TiDB 層本身是無狀態的,實踐中可以啟動多個 TiDB 例項,通過負載均衡元件(如 LVS、HAProxy 或 F5)對外提供統一的接入地址,客戶端的連線可以均勻地分攤在多個 TiDB 例項上以達到負載均衡的效果。TiDB Server 本身並不儲存資料,只是解析 SQL,將實際的資料讀取請求轉發給底層的儲存節點 TiKV(或 TiFlash)。
  • PD (Placement Driver) Server:整個 TiDB 叢集的元資訊管理模組,負責儲存每個 TiKV 節點實時的資料分佈情況和叢集的整體拓撲結構,提供 TiDB Dashboard 管控介面,併為分散式事務分配事務 ID。PD 不僅儲存元資訊,同時還會根據 TiKV 節點實時上報的資料分佈狀態,下發資料排程命令給具體的 TiKV 節點,可以說是整個叢集的“大腦”。此外,PD 本身也是由至少 3 個節點構成,擁有高可用的能力。建議部署奇數個 PD 節點。
  • 儲存節點
    • TiKV Server:負責儲存資料,從外部看 TiKV 是一個分散式的提供事務的 Key-Value 儲存引擎。儲存資料的基本單位是 Region,每個 Region 負責儲存一個 Key Range(從 StartKey 到 EndKey 的左閉右開區間)的資料,每個 TiKV 節點會負責多個 Region。TiKV 的 API 在 KV 鍵值對層面提供對分散式事務的原生支援,預設提供了 SI (Snapshot Isolation) 的隔離級別,這也是 TiDB 在 SQL 層面支援分散式事務的核心。TiDB 的 SQL 層做完 SQL 解析後,會將 SQL 的執行計劃轉換為對 TiKV API 的實際呼叫。所以,資料都儲存在 TiKV 中。另外,TiKV 中的資料都會自動維護多副本(預設為三副本),天然支援高可用和自動故障轉移。
    • TiFlash:TiFlash 是一類特殊的儲存節點。和普通 TiKV 節點不一樣的是,在 TiFlash 內部,資料是以列式的形式進行儲存,主要的功能是為分析型的場景加速。
  • TiSpark 作為 TiDB 中解決使用者複雜 OLAP 需求的主要元件,將 Spark SQL 直接執行在 TiDB 儲存層上,同時融合 TiKV 分散式叢集的優勢,並融入大資料社群生態。至此,TiDB 可以通過一套系統,同時支援 OLTP 與 OLAP,免除使用者資料同步的煩惱。

image-20211225200755421

  • TiKV 的選擇是 Key-Value 模型,並且提供有序遍歷方法

    • 巨大的 Map,也就是儲存的是 Key-Value Pairs(鍵值對)。
    • Map 中的 Key-Value pair 按照 Key 的二進位制順序有序,也就是可以 Seek 到某一個 Key 的位置,然後不斷地呼叫 Next 方法以遞增的順序獲取比這個 Key 大的 Key-Value。
  • 本地儲存

    • TiKV把資料儲存在 RocksDB 中,具體的資料落地由 RocksDB 負責, RocksDB 是由 Facebook 開源的一個非常優秀的單機 KV 儲存引擎,可以滿足 TiKV 對單機引擎的各種要求。這裡可以簡單的認為 RocksDB 是一個單機的持久化 Key-Value Map。
  • Raft協議

    • 通過單機的 RocksDB,TiKV 可以將資料快速地儲存在磁碟上;通過 Raft,將資料複製到多臺機器上,以防單機失效。資料的寫入是通過 Raft 這一層的介面寫入,而不是直接寫 RocksDB。通過實現 Raft,TiKV 變成了一個分散式的 Key-Value 儲存,少數幾臺機器當機也能通過原生的 Raft 協議自動把副本補全,可以做到對業務無感知。

      image-20211225201138946

  • Region

    • 按照 Key 分 Range,某一段連續的 Key 都儲存在一個儲存節點上,將整個 Key-Value 空間分成很多段,每一段是一系列連續的 Key,將每一段叫做一個 Region,並且會盡量保持每個 Region 中儲存的資料不超過一定的大小,目前在 TiKV 中預設是 96MB。每一個 Region 都可以用 [StartKey,EndKey) 這樣一個左閉右開區間來描述。
      • 以 Region 為單位,將資料分散在叢集中所有的節點上,並且儘量保證每個節點上服務的 Region 數量差不多。
      • 以 Region 為單位做 Raft 的複製和成員管理。
    • 以 Region 為單位做資料的分散和複製,TiKV 就成為了一個分散式的具備一定容災能力的 KeyValue 系統,不用再擔心資料存不下,或者是磁碟故障丟失資料的問題。

    image-20211225212616844

  • MVCC:TiKV 的 MVCC 實現是通過在 Key 後面新增版本號來實現。

  • 分散式事務:TiKV 的事務採用的是 Google 在 BigTable 中使用的事務模型。

計算

  • 表資料與 Key-Value 的對映關係

  • 索引資料和 Key-Value 的對映關係

  • 後設資料管理

    • TiDB 中每個 DatabaseTable 都有元資訊,也就是其定義以及各項屬性。這些資訊也需要持久化,TiDB 將這些資訊也儲存在了 TiKV 中。
  • SQL層

    • TiDB 的 SQL 層,即 TiDB Server,負責將 SQL 翻譯成 Key-Value 操作,將其轉發給共用的分散式 Key-Value 儲存層 TiKV,然後組裝 TiKV 返回的結果,最終將查詢結果返回給客戶端。

    • SQL計算

      image-20211225213054327

    • 計算應該需要儘量靠近儲存節點,以避免大量的 RPC 呼叫。首先,SQL 中的謂詞條件 name = "TiDB" 應被下推到儲存節點進行計算,這樣只需要返回有效的行,避免無意義的網路傳輸。然後,聚合函式 Count(*) 也可以被下推到儲存節點,進行預聚合,每個節點只需要返回一個 Count(*) 的結果即可,再由 SQL 層將各個節點返回的 Count(*) 的結果累加求和。

image-20211225213130534

  • SQL 層架構

    • 使用者的 SQL 請求會直接或者通過 Load Balancer 傳送到 TiDB Server,TiDB Server 會解析 MySQL Protocol Packet,獲取請求內容,對 SQL 進行語法解析和語義分析,制定和優化查詢計劃,執行查詢計劃並獲取和處理資料。資料全部儲存在 TiKV 叢集中,所以在這個過程中 TiDB Server 需要和 TiKV 互動,獲取資料。最後 TiDB Server 需要將查詢結果返回給使用者。

    image-20211225213556621

排程

PD (Placement Driver) 是 TiDB 叢集的管理模組,同時也負責叢集資料的實時排程。本文件介紹一下 PD 的設計思想和關鍵概念。

第一類:作為一個分散式高可用儲存系統,必須滿足的需求,包括幾種

  • 副本數量不能多也不能少
  • 副本需要根據拓撲結構分佈在不同屬性的機器上
  • 節點當機或異常能夠自動合理快速地進行容災

第二類:作為一個良好的分散式系統,需要考慮的地方包括

  • 維持整個叢集的 Leader 分佈均勻
  • 維持每個節點的儲存容量均勻
  • 維持訪問熱點分佈均勻
  • 控制負載均衡的速度,避免影響線上服務
  • 管理節點狀態,包括手動上線/下線節點

滿足上面需求首先需要收集足夠的資訊,比如每個節點的狀態、每個 Raft Group 的資訊、業務訪問操作的統計等;其次需要設定一些策略,PD 根據這些資訊以及排程的策略,制定出儘量滿足前面所述需求的排程計劃;最後需要一些基本的操作,來完成排程計劃。

排程依賴於整個叢集資訊的收集,簡單來說,排程需要知道每個 TiKV 節點的狀態以及每個 Region 的狀態。TiKV 叢集會向 PD 彙報兩類訊息,TiKV 節點資訊和 Region 資訊。

  • 排程策略
    • 一個 Region 的副本數量正確
    • 一個 Raft Group 中的多個副本不在同一個位置
    • 副本在 Store 之間的分佈均勻分配
    • Leader 數量在 Store 之間均勻分配
    • 訪問熱點數量在 Store 之間均勻分配
    • 各個 Store 的儲存空間佔用大致相等
    • 控制排程速度,避免影響線上服務
  • 排程的實現
    • PD 不斷地通過 Store 或者 Leader 的心跳包收集整個叢集資訊,並且根據這些資訊以及排程策略生成排程操作序列。每次收到 Region Leader 發來的心跳包時,PD 都會檢查這個 Region 是否有待進行的操作,然後通過心跳包的回覆訊息,將需要進行的操作返回給 Region Leader,並在後面的心跳包中監測執行結果。

儲存引擎

TiKV

TiKV 是一個分散式事務型的鍵值資料庫,提供了滿足 ACID 約束的分散式事務介面,並且通過Raft協議保證了多副本資料一致性以及高可用。TiKV 作為 TiDB 的儲存層,為使用者寫入 TiDB 的資料提供了持久化以及讀寫服務,同時還儲存了 TiDB 的統計資訊資料。

  • Region 與 RocksDB:雖然 TiKV 將資料按照範圍切割成了多個 Region,但是同一個節點的所有 Region 資料仍然是不加區分地儲存於同一個 RocksDB 例項上,而用於 Raft 協議複製所需要的日誌則儲存於另一個 RocksDB 例項。這樣設計的原因是因為隨機 I/O 的效能遠低於順序 I/O,所以 TiKV 使用同一個 RocksDB 例項來儲存這些資料,以便不同 Region 的寫入可以合併在一次 I/O 中。
  • Region 與 Raft 協議:Region 與副本之間通過 Raft 協議來維持資料一致性,任何寫請求都只能在 Leader 上寫入,並且需要寫入多數副本後(預設配置為 3 副本,即所有請求必須至少寫入兩個副本成功)才會返回客戶端寫入成功。
  • RocksDB是由 Facebook 基於 LevelDB 開發的一款提供鍵值儲存與讀寫功能的 LSM-tree 架構引擎。使用者寫入的鍵值對會先寫入磁碟上的 WAL (Write Ahead Log),然後再寫入記憶體中的跳錶(SkipList,這部分結構又被稱作 MemTable)。LSM-tree 引擎由於將使用者的隨機修改(插入)轉化為了對 WAL 檔案的順序寫,因此具有比 B 樹類儲存引擎更高的寫吞吐。記憶體中的資料達到一定閾值後,會刷到磁碟上生成 SST 檔案 (Sorted String Table),SST 又分為多層(預設至多 6 層),每一層的資料達到一定閾值後會挑選一部分 SST 合併到下一層,每一層的資料是上一層的 10 倍(因此 90% 的資料儲存在最後一層)。RocksDB 允許使用者建立多個 ColumnFamily ,這些 ColumnFamily 各自擁有獨立的記憶體跳錶以及 SST 檔案,但是共享同一個 WAL 檔案,這樣的好處是可以根據應用特點為不同的 ColumnFamily 選擇不同的配置,但是又沒有增加對 WAL 的寫次數。

TiFlash

TiFlash 是 TiDB HTAP 形態的關鍵元件,它是 TiKV 的列存擴充套件,在提供了良好的隔離性的同時,也兼顧了強一致性。列存副本通過 Raft Learner 協議非同步複製,但是在讀取的時候通過 Raft 校對索引配合 MVCC 的方式獲得 Snapshot Isolation 的一致性隔離級別。這個架構很好地解決了 HTAP 場景的隔離性以及列存同步的問題。

image-20211229214022873

上圖為 TiDB HTAP 形態架構,其中包含 TiFlash 節點。

TiFlash 提供列式儲存,且擁有藉助 ClickHouse 高效實現的協處理器層。除此以外,它與 TiKV 非常類似,依賴同樣的 Multi-Raft 體系,以 Region 為單位進行資料複製和分散。

TiFlash 主要有非同步複製、一致性、智慧選擇、計算加速等幾個核心特性。

  • 非同步複製:TiFlash 中的副本以特殊角色 (Raft Learner) 進行非同步的資料複製。這表示當 TiFlash 節點當機或者網路高延遲等狀況發生時,TiKV 的業務仍然能確保正常進行。這套複製機制也繼承了 TiKV 體系的自動負載均衡和高可用:並不用依賴附加的複製管道,而是直接以多對多方式接收 TiKV 的資料傳輸;且只要 TiKV 中資料不丟失,就可以隨時恢復 TiFlash 的副本。
  • 一致性:TiFlash 提供與 TiKV 一樣的快照隔離支援,且保證讀取資料最新(確保之前寫入的資料能被讀取)。這個一致性是通過對資料進行復制進度校驗做到的。每次收到讀取請求,TiFlash 中的 Region 副本會向 Leader 副本發起進度校對(一個非常輕的 RPC 請求),只有當進度確保至少所包含讀取請求時間戳所覆蓋的資料之後才響應讀取。
  • 智慧選擇:TiDB 可以自動選擇使用 TiFlash 列存或者 TiKV 行存,甚至在同一查詢內混合使用提供最佳查詢速度。這個選擇機制與 TiDB 選取不同索引提供查詢類似:根據統計資訊判斷讀取代價並作出合理選擇。
  • 計算加速:TiFlash 對 TiDB 的計算加速分為兩部分:列存本身的讀取效率提升以及為 TiDB 分擔計算。其中分擔計算的原理和 TiKV 的協處理器一致:TiDB 會將可以由儲存層分擔的計算下推。能否下推取決於 TiFlash 是否可以支援相關下推

**本人部落格網站 **IT小神 www.itxiaoshen.com

相關文章