MyRocks之bloomfilter
title: MySQL · mysql · myrocks之Bloom filter
author: 張遠
Bloom filter 簡介
Bloom filter用於判斷一個元素是不是在一個集合裡,當一個元素被加入集合時,通過k個雜湊函式將這個元素對映成一個位陣列中的k個點,把它們置為1。檢索時如果這些點有任何一個為0,則被檢元素一定不在;如果都是1,則被檢元素很可能在。這就是布隆過濾器的基本思想。
優點:布隆過濾器儲存空間和插入/查詢時間都是常數O(k)。
缺點:有一定的誤算率,同時標準的Bloom Filter不支援刪除操作。
Bloom Filter通過極少的錯誤換取了儲存空間的極大節省。
設集合元素個數為n,陣列大小為m, 雜湊函式個數為k
有一個規律是當 k=m/n*ln2 時,誤算率最低。參考Bloom_filter wiki
rocksdb與bloom filter
rocksdb中memtable和SST file都屬於集合類資料且不需要刪除資料,比較適合於Bloom filter.
rocksdb memtable和SST file都支援bloom filter, memtable 的bloom filter陣列就儲存在記憶體中,而SST file的bloom filter持久化在bloom filter中.
-
SST Bloom filter
SST Boomfilter 在Flush生成SST files時通過計算產生,分為兩個階段- 將prefix_extrator指定的key字首加入到HASH表hash_entries_中
- 將hash_entries_所有對映到Bloom filter的陣列中
SST Bloom filter相關引數有
filter_policy=bloomfilter:10:false;
whole_key_filtering=0
prefix_extractor=capped:24
partition_filters=false
其中prefix_extractor=capped:24, 表示最多取字首24個位元組,另外還有fixed:n方式表示只取字首n個位元組,忽略小於n個位元組的key. 具體可參考CappedPrefixTransform,FixedPrefixTransform
filter_policy=bloomfilter:10:false;其中bits_per_key_=10, bits_per_key_實際就是前面公式k=m/n*ln2 中的m/n. 從而如下計算k即num_probes_的方式
void initialize() {
// We intentionally round down to reduce probing cost a little bit
num_probes_ = static_cast<size_t>(bits_per_key_ * 0.69); // 0.69 =~ ln(2)
if (num_probes_ < 1) num_probes_ = 1;
if (num_probes_ > 30) num_probes_ = 30;
}
use_block_based_builder_表示是使用block base filter還是full filter
partition_filters 表示時否使用partitioned filter,SST資料有序排列,按block_size進行分割槽後在生產filter,index_on_filter block儲存分割槽範圍. 開啟partition_filters 需配置index_type =kTwoLevelIndexSearch
filter 引數優先順序如下 block base > partitioned > full. 比如說同時指定use_block_based_builder_=true和partition_filters=true實際使用的block based filter
whole_key_filtering,取值true, 表示增加全key的filter. 它和字首filter並不衝突可以共存。
- memtable Bloom filter
memtable 在每次Add資料時都會更新Bloom filter.
Bloom filter提供引數memtable_prefix_bloom_size_ratio,其值不超過0.25, Bloom filter陣列大小為write_buffer_size* memtable_prefix_bloom_size_ratio.
memtable Bloom filter 中的num_probes_取值硬編碼為6
另外引數cache_index_and_filter_blocks可以讓filter資訊快取在block cache中。
MyRocks和bloom filter
在myrocks中,Bloom filter是全域性的,設定了Bloom filter後,所有表都有Bloom filter。Bloom filter和索引是繫結在一起的。也就是說,表在查詢過程中,如果可以用到某個索引,且設定了Bloom filter,那麼就有可能會用到索引的Bloom filter.
MyRocks可以使用Bloom filter的條件如下,詳見函式can_use_bloom_filter
- 必須是索引字首或索引全列的等值查詢
- 等值字首的長度應該符合prefix_extrator的約定
我們可以通過以下兩個status變數來觀察Bloom filter使用情況
rocksdb_bloom_filter_prefix_checked:是否使用了Bloom filter
rocksdb_bloom_filter_prefix_useful:使用Bloom filter判斷出不存在
rocksdb_bloom_filter_useful:BlockBasedTable::Get介面使用Bloom filter判斷出不存在
設定引數rocksdb_skip_bloom_filter_on_read可以讓查詢不使用Bloom filter。
示例
最後給個示例
引數設定如下,使用partitioned filter
rocksdb_default_cf_options=write_buffer_size=64k;block_based_table_factory={filter_policy=bloomfilter:10:false;whole_key_filtering=0;partition_filters=true;index_type=kTwoLevelIndexSearch};prefix_extractor=capped:24
SQL
CREATE TABLE t1 (id1 INT, id2 VARCHAR(100), id3 BIGINT, value INT, PRIMARY KEY (id1, id2, id3)) ENGINE=rocksdb collate latin1_bin;
let $i = 1;
while ($i <= 10000) {
let $insert = INSERT INTO t1 VALUES($i, $i, $i, $i);
inc $i;
eval $insert;
}
# case 1: 等值條件prefix長度 < 24, 用不Bbloom filter
select variable_value into @c from information_schema.global_status where variable_name=`rocksdb_bloom_filter_prefix_checked`;
select variable_value into @u from information_schema.global_status where variable_name=`rocksdb_bloom_filter_prefix_useful`;
select count(*) from t1 WHERE id1=100 and id2 =`10`;
count(*)
0
select (variable_value-@c) > 0 from information_schema.global_status where variable_name=`rocksdb_bloom_filter_prefix_checked`;
(variable_value-@c) > 0
0
select (variable_value-@u) > 0 from information_schema.global_status where variable_name=`rocksdb_bloom_filter_prefix_useful`;
(variable_value-@u) > 0
0
# case 2: 符合使用Bbloom filter的條件,且成功判斷出不存在
select variable_value into @c from information_schema.global_status where variable_name=`rocksdb_bloom_filter_prefix_checked`;
select variable_value into @u from information_schema.global_status where variable_name=`rocksdb_bloom_filter_prefix_useful`;
select count(*) from t1 WHERE id1=100 and id2 =`00000000000000000000`;
count(*)
0
select (variable_value-@c) > 0 from information_schema.global_status where variable_name=`rocksdb_bloom_filter_prefix_checked`;
(variable_value-@c) > 0
1
select (variable_value-@u) > 0 from information_schema.global_status where variable_name=`rocksdb_bloom_filter_prefix_useful`;
(variable_value-@u) > 0
1
相關文章
- MyRocks事務鎖分析
- Redisson實戰-BloomFilterRedisOOMFilter
- MyRocks儲存引擎資料結構解析儲存引擎資料結構
- 布隆過濾器(BloomFilter)原理 實現和效能測試過濾器OOMFilter
- PostgreSQL11preview-BRIN索引介面功能擴充套件(BLOOMFILTER、minmax分段)SQLView索引套件OOMFilter
- PostgreSQL11preview-bloomfilter誤報率評估測試及如何降低誤報-暨bloomfilter應用於HEAP與INDEX的一致性檢測SQLViewOOMFilterIndex
- 漢字之美,拼音之韻
- 深入Spring之IOC之載入BeanDefinitionSpringBean
- PHP之string之ord()函式使用PHP函式
- 若之
- JavaScript之thisJavaScript
- React之元件(component)之間的通訊React元件
- 計算方法之祖沖之的精度
- Kubernetes安裝之八:配置master之schedulerAST
- vue 兄弟元件之間傳值之busVue元件
- 《碼農翻身》之浪潮之巔的WebWeb
- 揭秘ORACLE備份之----RMAN之五(CATALOG)Oracle
- 序列SRAM和FRAM之間的相似之處
- 計算機網路之HTTP之概況計算機網路HTTP
- PHP之string之str_split()函式使用PHP函式
- AI犯錯誰之過?切勿盲目相信之AI
- Java常用資料結構之Set之TreeSetJava資料結構
- PHP之string之str_pad()函式使用PHP函式
- 前端之資料模擬之Mock.js前端MockJS
- flutter之從零開始搭建(一)之 BottomNavigationBarFlutterNavigation
- kubernetes實踐之五十五:kubectl之配置kubeconfig
- Linux之 psLinux
- linux之sedLinux
- linux之awkLinux
- Solon 之 STOMP
- Python之QRCodePython
- OI之詩
- libevent之event
- libevent之bufferevents
- libevent之evbuffer
- libevent之evconnlistener
- phpredis之zrangeByScorePHPRedis
- 天堂之門
- Redis之setRedis