日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

常见存储引擎_存储引擎

發布時間:2023/12/19 综合教程 42 生活家
生活随笔 收集整理的這篇文章主要介紹了 常见存储引擎_存储引擎 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

TiKV 簡介

TiKV 是一個分布式事務型的鍵值數據庫,提供了滿足 ACID 約束的分布式事務接口,并且通過Raft 協議保證了多副本數據一致性以及高可用。TiKV 作為 TiDB 的存儲層,為用戶寫入 TiDB 的數據提供了持久化以及讀寫服務,同時還存儲了 TiDB 的統計信息數據。

整體架構

與傳統的整節點備份方式不同,TiKV 參考 Spanner 設計了 multi raft-group 的副本機制。將數據按照 key 的范圍劃分成大致相等的切片(下文統稱為 Region),每一個切片會有多個副本(通常是 3 個),其中一個副本是 leader,提供讀寫服務。TiKV 通過 PD 對這些 Region 以及副本進行調度,以保證數據和讀寫負載都均勻地分散在各個 TiKV 上,這樣的設計保證了整個集群資源的充分利用并且可以隨著機器數量的增加水平擴展。

Region 與 RocksDB

雖然 TiKV 將數據按照范圍切割成了多個 Region,但是同一個節點的所有 Region 數據仍然是不加區分地存儲于同一個 RocksDB 實例上,而用于 Raft 協議復制所需要的日志則存儲于另一個 RocksDB 實例。這樣設計的原因是因為隨機 I/O 的性能遠低于順序 I/O,所以 TiKV 使用同一個 RocksDB 實例來存儲這些數據,以便不同 Region 的寫入可以合并在一次 I/O 中。

Region 與 Raft 協議

Region 與副本之間通過 Raft 協議來維持數據一致性,任何寫請求都只能在 leader 上寫入,并且需要寫入多數副本后(默認配置為 3 副本,即所有請求必須至少寫入兩個副本成功)才會返回客戶端寫入成功。

當某個 Region 的大小超過一定限制(默認是 144MB)后,TiKV 會將它分裂為兩個或者更多個 Region,以保證各個 Region 的大小是大致接近的,這樣更有利于 PD 進行調度決策。同樣的,當某個 Region 因為大量的刪除請求導致 Region 的大小變得更小時,TiKV 會將比較小的兩個相鄰 Region 合并為一個。

當 PD 需要把某個 Region 的一個副本從一個 TiKV 節點調度到另一個上面時,PD 會先為這個 Raft Group 在目標節點上增加一個 Learner 副本(雖然會復制 leader 的數據,但是不會計入寫請求的多數副本中)。當這個 Learner 副本的進度大致追上 Leader 副本時,Leader 會將他變更為 Follower,之后再移除操作節點的 Follower 副本,這樣就完成了 Region 副本的一次調度。

Leader 副本的調度原理也類似,不過需要在目標節點的 Learner 副本變為 Follower 副本后,再執行一次 Leader Transfer,讓該 Follower 主動發起一次選舉成為新 Leader,之后新 Leader 負責刪除舊 Leader 這個副本。

分布式事務

TiKV 支持分布式事務,用戶(或者 TiDB)可以一次性寫入多個 key-value 而不必關心這些 key-value 是否處于同一個數據切片 (Region) 上,TiKV 通過兩階段提交保證了這些讀寫請求的 ACID 約束,詳見TiDB 樂觀事務模型。

計算加速

TiKV 通過協處理器 (Coprocessor) 可以為 TiDB 分擔一部分計算:TiDB 會將可以由存儲層分擔的計算下推。能否下推取決于 TiKV 是否可以支持相關下推。計算單元仍然是以 Region 為單位,即 TiKV 的一個 Coprocessor 計算請求中不會計算超過一個 Region 的數據。

RocksDB 簡介

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 的寫次數。

TiKV 架構

TiKV 的系統架構如下圖所示:

RocksDB 作為 TiKV 的核心存儲引擎,用于存儲 Raft 日志以及用戶數據。每個 TiKV 實例中有兩個 RocksDB 實例,一個用于存儲 Raft 日志(通常被稱為 raftdb),另一個用于存儲用戶數據以及 MVCC 信息(通常被稱為 kvdb)。kvdb 中有四個 ColumnFamily:raft、lock、default 和 write:

  • raft 列:用于存儲各個 Region 的元信息。僅占極少量空間,用戶可以不必關注。

  • lock 列:用于存儲悲觀事務的悲觀鎖以及分布式事務的一階段 Prewrite 鎖。當用戶的事務提交之后, lock cf 中對應的數據會很快刪除掉,因此大部分情況下 lock cf 中的數據也很少(少于 1GB)。如果 lock cf 中的數據大量增加,說明有大量事務等待提交,系統出現了 bug 或者故障。

  • write 列:用于存儲用戶真實的寫入數據以及 MVCC 信息(該數據所屬事務的開始時間以及提交時間)。當用戶寫入了一行數據時,如果該行數據長度小于 255 字節,那么會被存儲 write 列中,否則的話該行數據會被存入到 default 列中。由于 TiDB 的非 unique 索引存儲的 value 為空,unique 索引存儲的 value 為主鍵索引,因此二級索引只會占用 writecf 的空間。

  • default 列:用于存儲超過 255 字節長度的數據。

RocksDB 的內存占用

為了提高讀取性能以及減少對磁盤的讀取,RocksDB 將存儲在磁盤上的文件都按照一定大小切分成 block(默認是 64KB),讀取 block 時先去內存中的 BlockCache 中查看該塊數據是否存在,存在的話則可以直接從內存中讀取而不必訪問磁盤。

BlockCache 按照 LRU 算法淘汰低頻訪問的數據,TiKV 默認將系統總內存大小的 45% 用于 BlockCache,用戶也可以自行修改storage.block-cache.capacity配置設置為合適的值,但是不建議超過系統總內存的 60%。

寫入 RocksDB 中的數據會寫入 MemTable,當一個 MemTable 的大小超過 128MB 時,會切換到一個新的 MemTable 來提供寫入。TiKV 中一共有 2 個 RocksDB 實例,合計 4 個 ColumnFamily,每個 ColumnFamily 的單個 MemTable 大小限制是 128MB,最多允許 5 個 MemTable 存在,否則會阻塞前臺寫入,因此這部分占用的內存最多為 4 x 5 x 128MB = 2.5GB。這部分占用內存較少,不建議用戶自行更改。

RocksDB 的空間占用

  • 多版本:RocksDB 作為一個 LSM-tree 結構的鍵值存儲引擎,MemTable 中的數據會首先被刷到 L0。L0 層的 SST 之間的范圍可能存在重疊(因為文件順序是按照生成的順序排列),因此同一個 key 在 L0 中可能存在多個版本。當文件從 L0 合并到 L1 的時候,會按照一定大小(默認是 8MB)切割為多個文件,同一層的文件的范圍互不重疊,所以 L1 及其以后的層每一層的 key 都只有一個版本。

  • 空間放大:RocksDB 的每一層文件總大小都是上一層的 x 倍,在 TiKV 中這個配置默認是 10,因此 90% 的數據存儲在最后一層,這也意味著 RocksDB 的空間放大不超過 1.11 (L0 層的數據較少,可以忽略不計)

  • TiKV 的空間放大:TiKV 在 RocksDB 之上還有一層自己的 MVCC,當用戶寫入一個 key 的時候,實際上寫入到 RocksDB 的是 key + commit_ts,也就是說,用戶的更新和刪除都是會寫入新的 key 到 RocksDB。TiKV 每隔一段時間會刪除舊版本的數據(通過 RocksDB 的 Delete 接口),因此可以認為用戶存儲在 TiKV 上的數據的實際空間放大為,1.11 加最近 10 分鐘內寫入的數據(假設 TiKV 回收舊版本數據足夠及時)。詳情見《TiDB in Action》。

RocksDB 后臺線程與 Compact

RocksDB 中,將內存中的 MemTable 轉化為磁盤上的 SST 文件,以及合并各個層級的 SST 文件等操作都是在后臺線程池中執行的。后臺線程池的默認大小是 8,當機器 CPU 數量小于等于 8 時,則后臺線程池默認大小為 CPU 數量減一。通常來說,用戶不需要更改這個配置。如果用戶在一個機器上部署了多個 TiKV 實例,或者機器的讀負載比較高而寫負載比較低,那么可以適當調低rocksdb/max-background-jobs至 3 或者 4。

WriteStall

RocksDB 的 L0 與其他層不同,L0 的各個 SST 是按照生成順序排列,各個 SST 之間的 key 范圍存在重疊,因此查詢的時候必須依次查詢 L0 中的每一個 SST。為了不影響查詢性能,當 L0 中的文件數量過多時,會觸發 WriteStall 阻塞寫入。

如果用戶遇到了寫延遲突然大幅度上漲,可以先查看 Grafana RocksDB KV 面板 WriteStall Reason 指標,如果是 L0 文件數量過多引起的 WriteStall,可以調整下面幾個配置到 64,詳細見《TiDB in Action》。

rocksdb.defaultcf.level0-slowdown-writes-trigger

rocksdb.writecf.level0-slowdown-writes-trigger

rocksdb.lockcf.level0-slowdown-writes-trigger

rocksdb.defaultcf.level0-stop-writes-trigger

rocksdb.writecf.level0-stop-writes-trigger

rocksdb.lockcf.level0-stop-writes-trigger

總結

以上是生活随笔為你收集整理的常见存储引擎_存储引擎的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。