在LevelDb 1.4版本中,加入了bloomfilter的支持,這樣在DB::Get()方法的調用過程當中,能夠直接讀取到bloom filter的block部分,從而減小了不存在key的大量的sstable文件隨機讀的操做。
在levelDb中的filter block是存儲在Meta Block部分,目前的版本Meta BLock只有如今的bloom filter,後續版本還可能會加入新的內容。以下圖所示。 nginx
對於Meta block中的bloom filter的存儲方式,以下圖所示。 算法
[filter 0]
[filter 1]
[filter 2]
…
[filter N-1] app
[offset of filter 0] : 4 bytes
[offset of filter 1] : 4 bytes
[offset of filter 2] : 4 bytes
…
[offset of filter N-1] : 4 bytes memcached
[offset of beginning of offset array] : 4 bytes
lg(base) : 1 byte
首先有一個base,大小是以lg的方式進行存儲的,默認爲2Kb,則在數據存儲區的[i*base,(i+1)*base)這一部分的數據就映射到了 filter i上面,能夠直接計算出i的值,而後獲取到offset of beginning of offset array,就能夠獲得filter i和filter i+1的offset,這兩段中間的內容便是該部分的bloom filter的存儲內容。Table::InternalGet會首先利用filter進行判斷該key是否match,若是不match就直接返回,無 需讀取相應的block,代碼在/table/table.cc中。 wordpress
具體的bloom fliter的構造算法在/util/bloom.cc.
從該bloom.cc建立的代碼能夠看出,bloom fliter所佔有的內存由n(key的個數)和bits_per_key_這兩個參數來決定的。 而在整個leveldb中bloom fliter所佔有的內存,應該是全部打開的sstable中的內存和,打開的sstable文件個數爲max_open_files 進行指定,默認爲1000。所以整個leveldb中bloom fliter佔有的內存有全部打開的key的個數和keyt指定的bits_per_key_來決定的。a million keys and you use the suggested 10 bits per key as the argument to NewBloomFilterPolicy, the memory usage will be approximately 10 million bits =~ 1.25 MB。 svn
bloom的Hash採用k_個hash函數的值,k_在1~30之間,由bits_per_key_*ln(2)計算所得。這些hash函數式經過BloomHash計算所得後,再進行相互移位所得。
具體的BloomHash的計算方法與MurMurHash相似。代碼以下所示, 函數
MurmurHash 是一種非加密型哈希函數,適用於通常的哈希檢索操做。由Austin Appleby在2008年發明
MurmurHash2能產生32-bit或64-bit哈希值。 murmurhash在多個開源項目中獲得應用,包括libstdc、libmemcached、nginx、hadoop等。 oop
http://leveldb.googlecode.com/svn/trunk/doc/table_format.txt google
https://code.google.com/p/smhasher/source/browse/trunk/MurmurHash2.cpp 加密
http://duanple.blog.163.com/blog/static/7097176720123227403134/
http://zh.wikipedia.org/wiki/Murmur%E5%93%88%E5%B8%8C
https://code.google.com/p/leveldb/source/detail?r=85584d497e7b354853b72f450683d59fcf6b9c5c