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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Rocksdb 获取当前db内部的有效key个数 (估值)

發布時間:2023/11/27 生活经验 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Rocksdb 获取当前db内部的有效key个数 (估值) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

      • 1. 基本接口
      • 2. Memtable key個數統計
      • 3. Immutable Memtable key個數統計
      • 4. Sstables key個數統計
      • 5. 疑問

Rocksdb因為是AppendOnly 方式寫入,所以沒有辦法提供db內部唯一key個數的接口(可能存在多版本的key,對用戶來說只有一個userkey,但是rocksdb認為是多個internal key)。
不過Rocksdb支持提供獲取大概非刪除key 的internal-key的個數接口,也能讓用戶對寫入的key有一個大體量級的估計。

本文相關rocksdb代碼版本是6.4.6

1. 基本接口

可以通過如下接口來獲取:

uint64_t int_num;
dbfull()->GetIntProperty("rocksdb.estimate-num-keys", &int_num)

這一部分key組成從Rocksdb的寫入整體架構來看應該由三部分組成:

  • memtable-keys
  • imm memtable-keys
  • sstables-keys

實際獲取的時候還需要將刪除key(DeleteType)過濾掉

具體estimate-num-keys的底層實現接口是:

bool InternalStats::HandleEstimateNumKeys(uint64_t* value, DBImpl* /*db*/,Version* /*version*/) {// Estimate number of entries in the column family:// Use estimated entries in tables + total entries in memtables.const auto* vstorage = cfd_->current()->storage_info(); uint64_t estimate_keys = cfd_->mem()->num_entries() + // memtable 的keyscfd_->imm()->current()->GetTotalNumEntries() + // imm 的keysvstorage->GetEstimatedActiveKeys(); // sstables 的keysuint64_t estimate_deletes = // 刪除keyscfd_->mem()->num_deletes() + cfd_->imm()->current()->GetTotalNumDeletes();*value = estimate_keys > estimate_deletes * 2? estimate_keys - (estimate_deletes * 2): 0;return true;
}

2. Memtable key個數統計

針對memtable中的keys的統計會獲取mem()->num_entries()中的num_entries_的個數,memtable即active-memtable 在寫入路徑中達到write-buffer-size閾值之前有且僅有一個,所以只需要看一下當前的用戶進程中這一個memtable中寫入的key的個數即可,而這個數據會在Add memtable的時候同步更新。

3. Immutable Memtable key個數統計

針對immutable memtable的keys統計,因為這種只讀的memtable可能存在多個,由一個鏈表進行管理,后續統一進行flush,所以獲取對應的有效key以及刪除key的個數的話只需要逐個累加immutable memtable中的key的個數即可。

uint64_t MemTableListVersion::GetTotalNumEntries() const {uint64_t total_num = 0;for (auto& m : memlist_) {total_num += m->num_entries();}return total_num;
}

這一些有效key的更新是在Status MemTable::Add()函數中進行更新的,包括后續的num_deletes_的個數也一樣。

4. Sstables key個數統計

這個數據的統計也是我們想要的數據主體,因為大多數的時候 我們數據還是會持久化到sst文件之中的。
針對sst的有效key的個數統計是通過如下接口實現的:
大體邏輯是

  • 如果發現sst文件個數為0,則直接返回0。
    這個場景接口也說明了,在用戶寫入少量 key沒有達到觸發flush的條件時,這里獲取到的數據就是0
  • 如果當前統計的有效key的個數current_num_non_deletions_ 比實際的刪除key的個數還少,則也認為這一些有效key后續都會被刪除,也返回0
  • 有效key的個數 通過current_num_non_deletions_ - current_num_deletions_ 即可獲得
  • 為了防止返回的key數量過多(compaction完成之后會伴隨著文件的刪除),這里會重新逐層獲取一下sst文件數量,和實際統計的sst文件數量做一個比值再乘上一步有效key的個數 – 雙重保險
uint64_t VersionStorageInfo::GetEstimatedActiveKeys() const {// Estimation will be inaccurate when:// (1) there exist merge keys// (2) keys are directly overwritten// (3) deletion on non-existing keys// (4) low number of samplesif (current_num_samples_ == 0) {return 0;}if (current_num_non_deletions_ <= current_num_deletions_) {return 0;}uint64_t est = current_num_non_deletions_ - current_num_deletions_;uint64_t file_count = 0;for (int level = 0; level < num_levels_; ++level) {file_count += files_[level].size();}if (current_num_samples_ < file_count) {// casting to avoid overflowingreturnstatic_cast<uint64_t>((est * static_cast<double>(file_count) / current_num_samples_));} else {return est;}
}

而實際的這一些指標的填充都是VersionStorageInfo::UpdateAccumulatedStats 這個函數中,這個函數的調用鏈實際能貫穿到compaction ,如下調用鏈

DBImpl::BackgroundCompaction // compaction執行入口VersionSet::LogAndApply // compaction 執行結束前需要更新manifest的version信息VersionSet::ProcessManifestWrites // manifest更新入口Version::PrepareApply // 更新各個指標Version::UpdateAccumulatedStats // 更新當前version內所有層的所有文件元信息VersionStorageInfo::UpdateAccumulatedStats // 更新每一個sst文件的元信息

最后一個函數的的更新一個sst文件元數據指標方式如下:

void VersionStorageInfo::UpdateAccumulatedStats(FileMetaData* file_meta) {assert(file_meta->init_stats_from_file);accumulated_file_size_ += file_meta->fd.GetFileSize();accumulated_raw_key_size_ += file_meta->raw_key_size;accumulated_raw_value_size_ += file_meta->raw_value_size;accumulated_num_non_deletions_ +=file_meta->num_entries - file_meta->num_deletions;accumulated_num_deletions_ += file_meta->num_deletions;current_num_non_deletions_ +=file_meta->num_entries - file_meta->num_deletions;current_num_deletions_ += file_meta->num_deletions;current_num_samples_++;
}

5. 疑問

可以看到以上代碼中
current_num_non_deletions_的數值是file_meta->num_entries - file_meta->num_deletions; ,已經減去了當前文件被刪除的數據條目,細心的同學可能會發現估算sst文件內key的個數的函數GetEstimatedActiveKeys中有一行代碼uint64_t est = current_num_non_deletions_ - current_num_deletions_;,這里又減了一次統計的刪除key,有點奇怪。

針對刪除類型的key減了兩次,這里想一想,rocksdb寫入一個刪除類型的key肯定表示需要刪除之前一個已經存在的key,所以我們想要保證返回的是有效key,需要減掉當前刪除key個數的兩倍才行。

總結

以上是生活随笔為你收集整理的Rocksdb 获取当前db内部的有效key个数 (估值)的全部內容,希望文章能夠幫你解決所遇到的問題。

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