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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

rocksdb学习笔记

發(fā)布時間:2024/4/15 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 rocksdb学习笔记 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

rocksdb是在leveldb的基礎上優(yōu)化而得,解決了leveldb的一些問題。

主要的優(yōu)化點

1.增加了column family,這樣有利于多個不相關的數(shù)據(jù)集存儲在同一個db中,因為不同column family的數(shù)據(jù)是存儲在不同的sst和memtable中,所以一定程度上起到了隔離的作用。

2.采用了多線程同時進行compaction的方法,優(yōu)化了compact的速度。

3.增加了merge operator,優(yōu)化了modify的效率

4.將flush和compaction分開不同的線程池,能有效的加快flush,防止stall。

5.增加了對write ahead log(WAL)的特殊管理機制,這樣就能方便管理WAL文件,因為WAL是binlog文件。

?

下面從幾個小點來一窺rocksdb的微妙之處。

rocksdb的column family

column family的具體使用場景,官方并沒有給出非常好的說明,rocksdb支持跨column family的原子寫操作,說明官方認為column family的數(shù)據(jù)之間還是有一定的關系的,而column family的數(shù)據(jù)文件是分割開的,包括sst文件和memtable都是不會共用的,所以官方還是希望不同column family的數(shù)據(jù)進行隔離。所以我覺著一個應用場景就是不同的數(shù)據(jù)混跑在同一個db上,這個僅是個人感覺,歡迎大家討論。那么不同column family之間會怎樣互相干涉呢?

Q:多column family的flush是怎么進行線程分布的?

A:可以共用一個線程池,所以寫的多的會多占用線程。也可以分開配置線程池(指定不同的env),這樣就會不互相干擾。

?

Q:多column family的內(nèi)存是怎么分配的?

A:內(nèi)存主要有兩方面,第一方面是write buffer,第二方面是block cache。

write buffer是每個column family單獨享有的,block cache可以配置成column family級別,也可以配置成整個db的column family共享一個block cache,也可以配置成多個db共享一個block cache。

rocksdb的文件類型

主要有以下幾種類型sst文件,CURRENT文件,manifest文件,log文件,LOG文件和LOCK文件

sst文件存儲的是落地的數(shù)據(jù),CURRENT文件存儲的是當前最新的是哪個manifest文件,manifest文件存儲的是Version的變化,log文件是rocksdb的write ahead log,就是在寫db之前寫的數(shù)據(jù)日志文件,LOG文件是一些日志信息,是供調(diào)試用的,LOCK是打開db鎖,只允許同時有一個進程打開db。

ColumnFamilyOptions

  這些option都是column family相關的,可以對不同的column family賦不同的值。

  inplace_update_support: 字面含義是是否支持在原位置更新,如果支持的話,那么原來的數(shù)據(jù)就被擦除了,所以snapshot和iterator保留當時的數(shù)據(jù)的邏輯就沒法實現(xiàn)了

  num_levels: 記錄的是version的level的數(shù)目,默認是7,即0~6

  target_file_size_base: level1的sst文件的大小,默認為2MB

  target_file_size_multiplier: level1以上的sst文件大小,乘數(shù)因子默認是1,即所有l(wèi)evel的文件大小都是2MB

    level0的文件大小是由write_buffer_size決定的,level1的文件大小是由target_file_size_base決定的,level2及以上,size =?target_file_size_base * (target_file_size_multiplier ^ (L - 1))

  max_bytes_for_level_base: level1的sst總的文件總和大小,默認是10MB

  max_bytes_for_level_multiplier: level2及以上的level的sst文件總和大小的乘數(shù)因子,默認是10,

    level0的sst文件總和大小是level0_stop_writes_trigger *?write_buffer_size,因為level0的文件數(shù)目達到level0_stop_writes_trigger時候就會停止write。

    level1及以上的文件總和大小是max_bytes_for_level_base * (max_bytes_for_level_multiplier ^ (L - 1)),默認的level0是4MB * 24 = 96MB,level1是10MB,level2是100MB,level3是1G,level4是10G。。。

?

rocksdb原子操作的實現(xiàn)

  rocksdb的一個WriteBatch是原子操作,要么全部成功,要么全部失敗,具體的實現(xiàn)原理是在整個log的寫的過程中只會調(diào)用Write操作,最后會調(diào)用一次flush,所以如果中間發(fā)生機器crash,所有的都會失敗,否則所有的都會成功。

?

rocksdb寫和讀放大

  rocksdb的寫會寫WAL(Write Ahead Log),如果sync的話,會寫一次磁盤,然后會寫memtable

  寫rocksdb的時候有可能會卡住,詳見下面的rocksdb的寫stall

?

  rocksdb的讀,會首先讀memtable,如果memtable沒有找到的話,會讀下面level的數(shù)據(jù),由于level0的多個sst會有交疊,所以每個sst都會通過filemeta判斷在不在最小和最大的范圍內(nèi),如果在就需要讀這個sst的文件內(nèi)容,來查看,其他level的sst文件不會有數(shù)據(jù)交疊的情況,所以只會有一個文件可能含有這個數(shù)據(jù)。

  可以看出來讀放大還是比較嚴重的。rocksdb為了減少讀放大,增加了cache.

  讀cache

    rocksdb的讀cache分為兩部分:table cache和block cache。這兩個都是LRUCache

    block cache存儲的block,包括index block和filter block(通過options可以配置)

    table cache存儲的是table,是整個文件的meta信息和Foot信息。table_cache_size的消耗內(nèi)存的大小是有Options里面的max_open_files決定的。

  bloomfilter:

    bloomfilter的增加并不能減少寫放大,因為bloomfilter是table范圍的或者block范圍的,而且bloomfilter是存儲在文件中的,那么必須把這些從文件里面讀出來后才能起到作用。

?

rocksdb的版本管理

rocksdb的版本相關的數(shù)據(jù)結(jié)構有Version、VersionStorageInfo、VersionBuilder、VersionEdit、SuperVersion和VersionSet。

VersionEdit描述的是版本的變更,其主要操作為AddFile和DeleteFile,分別表示,在某個level上增加文件和刪除文件,都是版本變更的操作。

VersionBuilder是生成Version的工具,所以其有兩個主要函數(shù):

void Apply(VersionEdit* edit); void SaveTo(VersionStorageInfo* vstorage);

分別是應用某個VersionEdit和將現(xiàn)在的版本Saveto某個VersionStorageInfo

VersionStorageInfo是Version的信息的存儲結(jié)構,每一個Version的sst文件信息都保存在VersionStorageInfo。

Version是一個完整的版本。sst文件信息存儲在VersionStorageInfo。可以在這個版本上Get數(shù)據(jù)。

SuperVersion是db的一個完整的版本包含的所有信息,包含當前的Memtable,imm和一個Version。也就是Version包含的是sst數(shù)據(jù)信息,SuperVersion包含的是Version的數(shù)據(jù)和memtable中的數(shù)據(jù)。

VersionSet是整個db的版本管理,并維護著manifest文件。每個column family的版本單獨管理,在ColumnFamilyData這個數(shù)據(jù)結(jié)構里面有current Version。

?

rocksdb的Flush

Flush是指將memtable的數(shù)據(jù)導入到sst中,變成持久化存儲,就不怕數(shù)據(jù)丟失了。

1.首先在memtable的add的時候,會檢測是否memtable的大小達到了max write buffer,如果是就將should_flush_置為true,并會在WriteBatch的Handler里面調(diào)用CheckMemtableFull,將當前column family加入flush_scheduler。

2.在Write的時候,調(diào)用ScheduleFlushes,將需要flush的column family的memtable切換一個新的,同時將原來的memtable加入cfd的imm中,如果這個column family data的imm數(shù)量大于min_write_buffer_number_to_merge,并啟動一個新的線程調(diào)用BGWorkFlush

由于真正的Flush過程是在另一個線程完成的,所以這個地方并不會block寫過程

?

另外,如果total_log_size大于max_wal_log_size并且不是只有一個column family,也會觸發(fā)flush,因為flush能將memtable持久化到磁盤上,同時對應的wal就可以刪除了

rocksdb的compaction

rocksdb的compaction的觸發(fā)條件有兩類:

第一類是某一個level的數(shù)據(jù)太多

  • VersionStorageInfo的compaction_score_的計算方法是level0的是當前文件數(shù)目/level0_file_num_compaction_trigger,其他層是該層當前文件大小總和/該層的配置的允許文件總和最大值
  • 基于level的存儲的compaction總的來說,就是一次挑選某一個level的一個文件,然后將該文件和高level的多個相交文件merge,最后生成多個高level的文件。具體的細節(jié)是:每次會挑選compaction score最高的一個level,并在這個level中找到一個文件大小最大,并且上一個level的相交文件沒有在compaction的一個文件
  • 第二類是seek太多

    疑問:

    如果option里面soft_rate_limit設置的為0.0和1之間,compaction并不會觸發(fā),但是會觸發(fā)write delay,這是為什么?

    rocksdb的寫stall

    ?在DBImpl也就是db的實例里面有一個WriteController,同時在ColumnFamilySet里面也有這個WriteController的指針,這個數(shù)據(jù)結(jié)構會控制db的寫stall行為。

    在ColumnFamily進行SuperVersion變更的時候(增加新memtable,flush增加sst,compaction)都會查看需不需要stall Write,stall的條件是:

    1)imm的數(shù)量大于等于option允許的最大數(shù)目

    2)level0的文件的數(shù)量大于option允許的數(shù)目

    如果沒有滿足上面兩項,但是compaction score比較大會delay寫

    rocksdb的write ahead log(WAL)

  • 每次寫操作,rocksdb會先寫write ahead log,然后才會寫db
  • write ahead log可以配置到單獨的空間,并且可以配置WAL文件的單獨的刪除機制。這種原因是為了保存WAL文件,達到特殊的目的,比如,其他sst文件放在不可靠存儲里面,而WAL放到可靠存儲里面。
  • rocksdb的缺點

    1.column family之間的隔離做的不是非常好,因為一個db只有一個WriteController,那么一旦一個db中的一個column family發(fā)生了阻塞,比如寫太快,那么就會阻塞其他的column family的寫。

    2.多進程compaction和flush的效果我持懷疑態(tài)度,因為這兩個主要是磁盤操作,多進程并不會有很好的效果。

    轉(zhuǎn)載于:https://www.cnblogs.com/jfwang/p/4432905.html

    總結(jié)

    以上是生活随笔為你收集整理的rocksdb学习笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。