HBase表设计图解

1.Get操作

需求:根据业务ID,获取这个业务ID对应的属性

以上图为例:

为什么要进行md5 或 Hash 或进行反转?

一句话说明:负载均衡,可以将记录平均分到不同的region

 

比如:业务id有时候开头是跟业务相关的一些编码。有个可能某个编码下面对应记录比较多,某些编码对应比较少。

比如上图示例中1111开头的有3条数据。其他前缀的都在3条以下

所以通过md5或者其他方式进行散列。

 

MD5  =>   DHS中选十六进制(string)

手机号反转=>DHS中选十进制(string)

其他自定义hash并序列化存储的=>DHS中选二进制

 

api:

写入:table.put  

查询:通过rowkey精准查询:table.get( Get(rowkey) )

 

DHS选“十六进制String类型”

MD5开头前缀作为rowkey代码写法:

1
2
3
4
5
6
import  com.google.common.hash.Hashing;
 
     String uid= "uid01" ;
     String md5_uid= Hashing.md5().newHasher().putString(uid).hash().toString();
     String rowkey=md5_uid+ "其他内容" ;   //因为是前缀匹配,只要前缀是MD5开头的就可以,后面有其他内容没关系。
     Put put= new  Put(rowkey.getBytes());
    table.put(put);


 


2.Scan操作(扫描操作):

利用hbase表,字典排序的特性,进行的扫描操作,要查询的数据有共同的前缀

scan操作不是无限制的!

scan操作一般都设置startkey,stopkey。数据量比较多的时候要增加salt_bucket

但是这还不够:为防止超时,scan 1w条以上的操作,要分成多次进行scan。因为scan数据操作会有大量的磁盘读取操作(磁盘IO升高),把结果放入内存(占用内存导致GC频率升高),再通过RPC发送到客户端(网络带宽)。

如果设置Filter进行过滤呢?——即使设置了Filter,也会扫描startkey到stopkey之间的所有数据。再在内存中过滤之后再返回客户端。

对客户端有什么影响?如果不分批扫描,除了对服务器磁盘内存网络造成压力,也会造成客户端超时。

下面是增加salt_bucket之后,分多个线程同时scan的情况。如果没有分salt_bucket,就是其中一个scan线程的情况。


你可能感兴趣的:(hbase,hbase用户)