当前一般HBase的读写(删除也认为是写)都是通过HTable对象来操作的。
首先看官方的注释
* <p>Used to communicate with a single HBase table.
*
* <p>This class is not thread safe for reads nor write.
*
* <p>In case of writes (Put, Delete), the underlying write buffer can
* be corrupted if multiple threads contend over a single HTable instance.
多线程操作同一个HTable实例的时候write buffer会混乱。也就是说HTable不是线程安全的。
具体体现在两个方面:
1.写的时候会把数据写到一个writebuffer里面,多线程的话全部写入到同一个buffer会导致数据紊乱
2. wirteBuffer清空的时候也有问题,不知道哪些数据已经写成功,哪些还未写成功。
基于这两个方面我们可以认为写的时候用同一个HTable实例时不推荐的。
有人可能会提出HTablePool是线程安全的,那用pool会如何。
实际上HTabePool的作用我认为是为了控制客户端对HTable的滥用。
其官方说明
/*Get areference to the specified table from the pool。*/
得到的仅仅是一个HTable的引用,如果当前pool中没有该table的HTable对象那么会new一个。
记住操作完以后要把该引用放回去,否则你每次去getTable都是去new一个新的对象,这是一个很大的开销。
接着来看看scan的几个参数:
1. caching
对于这个重要的参数,api上尽然说明不多。。
这个值可以大幅减少rpc时间,也就是说,如果你要求100条数据,如果你的caching是10,那么rpc通信次数只有10次,如果你的caching设置为1,那么rpc次数是100,这是一个极大地开销,不过这个值也不能设置的太大,否则对服务器端和客户端都是灾难性的。
2. batch
每个result上的kv数。
3.maxResultSize
Result的最大值
简单来说,
caching是一次从服务器端返回对少个Result对象,batch是每个Result上的kv数目,MaxResultSize是单个Result的最大值。
batch和MaxResultSize都是为了防止单个Result过大,将单个过大的Result拆开成几个返回防止客户端oom。。