浅谈hBase 的rowkey设计与filter查询
Posted 南方IT界
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈hBase 的rowkey设计与filter查询相关的知识,希望对你有一定的参考价值。
浅谈hBase 的rowkey设计与filter查询
丨Part 1 hBase的rowkey设计丨
hBase是一个分布式的、面向列的数据库,它和一般关系型数据库的最大区别是,hBase很适合于存储非结构化的数据,还有就是它基于列的而不是基于行的模式。hBase采用key-value的列存储,其中rowkey是一段二进制码流,最大长度为64KB,内容可以由使用的用户自定义,数据加载时,一般也是根据rowkey的二进制序由小到大进行的。hBase是根据rowkey来进行检索的,系统通过找到某个rowkey (或者某个 rowkey 范围)所在的region,然后将查询数据的请求路由到该region获取数据。
rowkey是一个二进制码流,rowkey在设计上必须保证其唯一性,其长度一般建议设计成10~100个字节,而且是越短越好,最好不要超过16个字节。hBase中的行是按照rowkey的字典顺序排序的,可以将相关的行以及会被一起读取的行存取在临近位置,从而使得scan操作变得更加简单。另一方面,如果rowkey设计得很糟糕,将会造成读写操作的热点,大量的client将直接访问集群的一个或极少数个节点,使得热点region的性能下降,同时也会影响同一个regionServer上的其他region。 因此,应该保持良好的rowkey设计习惯,让集群被充分均衡地利用,更多的数据情能够被写入集群的多个region,下面将对一些常见的避免热点的方法进行介绍。
1.在rowkey的前面增加随机数,具体就是给rowkey分配一个随机前缀。分配的前缀种类数量应该和你想使用数据分散到不同的region的数量一致,经过处理之后的rowkey将会分散到各个region上。
2.在rowkey前面添加设计好的Hash前缀,让所有的数据散列到多个Region服务器上。使用确定的哈希可以让客户端重构完整的rowkey,通过使用get操作准确地获取到某一个行的数据。
3.第三种防止热点的方法是反转,将固定长度或者数字格式的rowkey进行反转。这种处理可以让rowkey中经常改变的部分放在前面,通过牺牲rowkey的有序性,保证了rowkey的随机性。
丨Part 2 hBase的filter查询丨
hBase的普通检索主要有两种方式,一是通过单个rowkey访问,即按照某个rowkey键值进行get操作,这样获取唯一的一条记录,二是通过rowkey的range进行scan,即通过设置startRowkey和endRowkey,在这个范围内进行扫描,从而按指定的条件获取一批记录。HBASE按单个rowkey检索的效率是相当高的,耗时在1毫秒以下,每秒钟可获取1000~2000条记录,但是非key列的查询就很慢了。hBase 除了提供上面提到的这些简单查询,还提供了更加高级的filter来满足更多复杂的查询。
过滤器可以根据列族、列、版本等更多的条件来对数据进行过滤,高效地完成查询过滤的任务,带有过滤器条件的RPC查询请求会把过滤器分发到各个 regionServer,达到降低网络传输压力的目的。通过提供一组过滤器,hBase可以对hBase中数据的多个维度进行筛选,最终筛选出来的数据能够细化到具体的一个存储单元格上。 通常来说,通过行键和值来筛选数据的应用场景较多,其中应用得比较多的过滤器包括RowFilter、PrefixFilter、FirstKeyOnlyFilter和ValueFilter。
1. RowFilter:筛选出匹配的所有的行,对于这个过滤器的应用场景,是非常直观的,使用BinaryComparator可以筛选出具有某个行键的行,或者通过改变比较运算符来筛选出符合某一条件的多条数据,以下就是筛选出行键为row0的一行数据。
Filter mFilter = new RowFilter(CompareFilter.CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("row0")));
2. PrefixFilter:筛选出具有特定前缀的行键的数据,这个过滤器所实现的功能其实也可以由RowFilter结合RegexComparator来实现,不过这里提供了一种更为简便的方法,以下过滤器将筛选出行键以prefix为前缀的所有的行。
Filter mFilter = new PrefixFilter(Bytes.toBytes("prefix"));
3. FirstKeyOnlyFilter:如果你只想返回的结果集中只包含第一列的数据,那么这个过滤器能够满足你的要求。它在找到每行的第一列之后会停止扫描,从而使扫描的性能也得到了一定的提升。
Filter mFilter = new FirstKeyOnlyFilter();
4. ValueFilter:按照具体的值来筛选单元格的过滤器,这会把一行中值不能满足的单元格过滤掉,对于每一行的一个列,如果其对应的值不包含row_value,那么这个列将不会返回到客户端。
Filter mFilter = new ValueFilter(CompareFilter.CompareOp.EQUAL, new SubstringComparator("row_value"));
除此以外,hBase还提供了FilterList用于综合使用多个过滤器,通过指定FilterList.Operator.MUST_PASS_ONE和FilterList.Operator.MUST_PASS_ALL,来分别设置必须通过所有过滤器或者仅需通过其中一个过滤器,FilterList可以嵌套使用FilterList,面对复杂的查询需求也能够得心应手。
南方IT界
以上是关于浅谈hBase 的rowkey设计与filter查询的主要内容,如果未能解决你的问题,请参考以下文章