| 導(dǎo)語 對(duì)于 LevelCompact 策略,RocksDB會(huì)根據(jù)每一層不同的策略計(jì)算出CompactScore,根據(jù)CompactScore大小來決定那一層將會(huì)優(yōu)先進(jìn)行Compact,然后選擇Level-N 和Level-(N+1)的文件進(jìn)行Compact。如何計(jì)算CompactScore? 如何選擇文件進(jìn)行Compact?Compact有哪些參數(shù)?如何知道RocksDB當(dāng)前的一個(gè)狀態(tài)?
RocksDB是基于LSM結(jié)構(gòu)的K-V存儲(chǔ)引擎,由于數(shù)據(jù)文件采用Append Only方式寫入,而對(duì)于過期的數(shù)據(jù)、重復(fù)的數(shù)據(jù)必然會(huì)存在有多份副本,這部分?jǐn)?shù)據(jù)通過Compact的方式進(jìn)行逐步的清理。
那么這里好奇的提出幾個(gè)問題,由這幾個(gè)問題引出下文:
RocksDB是如何進(jìn)行Compact 的?
Compact的時(shí)候這些文件是如何進(jìn)行選擇的?
Compact在什么時(shí)候、或者什么條件下觸發(fā)?
對(duì)于Compact我們能知道哪些信息?通過TRedis怎么查看這部分信息?
有哪些參數(shù)可以控制或者影響到Compact
由于我們的TRedis底層采用RocksDB存儲(chǔ)引擎進(jìn)行持久化,底層數(shù)據(jù)文件采用分層的方式管理,故這里討論的Compact 基于Level Compact 。
數(shù)據(jù)怎么來?我們調(diào)用TRedis接口進(jìn)行寫數(shù)據(jù)時(shí),數(shù)據(jù)會(huì)先寫入到內(nèi)存中的Memtable里邊,當(dāng)Memtable寫滿后會(huì)寫入下一個(gè)Memtable,Memtable采用Skiplist結(jié)構(gòu)以此保證數(shù)據(jù)按照Key的字典序進(jìn)行排序,同時(shí)這個(gè)Memtable會(huì)被后臺(tái)線程刷到磁盤文件–Level-0,當(dāng)Level-0文件個(gè)數(shù)達(dá)到一定數(shù)量,Compact線程可能會(huì)進(jìn)行Compact,由此產(chǎn)生Level-1,當(dāng)Level-1文件總大小達(dá)到一定大小后, Compact線程可能會(huì)進(jìn)行Compact,由此產(chǎn)生Level-2,…….
RocksDB對(duì)每一層的處理規(guī)則不太一樣,由于Level-0層的數(shù)據(jù)直接由Memtable dump得到,從而不能保證Level-0層的每個(gè)文件Key的范圍不能有交集,故對(duì)Level-0層的會(huì)進(jìn)行特殊處理,而對(duì)于Level-1+層處理規(guī)則一樣。
Level-0 層的文件在不停的從Memtable 中dump出來,那么何時(shí)才會(huì)把這些Level-0層的文件合并到Level-1 ?
RocksDB對(duì)對(duì)每一層進(jìn)行打分,分?jǐn)?shù)從0~1000000,這個(gè)分?jǐn)?shù)的大小決定了進(jìn)行Compact 的優(yōu)先級(jí),分?jǐn)?shù)越大,越先進(jìn)行Compact。
那么這個(gè)分?jǐn)?shù)如何計(jì)算出來?
如果是Level-0層,會(huì)先算出當(dāng)前有多少個(gè)沒有進(jìn)行Compact 的文件個(gè)數(shù)numfiles, 然后根據(jù)這個(gè)文件的個(gè)數(shù)進(jìn)行判斷,
當(dāng)numfiles<20 時(shí),Score = numfiles/4;當(dāng)24>numfiles>=20時(shí),Score = 10000;當(dāng) numfiles>=24時(shí),Score = 1000000
: