tiKV 最底層使用的是 RocksDB(tidb3.0版本中將使用tian存儲引擎) 作爲持久化存儲,因此 TiKV 的不少性能相關的參數都是與 RocksDB 相關的。TiKV 使用了兩個 RocksDB 實例,默認 RocksDB 實例存儲 KV 數據,Raft RocksDB 實例(簡稱 RaftDB)存儲 Raft 數據。ios
TiKV 使用了 RocksDB 的 Column Families
(CF) 特性。git
默認 RocksDB 實例將 KV 數據存儲在內部的 default
、write
和 lock
3 個 CF 內。github
default
CF 存儲的是真正的數據,與其對應的參數位於 [rocksdb.defaultcf]
項中;write
CF 存儲的是數據的版本信息 (MVCC) 以及索引相關的數據,相關的參數位於 [rocksdb.writecf]
項中;lock
CF 存儲的是鎖信息,系統使用默認參數。Raft RocksDB 實例存儲 Raft log。算法
default
CF 主要存儲的是 Raft log,與其對應的參數位於 [raftdb.defaultcf]
項中。每一個 CF 都有單獨的 block-cache
,用於緩存數據塊,加速 RocksDB 的讀取速度,block-cache 的大小經過參數 block-cache-size
控制,block-cache-size 越大,可以緩存的熱點數據越多,對讀取操做越有利,同時佔用的系統內存也會越多。數據庫
每一個 CF 有各自的 write-buffer
,大小經過 write-buffer-size
控制緩存
# 日誌級別,可選值爲:trace,debug,info,warn,error,off log-level = "info" [server] # 監聽地址 # addr = "127.0.0.1:20160" # gRPC 線程池大小 # grpc-concurrency = 4 # TiKV 每一個實例之間的 gRPC 鏈接數 # grpc-raft-conn-num = 10 # TiDB 過來的大部分讀請求都會發送到 TiKV 的 Coprocessor 進行處理,該參數用於設置 # coprocessor 線程的個數,若是業務是讀請求比較多,增長 coprocessor 的線程數,但應比系統的 # CPU 核數小。例如:TiKV 所在的機器有 32 core,在重讀的場景下甚至能夠將該參數設置爲 30。在沒有 # 設置該參數的狀況下,TiKV 會自動將該值設置爲 CPU 總核數乘以 0.8。 # end-point-concurrency = 8 # 能夠給 TiKV 實例打標籤,用於副本的調度 # labels = {zone = "cn-east-1", host = "118", disk = "ssd"} [storage] # 數據目錄 # data-dir = "/tmp/tikv/store" # 一般狀況下使用默認值就能夠了。在導數據的狀況下建議將該參數設置爲 1024000。 # scheduler-concurrency = 102400 # 該參數控制寫入線程的個數,當寫入操做比較頻繁的時候,須要把該參數調大。使用 top -H -p tikv-pid # 發現名稱爲 sched-worker-pool 的線程都特別忙,這個時候就須要將 scheduler-worker-pool-size # 參數調大,增長寫線程的個數。 # scheduler-worker-pool-size = 4 [pd] # pd 的地址 # endpoints = ["127.0.0.1:2379","127.0.0.2:2379","127.0.0.3:2379"] [metric] # 將 metrics 推送給 Prometheus pushgateway 的時間間隔 interval = "15s" # Prometheus pushgateway 的地址 address = "" job = "tikv" [raftstore] # 默認爲 true,表示強制將數據刷到磁盤上。若是是非金融安全級別的業務場景,建議設置成 false, # 以便得到更高的性能。 sync-log = true # Raft RocksDB 目錄。默認值是 [storage.data-dir] 的 raft 子目錄。 # 若是機器上有多塊磁盤,能夠將 Raft RocksDB 的數據放在不一樣的盤上,提升 TiKV 的性能。 # raftdb-dir = "/tmp/tikv/store/raft" region-max-size = "384MB" # Region 分裂閾值 region-split-size = "256MB" # 當 Region 寫入的數據量超過該閾值的時候,TiKV 會檢查該 Region 是否須要分裂。爲了減小檢查過程 # 中掃描數據的成本,數據過程當中能夠將該值設置爲32MB,正常運行狀態下使用默認值便可。 region-split-check-diff = "32MB" [rocksdb] # RocksDB 進行後臺任務的最大線程數,後臺任務包括 compaction 和 flush。具體 RocksDB 爲何須要進行 compaction, # 請參考 RocksDB 的相關資料。在寫流量比較大的時候(例如導數據),建議開啓更多的線程, # 但應小於 CPU 的核數。例如在導數據的時候,32 核 CPU 的機器,能夠設置成 28。 # max-background-jobs = 8 # RocksDB 可以打開的最大文件句柄數。 # max-open-files = 40960 # RocksDB MANIFEST 文件的大小限制. # 更詳細的信息請參考:https://github.com/facebook/rocksdb/wiki/MANIFEST max-manifest-file-size = "20MB" # RocksDB write-ahead logs 目錄。若是機器上有兩塊盤,能夠將 RocksDB 的數據和 WAL 日誌放在 # 不一樣的盤上,提升 TiKV 的性能。 # wal-dir = "/tmp/tikv/store" # 下面兩個參數用於怎樣處理 RocksDB 歸檔 WAL。 # 更多詳細信息請參考:https://github.com/facebook/rocksdb/wiki/How-to-persist-in-memory-RocksDB-database%3F # wal-ttl-seconds = 0 # wal-size-limit = 0 # RocksDB WAL 日誌的最大總大小,一般狀況下使用默認值就能夠了。 # max-total-wal-size = "4GB" # 能夠經過該參數打開或者關閉 RocksDB 的統計信息。 # enable-statistics = true # 開啓 RocksDB compaction 過程當中的預讀功能,若是使用的是機械磁盤,建議該值至少爲2MB。 # compaction-readahead-size = "2MB" [rocksdb.defaultcf] # 數據塊大小。RocksDB 是按照 block 爲單元對數據進行壓縮的,同時 block 也是緩存在 block-cache # 中的最小單元(相似其餘數據庫的 page 概念)。 block-size = "64KB" # RocksDB 每一層數據的壓縮方式,可選的值爲:no,snappy,zlib,bzip2,lz4,lz4hc,zstd。 # no:no:lz4:lz4:lz4:zstd:zstd 表示 level0 和 level1 不壓縮,level2 到 level4 採用 lz4 壓縮算法, # level5 和 level6 採用 zstd 壓縮算法,。 # no 表示沒有壓縮,lz4 是速度和壓縮比較爲中庸的壓縮算法,zlib 的壓縮比很高,對存儲空間比較友 # 好,可是壓縮速度比較慢,壓縮的時候須要佔用較多的 CPU 資源。不一樣的機器須要根據 CPU 以及 I/O 資 # 源狀況來配置怎樣的壓縮方式。例如:若是採用的壓縮方式爲"no:no:lz4:lz4:lz4:zstd:zstd",在大量 # 寫入數據的狀況下(導數據),發現系統的 I/O 壓力很大(使用 iostat 發現 %util 持續 100% 或者使 # 用 top 命令發現 iowait 特別多),而 CPU 的資源還比較充裕,這個時候能夠考慮將 level0 和 # level1 開啓壓縮,用 CPU 資源換取 I/O 資源。若是採用的壓縮方式 # 爲"no:no:lz4:lz4:lz4:zstd:zstd",在大量寫入數據的狀況下,發現系統的 I/O 壓力不大,可是 CPU # 資源已經吃光了,top -H 發現有大量的 bg 開頭的線程(RocksDB 的 compaction 線程)在運行,這 # 個時候能夠考慮用 I/O 資源換取 CPU 資源,將壓縮方式改爲"no:no:no:lz4:lz4:zstd:zstd"。總之,目 # 的是爲了最大限度地利用系統的現有資源,使 TiKV 的性能在現有的資源狀況下充分發揮。 compression-per-level = ["no", "no", "lz4", "lz4", "lz4", "zstd", "zstd"] # RocksDB memtable 的大小。 write-buffer-size = "128MB" # 最多容許幾個 memtable 存在。寫入到 RocksDB 的數據首先會記錄到 WAL 日誌裏面,而後會插入到 # memtable 裏面,當 memtable 的大小到達了 write-buffer-size 限定的大小的時候,當前的 # memtable 會變成只讀的,而後生成一個新的 memtable 接收新的寫入。只讀的 memtable 會被 # RocksDB 的 flush 線程(max-background-flushes 參數可以控制 flush 線程的最大個數) # flush 到磁盤,成爲 level0 的一個 sst 文件。當 flush 線程忙不過來,致使等待 flush 到磁盤的 # memtable 的數量到達 max-write-buffer-number 限定的個數的時候,RocksDB 會將新的寫入 # stall 住,stall 是 RocksDB 的一種流控機制。在導數據的時候能夠將 max-write-buffer-number # 的值設置的更大一點,例如 10。 max-write-buffer-number = 5 # 當 level0 的 sst 文件個數到達 level0-slowdown-writes-trigger 指定的限度的時候, # RocksDB 會嘗試減慢寫入的速度。由於 level0 的 sst 太多會致使 RocksDB 的讀放大上升。 # level0-slowdown-writes-trigger 和 level0-stop-writes-trigger 是 RocksDB 進行流控的 # 另外一個表現。當 level0 的 sst 的文件個數到達 4(默認值),level0 的 sst 文件會和 level1 中 # 有 overlap 的 sst 文件進行 compaction,緩解讀放大的問題。 level0-slowdown-writes-trigger = 20 # 當 level0 的 sst 文件個數到達 level0-stop-writes-trigger 指定的限度的時候,RocksDB 會 # stall 住新的寫入。 level0-stop-writes-trigger = 36 # 當 level1 的數據量大小達到 max-bytes-for-level-base 限定的值的時候,會觸發 level1 的 # sst 和 level2 種有 overlap 的 sst 進行 compaction。 # 黃金定律:max-bytes-for-level-base 的設置的第一參考原則就是保證和 level0 的數據量大體相 # 等,這樣可以減小沒必要要的 compaction。例如壓縮方式爲"no:no:lz4:lz4:lz4:lz4:lz4",那麼 # max-bytes-for-level-base 的值應該是 write-buffer-size 的大小乘以 4,由於 level0 和 # level1 都沒有壓縮,並且 level0 觸發 compaction 的條件是 sst 的個數到達 4(默認值)。在 # level0 和 level1 都採起了壓縮的狀況下,就須要分析下 RocksDB 的日誌,看一個 memtable 的壓 # 縮成一個 sst 文件的大小大概是多少,例如 32MB,那麼 max-bytes-for-level-base 的建議值就應 # 該是 32MB * 4 = 128MB。 max-bytes-for-level-base = "512MB" # sst 文件的大小。level0 的 sst 文件的大小受 write-buffer-size 和 level0 採用的壓縮算法的 # 影響,target-file-size-base 參數用於控制 level1-level6 單個 sst 文件的大小。 target-file-size-base = "32MB" # 在不配置該參數的狀況下,TiKV 會將該值設置爲系統總內存量的 40%。若是須要在單個物理機上部署多個 # TiKV 節點,須要顯式配置該參數,不然 TiKV 容易出現 OOM 的問題。 # block-cache-size = "1GB" [rocksdb.writecf] # 保持和 rocksdb.defaultcf.compression-per-level 一致。 compression-per-level = ["no", "no", "lz4", "lz4", "lz4", "zstd", "zstd"] # 保持和 rocksdb.defaultcf.write-buffer-size 一致。 write-buffer-size = "128MB" max-write-buffer-number = 5 min-write-buffer-number-to-merge = 1 # 保持和 rocksdb.defaultcf.max-bytes-for-level-base 一致。 max-bytes-for-level-base = "512MB" target-file-size-base = "32MB" # 在不配置該參數的狀況下,TiKV 會將該值設置爲系統總內存量的 15%。若是須要在單個物理機上部署多個 # TiKV 節點,須要顯式配置該參數。版本信息(MVCC)相關的數據以及索引相關的數據都記錄在 write 這 # 個 CF 裏面,若是業務的場景下單表索引較多,能夠將該參數設置的更大一點。 # block-cache-size = "256MB" [raftdb] # RaftDB 可以打開的最大文件句柄數。 # max-open-files = 40960 # 能夠經過該參數打開或者關閉 RaftDB 的統計信息。 # enable-statistics = true # 開啓 RaftDB compaction 過程當中的預讀功能,若是使用的是機械磁盤,建議該值至少爲2MB。 # compaction-readahead-size = "2MB" [raftdb.defaultcf] # 保持和 rocksdb.defaultcf.compression-per-level 一致。 compression-per-level = ["no", "no", "lz4", "lz4", "lz4", "zstd", "zstd"] # 保持和 rocksdb.defaultcf.write-buffer-size 一致。 write-buffer-size = "128MB" max-write-buffer-number = 5 min-write-buffer-number-to-merge = 1 # 保持和 rocksdb.defaultcf.max-bytes-for-level-base 一致。 max-bytes-for-level-base = "512MB" target-file-size-base = "32MB" # 一般配置在 256MB 到 2GB 之間,一般狀況下使用默認值就能夠了,但若是系統資源比較充足能夠適當調大點。 block-cache-size = "256MB"
tikv內存使用狀況安全
select * from ...
)會讀取數據而後在內存中生成對應的數據結構返回給 TiDB,這個過程當中 TiKV 會佔用一部份內存