hbase 客户端HTablePool

1、首先定义一个池,重点: 定义一个什么资源(R)的池子, 池子应该有增删改查、大小等功能。

  protected interface Pool {
    public R get();
    public R put(R resource);
    public boolean remove(R resource);
    public void clear();
    public Collection values();
    public int size();
  }

2、定义完池子后、确定池子的类型,也即池的实现

  public enum PoolType {
    Reusable, ThreadLocal, RoundRobin;

池子的实现描述:  Reusable ,把资源放到一个LinkedList 中,使用的时候从List中移除、使用完后再放回

                                   ThreadLocal, 基于ThreadLocal 线程安全的线程池,用于多线程并发时

                                    RoundRobin ,基于copyonWriteArrayList (一个ArrayList线程安全的变体,适用于读多写少)的一个池,取一次然后+1接下来除size() 求余、然后再get


3、 池子中放什么、是不是需要MapPool(不同的key对应不同的池),接下来梳理一下hbase HTable的情况

首先HTable 不是线程安全的

我们要想对HTable操作就需要创建多个 HTable instance ,这样每次创建都是很费劲的、所以需要把HTable instance 放到池中,但是所有的实例都放到一起的话逻辑比较混乱,于是我们创建一个 PoolMap 把 表名与池映射起来,也就是说一个表有一个池。

当我们需要一个表的时候、我们就会根据表名上PoolMap中根据表名获取HTable instance ,如果没有获取到就创建一个、但是这里请注意,创建完成之后并如在池中,只有当调用close的时候才放回到池中。  close 时的流程是,检查该表有没有pool 没有的话创建一个,并把该表及对应的pool放到poolMap中。

附图:

hbase 客户端HTablePool_第1张图片




针对上面的这种实现其实还是挺费劲的、所以后来社区有了一个新的解决方案、接下来对新方案进行讲解,参考:https://issues.apache.org/jira/browse/HBASE-6580


改变完了之后就是通过 HConnectionManager.getConnection获取Connection、同时ExcuteService池在connection中初始化 、然后通过Connection 获取 HTable ,并把pool传给HTable, 这样每一个HTable instance 提交请求之类的都是走同一个pool ,原先的话是每一个HTable instance都有一个 ExcuteService pool


前面已经说过了、所有HTable 共用一个Hconnection  和 config 为最佳方案,也是正确方案。下一篇开始讲Hconnection




                                    

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