【TIDB】二、TIDB進階

0、TIDB優點

一、和MySql相比,具有OLAP能力。省去了不少數據倉庫搭建成本和學習成本。這在業務層是很是受歡迎的。能夠在其餘分庫分表業務中,經過 syncer 同步,進行合併,而後進行統計分析
二、數據量增加極快的OLTP場景,這些數據庫的數據在一年內輕鬆達到數百億量級。TiDB 的全部特性都很是契合這種海量高併發的 OLTP 場景。git

三、彌補單機容量上限,支持水平擴展,無限擴容存儲github

四、傳統 Sharding 方案查詢維度單一,TIDB支持多維度查詢算法

五、支持在線 DDL 這個特性特別適合這些業務,有須要業務更改不會阻塞業務,業務快速迭代比較須要sql

六、在MySQL上要分庫分表,可是又須要分佈式事務的業務。支持分佈式事務數據庫

七、支持讀寫QPS須要彈性擴容、縮容的業務安全

一、語言技術棧

SQL層和調度層爲Go,KV層Rust,引擎C++服務器

二、協議兼容性

兼容80% MySQL協議網絡

三、分佈式時序

全局單點授時服務架構

四、分佈式事務的支持

不管是一個地方的幾個節點,仍是跨多個數據中心的多個節點,TiDB 均支持 ACID 分佈式事務。併發

TiDB 事務模型靈感源自 Google Percolator 模型,主體是一個兩階段提交協議,並進行了一些實用的優化。該模型依賴於一個時間戳分配器,爲每一個事務分配單調遞增的時間戳,這樣就檢測到事務衝突。在 TiDB 集羣中,PD 承擔時間戳分配器的角色。

TiKV 的事務採用樂觀鎖,事務的執行過程當中,不會檢測寫寫衝突,只有在提交過程當中,纔會作衝突檢測,衝突的雙方中比較早完成提交的會寫入成功,另外一方會嘗試從新執行整個事務。當業務的寫入衝突不嚴重的狀況下,這種模型性能會很好,好比隨機更新表中某一行的數據,而且表很大。可是若是業務的寫入衝突嚴重,性能就會不好,舉一個極端的例子,就是計數器,多個客戶端同時修改少許行,致使衝突嚴重的,形成大量的無效重試

五、併發控制

樂觀鎖

六、一致性

強一致的raft

七、存儲

7.一、TiKV 沒有選擇直接向磁盤上寫數據,而是把數據保存在 RocksDB 中,具體的數據落地由 RocksDB 負責。這個選擇的緣由是開發一個單機存儲引擎工做量很大,特別是要作一個高性能的單機引擎,須要作各類細緻的優化,而 RocksDB 是一個很是優秀的開源的單機存儲引擎,能夠知足咱們對單機引擎的各類要求,並且還有 Facebook 的團隊在作持續的優化

7.二、Raft協議保證存儲的高可用

Raft 是一個一致性協議,提供幾個重要的功能:

  1. Leader 選舉
  2. 成員變動
  3. 日誌複製

TiKV 利用 Raft 來作數據複製,每一個數據變動都會落地爲一條 Raft 日誌,經過 Raft 的日誌複製功能,將數據安全可靠地同步到 Group 的多數節點中。

經過單機的 RocksDB,咱們能夠將數據快速地存儲在磁盤上;經過 Raft,咱們能夠將數據複製到多臺機器上,以防單機失效。數據的寫入是經過 Raft 這一層的接口寫入,而不是直接寫 RocksDB。經過實現 Raft,咱們擁有了一個分佈式的 KV,如今不再用擔憂某臺機器掛掉了

7.三、存儲數據的基本單位:Region

  • 以 Region 爲單位,將數據分散在集羣中全部的節點上,而且儘可能保證每一個節點上服務的 Region 數量差很少
  • 以 Region 爲單位作 Raft 的複製和成員管理

7.四、多版本控制(MVCC)

設想這樣的場景,兩個 Client 同時去修改一個 Key 的 Value,若是沒有 MVCC,就須要對數據上鎖,在分佈式場景下,可能會帶來性能以及死鎖問題。 TiKV 的 MVCC 實現是經過在 Key 後面添加 Version 來實現

7.五、行存仍是列存?

TiDB 面向的首要目標是 OLTP 業務,這類業務須要支持快速地讀取、保存、修改、刪除一行數據,因此採用行存是比較合適的

八、關係模型到 Key-Value 模型的映射

8.一、一個 Table 內部全部的 Row 都有相同的前綴,一個 Index 的數據也都有相同的前綴。這樣具體相同的前綴的數據,在 TiKV 的 Key 空間內,是排列在一塊兒。同時只要咱們當心地設計後綴部分的編碼方案,保證編碼前和編碼後的比較關係不變,那麼就能夠將 Row 或者 Index 數據有序地保存在 TiKV 中

8.二、數據元數據處理(表結構)

通常數據庫在進行 DDL 操做時都會鎖表,致使線上對此表的 DML 操做所有進入等待狀態(有些數據支持讀操做,可是也以消耗大量內存爲代價),即不少涉及此表的業務都處於阻塞狀態,表越大,影響時間越久

TiDB 使用 Google F1 的 Online Schema 變動算法,有一個後臺線程在不斷的檢查 TiKV 上面存儲的 Schema 版本是否發生變化,而且保證在必定時間內必定可以獲取版本的變化(若是確實發生了變化)。這部分的具體實現參見 TiDB 的異步 schema 變動實現一文。

8.三、分佈式sql計算

咱們將 Filter 也下推到存儲節點進行計算,這樣只須要返回有效的行,避免無心義的網絡傳輸。最後,咱們能夠將聚合函數、GroupBy 也下推到存儲節點,進行預聚合,每一個節點只須要返回一個 Count 值便可,再由 tidb-server 將 Count 值 Sum 起來

提升計算速度的優化:

  • MPP:Massively Parallel Processing,即大規模並行處理。計算數據是分在不一樣的節點上,而且極可能不在一臺機器上,它們經過高速的網絡鏈接,讓每一個節點都本身去處理數據,處理完數據以後再彙總在一塊兒,最後給用戶返回結果。節點之間的計算是相互不知道的,而後他們只執行本身的事情,不須要去交換數據
  • SMP:Symmetric Multi-Processor,對稱多處理器結構。它是一種 share everything 的架構。每個共享的環節均可能形成SMP服務器擴展時的瓶頸,而最受限制的則是內存。因爲每一個CPU必須經過相同的內存總線訪問相同的內存資源,所以隨着CPU數量的增長,內存訪問衝突將迅速增長,最終會形成CPU資源的浪費,使 CPU性能的有效性大大下降
  • TiDB:結合MPP和SMP。 SQL layer 是用 Go 來寫的,Go 在多核機器上可以發揮併發優點,它的 Goroutine 調度的開銷很小,咱們能夠建不少 Goroutine,利用如今 CPU 愈來愈多的這個特性,去提升計算的並行度

九、調度模塊。PD

整個系統也是在動態變化,Region 分裂、節點加入、節點失效、訪問熱點變化等狀況會不斷髮生,整個調度系統也須要在動態中不斷向最優狀態前進,若是沒有一個掌握全局信息,能夠對全局進行調度,而且能夠配置的組件,就很難知足這些需求。所以咱們須要一箇中心節點,來對系統的總體情況進行把控和調整,因此有了 PD 這個模塊

一、信息收集

TiKV 節點(Store)與 PD 之間存在心跳包,一方面 PD 經過心跳包檢測每一個 Store 是否存活,以及是否有新加入的 Store;還包括如下信息:

  • 總磁盤容量
  • 可用磁盤容量
  • 承載的 Region 數量
  • 數據寫入速度
  • 發送/接受的 Snapshot 數量(Replica 之間可能會經過 Snapshot 同步數據)
  • 是否過載
  • 標籤信息(標籤是具有層級關係的一系列 Tag)

每一個 Raft Group 的 Leader 和 PD 之間存在心跳包,用於彙報這個 Region 的狀態,主要包括下面幾點信息:

  • Leader 的位置
  • Followers 的位置
  • 掉線 Replica 的個數
  • 數據寫入/讀取的速度

PD 還能夠經過管理接口接受額外的信息,用來作更準確的決策。

二、調度策略

  • 一個 Region 的 Replica 數量正確
  • 一個 Raft Group 中的多個 Replica 不在同一個位置

  • 副本在 Store 之間的分佈均勻分配。每一個副本中存儲的數據容量上限是固定的,因此咱們維持每一個節點上面,副本數量的均衡,會使得整體的負載更均衡。

  • Leader 數量在 Store 之間均勻分配

  • 訪問熱點數量在 Store 之間均勻分配

  • 各個 Store 的存儲空間佔用大體相等

  • 控制調度速度,避免影響在線服務

  • 支持手動下線節點

 

參考資料:

TIDB對Raft 的優化 https://zhuanlan.zhihu.com/p/25735592

https://pingcap.com/blog-cn/tidb-internal-1/

https://pingcap.com/blog-cn/tidb-internal-3/

相關文章
相關標籤/搜索