RocksDB 的常用調優引數

2021-08-10 19:56:45 字數 3072 閱讀 7788

rocksdb 的引數以其資料多和複雜著稱,要全部弄懂也要費一番功夫,這裡也僅僅會說一下我們使用的一些引數,還有很多我們也需要後面慢慢去研究。

rocksdb 有兩個後台執行緒,flush 和 compaction,兩個都可以同時並行執行。在優先順序上面,flush 是 high,而 compaction 是 low,也就是 flush 的優先順序會比 compaction 更高,這也很容易理解,如果資料都沒有 memtable flush 到 level 0,後面也沒法做 compaction。我們可以設定 flush 和 compaction 的最大執行緒數:

對於新插入的資料,rocksdb 會首先將其放到 memtable 裡面,所以 rocksdb 的寫入速度是很快的。當乙個 memtable full 之後,rocksdb 就會將這個 memtable 變成 immutable 的,然後用另乙個新的 memtable 來處理後續的寫入,immutable 的 memtable 就等待被 flush 到 level 0。也就是同時,rocksdb 會有乙個活躍的 memtable 和 0 或者多個 immutable memtable。對於 flush,我們需要關注:

- write_buffer_size:memtable 的最大 size,如果超過了這個值,rocksdb 就會將其變成 immutable memtable,並在使用另乙個新的 memtable。

- max_write_buffer_number:最大 memtable 的個數,如果 active memtable full 了,並且 active memtable 加上 immutable memtable 的個數已經到了這個閥值,rocksdb 就會停止後續的寫入。通常這都是寫入太快但是 flush 不及時造成的。

- min_write_buffer_number_to_merge:在 flush 到 level 0 之前,最少需要被 merge 的 memtable 個數。如果這個值是 2,那麼當至少有兩個 immutable 的 memtable 的時候,rocksdb 會將這兩個 immutable memtable 先 merge,在 flush 到 level 0。預先 merge 能減小需要寫入的 key 的資料,譬如乙個 key 在不同的 memtable 裡面都有修改,那麼我們可以 merge 成一次修改。但這個值太大了會影響讀取效能,因為 get 會遍歷所有的 memtable 來看這個 key 是否存在。

rocksdb 預設的將 sst 檔案放在不同的 level,自然就是用的 level style compaction。memtable 的被 flush 到 level 0,level 0 有最新的資料,其他更上層的 level 則是有老的資料。level 0 裡面的 sst 檔案可能會有重疊,也就是不同的 sst 檔案保護的資料 key range 會重疊,但 level 1 以及之上的 level 則不會重疊。對於一次 get 操作來說,通常會在所有的 level 0 檔案裡面檢查是否存在,但如果在其他層,如果在乙個 sst 裡面找到了這個 key,那麼其他 sst 都不會包含這個 key。每一層都比上一層大 10 倍,當然這個是可以配置的。

一次 compaction 會將 level n 的一些檔案跟 level n + 1 裡面跟這些檔案重疊的檔案進行 compact 操作。兩個不同的 compaction 操作會在不會的 level 或者不同的 key ranges 之間進行,所以可以同時併發的進行多個 compaction 操作。

在 level 0 和 level 1 之間的 compaction 比較 tricky,level 0 會覆蓋所有的 key range,所以當 level 0 和 level 1 之間開始進行 compaction 的時候,所有的 level 1 的檔案都會參與合併。這時候就不能處理 level 1 到 level 2 的 compaction,必須等到 level 0 到 level 1 的 compaction 完成,才能繼續。如果 level 0 到 level 1 的速度比較慢,那麼就可能導致整個系統大多數時候只有乙個 compaction 在進行。

level 0 到 level 1 的 compaction 是乙個單執行緒的,也就意味著這個操作其實並不快,rocksdb 後續引入了乙個 max_subcompactions,解決了 level 0 到 level 1 的 compaction 多執行緒問題。通常,為了加速 level 0 到 level 1 的 compaction,我們會盡量保證level 0 和 level 1 有相同的 size。

當決定了 level 1 的大概 size,我們就需要決定 level multiplier。假設 level 1 的 size 是 512mb,level multiplier 是 10,整個 db 的 size 是 500gb。level 2 的 size 是 5gb,level 3 是 51gb,level 4 是 512gb,level 5 以及更上層的 level 就是空的。

那麼 size amplification 就很容易計算了 (512 mb + 512 mb + 5gb + 51gb + 512gb) / (500gb) = 1.14,write amplification 的計算則是:任何乙個 byte 首先寫入 level 0,然後 compact 到 level 1,因為 level 1 的 size 跟 level 0 是一樣的,所以 write amplification 在 level 0 到 level 1 的 compaction 是 2。當這個 byte compact 到 level 2 的時候,因為 level 2 比 level 1 大 10 倍,所以 write amplification 是 10。對於 level 2 到 level 3,level 3 到 level 4 也是一樣。

所以總的 write amplification 就是 1 + 2 + 10 + 10 + 10 = 33。對於點查來說,通常會訪問所有的 level 0 檔案或者其他 level 的至多乙個檔案,這裡我們可以使用 bloom filter 來減少 read amplification,但這個對於 range scans(也就是 iterator seek 這些)沒啥作用,所以 range scans 的 read amplification 是 level 0 的檔案資料 + 非空 level 的數量。

理解了上面的 level compaction 的流程,我們就可以開始配置相關的引數了。

CPU常用引數調優

cpu 時間片長,優先順序低 io 時間片短,優先順序高 檢視cpu實時狀態命令 top w vmstat 1 5 uptime sar q 可以實時取樣也可以檢視過去cpu使用情況 檢視cpu使用率命令 mpstat 可檢視指定的cpu使用率,也可檢視全部cpu使用率 sar p all 1 2 ...

hive常用引數調優

決定是否可以在 map 端進行聚合操作 開啟資料傾斜時的負載均衡 設定所提交 job 的 reduer 的個數 hive map join 所快取的行數。決定 hive 是否應該自動地根據輸入檔案大小,在本地執行 需要合併的小檔案群的平均大小,預設 16 m。是否根據輸入小表的大小,自動將 redu...

Dubbo常用調優引數

dubbo是阿里開源的一款流行的分布式服務框架,有必要了解其常用調優引數 引數名作用範圍預設值說明備註 threads provider 200業務處理執行緒池大小 iothreads provider cpu 1 io執行緒池大小 queues provider 0執行緒池佇列大小,當執行緒池滿時...