目录
Schema Design
Bloom Filters
它是一种数据结构,用于预测给定元素是否是一组数据的成员。从Bloom filter得到的正结果并不总是准确的,但是负结果保证是准确的。Bloom过滤器被设计为对数据集“足够精确”,因为数据集太大,传统的哈希机制是不切实际的。
就HBase而言,Bloom过滤器提供了一种轻量级的内存结构,用于减少给定Get操作(Bloom过滤器不能用于扫描)的磁盘读取次数,只读取可能包含所需行的存储文件。潜在的性能增益随着并行读取的数量增加而增加。
Bloom 过滤器本身存储在每个 HFile 的元数据中,不需要更新。当一个 HFile 因为一个区域被部署到一个 RegionServer 而被打开时,Bloom 过滤器被加载到内存中。
HBase 包含一些调整机制,用于折叠 Bloom 过滤器以减小大小并将假阳性率保持在期望的范围内。
Bloom 过滤器是在 HBASE-1200 中引入的。从 HBase 0.96,默认情况下启用了基于行的 Bloom 过滤器。
什么时候使用
HBase 0.96,默认情况下启用了基于行的 Bloom 过滤器。您可以选择禁用它们或更改一些表来使用 row+column Bloom 过滤器,这取决于数据的特征以及如何将其加载到 HBase 中。
要确定 Bloom 过滤器是否有用,请检查 RegionServer 指标中的 blockCacheHitRatio 值。如果启用了 Bloom 过滤器,则 blockCacheHitRatio 的值应该会增加,因为 Bloom 过滤器正在过滤掉绝对不需要的数据块。
你可以选择基于 row 或 row+column 组合来启用布隆过滤。如果 scan rows,则 row+column 组合不会提供任何高性能。基于行的 Bloom 过滤器可以对 row+column Get 进行操作,但反过来不行。但是,如果有大量的列级put,比如每个 StoreFile 中都可能有一行,那么基于行的过滤器将始终返回一个正结果,并且没有任何好处。除非每行有一个列,否则row+column Bloom过滤器需要更多空间,以便存储更多键。当每个数据条目的大小至少为几kb时,Bloom 过滤器的性能是最好的。
数据存储在几个较大的存储文件中时,开销将会减少,以避免在低级扫描期间查找特定行的额外磁盘IO。
注意:Bloom过滤器需要在删除时重新构建,因此可能不适用于存在大量删除的环境。
开启布隆过滤
在列族上启用布隆过滤器。可以通过使用 HColumnDescriptor 的 setBloomFilterType 方法或使用 HBase API 来实现这一点。有效值为 NONE、ROW(默认值) 或 ROWCOL。
下面的示例创建一个表,并在colfam1列族上启用ROWCOL Bloom过滤器。
hbase> create 'mytable',{NAME => 'colfam1', BLOOMFILTER => 'ROWCOL'}
配置Bloom过滤器的服务器范围
你可以在 hbase-site.xml 文件中配置以下:
参数 | 默认值 | 描述 |
io.storefile.bloom.enabled | yes | 设置为no以在服务器范围内杀死 Bloom 过滤器 |
io.storefile.bloom.error.rate | .01 | Bloom 过滤器的平均假阳性率。折叠是用来维持假阳性率。用百分数的十进制表示。 |
io.storefile.bloom.max.fold | 7 | 保证最大折叠率。不需要更改此设置,也不建议更改。 |
io.storefile.bloom.max.keys | 128000000 | 对于默认的(单块) Bloom 过滤器,它指定键的最大数目。 |
io.storefile.delete.family.bloom.enabled | true | 主开关,以启用删除布隆过滤器族和存储在存储文件。 |
io.storefile.bloom.block.size | 131072 | 目标 Bloom 块大小。大约这个大小的Bloom过滤器块与数据块交错。 |
hfile.block.bloom.cacheonwrite | false | 为复合 Bloom 过滤器的内联块启用写时缓存。 |
Reading from HBase
Bloom Filters
启用 Bloom 过滤器可以节省到磁盘的时间,并有助于改善读取延迟。
Bloom 过滤器是在 HBase-1200 中开发的。这里描述的 Bloom 过滤器实际上是HBase中的版本2。HBase bloom 工作的核心后来被转移到 Hadoop 中,以实现 org.apache.hadoop.io.BloomMapFile。版本1中的 Hbase Bloom 并没有那么好用,版本2中对其重写。
Bloom StoreFile封装
Bloom 过滤器向 StoreFile general FileInfo 数据结构中添加一个条目,然后向 StoreFile 元数据部分添加两个额外的条目。
StoreFile``FileInfo数据结构中的BloomFilter
FileInfo 中的 BLOOM_FILTER_TYPE 可以设置为 NONE
,ROW,
ROWCOL
StoreFile元数据中的BloomFilter
BLOOM_FILTER_META 包含 Bloom 的大小、使用的哈希函数等等,它占用空间很小,缓存在 StoreFile.Reader
BLOOM_FILTER_DATA 包含 BloomFiler 的数据,
按需获取。存储在LRU缓存,如果它是启用的(它是默认启用的)。
Bloom StoreFile配置
见上,表格:↑↑↑↑
2版本中的 Bloom filters
与版本1不同的是,在版本2中,Bloom filter 元数据存储在 HFile 的 load-on-open 部分,用于快速启动。
- 复合 Bloom filter
- Bloom filter version = 3 (int)。以前有一个 DynamicByteBloomFilter 类,它的 Bloom 过滤器版本号为2
- 所有复合 Bloom filter 块的总字节大小(long)
- 哈希函数的数量(int)
- 哈希函数的类型(int)
- 插入到 Bloom 过滤器中的 key 总数(long)
- Bloom 过滤器中键的最大总数(long)
- 块的数量(int)
- Comparator 类用于 Bloom 过滤器的 key,UTF-8 编码串使用 Bytes.writeByteArray 存储
- 版本2中的 Bloom 的块索引
使用小结
使用方法:
create 'table',{BLOOMFILTER =>'ROW'}
HColumnDescriptor.setBloomFilterType(NONE | ROW | ROWCOL)