MyRocks之bloom filter



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时通过计算产生,分为两个阶段

    1. 将prefix_extrator指定的key前缀加入到HASH表hash_entries_中
    2. 将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
时间: 2024-10-26 07:38:27

MyRocks之bloom filter的相关文章

MySQL · myrocks · myrocks之Bloom filter

Bloom filter 简介 Bloom filter用于判断一个元素是不是在一个集合里,当一个元素被加入集合时,通过k个散列函数将这个元素映射成一个位数组中的k个点,把它们置为1.检索时如果这些点有任何一个为0,则被检元素一定不在:如果都是1,则被检元素很可能在.这就是布隆过滤器的基本思想. 优点:布隆过滤器存储空间和插入/查询时间都是常数O(k). 缺点:有一定的误算率,同时标准的Bloom Filter不支持删除操作. Bloom Filter通过极少的错误换取了存储空间的极大节省. 设

爬虫技术之bloom filter(含java代码)

在爬虫系统中,在内存中维护着两个关于URL的队列,ToDo队列和Visited队列,ToDo队列存放的是 爬虫从已经爬取的网页中解析出来的即将爬取的URL,但是网页是互联的,很可能解析出来的URL是已经 爬取到的,因此需要VIsited队列来存放已经爬取过的URL.当爬虫从ToDo队列中取出一个URL的时候, 先和Visited队列中的URL进行对比,确认此URL没有被爬取后就可以下载分析来.否则舍弃此URL,从 Todo队列取出下一个URL继续工作. 然后,我们知道爬虫在爬取网页时,网页的量是

PHP中实现Bloom Filter算法

 这篇文章主要介绍了PHP中实现Bloom Filter算法,本文直接给出实现代码,代码中给出详细注释,Bloom Filter算法介绍等内容,需要的朋友可以参考下     ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57

wiredtiger LSM trees bloom filter 设计原理

最近在做的调研中,其中包括了mongodb wiredtiger LSM trees bloom filter 部分,秉承着好记性不如烂笔头的原则, 做个简单的记录,不保证完全正确,欢迎讨论交流. bloom filter 来源 wiredtiger 也提供了LSM trees 的结构作为持久化存储, 当in-memory tree 大小达到阈值后, 新的in-memory tree会被创建, 旧的in-memory tree会被刷到磁盘.LSM trees 天然支持更快写操作,然而对读操作就不

Bloom Filter Python

http://bitworking.org/news/380/bloom-filter-resources The Bloom filter, conceived by Burton H. Bloom in 1970, is a space-efficient probabilistic data structure that is used to test whether an element is a member of a set. False positives are possible

布隆过滤器(Bloom Filter)的Java实现方法_java

布隆过滤器原理很简单:就是把一个字符串哈希成一个整数key,然后选取一个很长的比特序列,开始都是0,在key把此位置的0变为1:下次进来一个字符串,哈希之后的值key,如果在此比特位上的值也是1,那么就说明这个字符串存在了. 如果按照上面的做法,那就和哈希算法没有什么区别了,哈希算法还有重复的呢. 布隆过滤器是将一个字符串哈希成多个key,我还是按照书上的说吧. 先建立一个16亿二进制常量,然后将这16亿个二进制位全部置0.对于每个字符串,用8个不同的随机产生器(F1,F2,.....,F8)产

PHP中实现Bloom Filter算法_php技巧

<?php /*Bloom Filter算法来去重过滤. 介绍下Bloom Filter的基本处理思路:申请一批空间用于保存0 1信息,再根据一批哈希函数确定元素对应的位置,如果每个哈希函数对应位置的值为全部1,说明此元素存在.相反,如果为0,则要把对应位置的值设置为1.由于不同的元素可能会有相同的哈希值,即同一个位置有可能保存了多个元素的信息,从而导致存在一定的误判率. 如果申请空间太小,随着元素的增多,1会越来越多,各个元素冲突的机会越来越来大,导致误判率会越来越大.另外哈希函数的选择及个数

bloom filter概念讲解以及代码分析_C 语言

一. 简介1.什么是bloom filter?Bloom filter 是由 Howard Bloom 在 1970 年提出的二进制向量数据结构,它具有很好的空间和时间效率,被用来检测一个元素是不是集合中的一个成员,这种检测只会对在集合内的数据错判,而不会对不是集合内的数据进行错判,这样每个检测请求返回有"在集合内(可能错误)"和"不在集合内(绝对不在集合内)"两种情况,可见 Bloom filter 是牺牲了正确率换取时间和空间. 2.bloom filter的计

[20141228]关于bloom filter.txt

[20141228]关于bloom filter.txt --系统升级到11.2.0.4 ,执行计划经常出现bloom filter,自己对这些一点都不了解. --自己做了google,能查到的资料不多,eygle的blog讲解,我水平有限,至少第1次没看懂,不过里面指向一个链接: --http://antognini.ch/papers/BloomFilters20080620.pdf --我仔细阅读,感觉还是不好理解,决定把里面的测试例子执行1次,后面做一个测试: --实际上bloom fi