HTablePool的实现分析

1)基本概念

HTablePool

  • ​3种类型
    • ​PoolType.Reusable(默认)一个实例池,多线程复用,内部是每个table一个ConcurrentLinkedQueue装多个实例
    • PoolType.ThreadLocal,很奇怪的实现,每个线程只能有一个实例,感觉在多线程的场景没有意义
    • PoolType.RoundRobin​(没有被使用,就算设置了该类型也没用,见HTablePool的构造函数)
  • PoolMap<String, HTableInterface> tables​:用于存放table实例,正如上面提到的默认是每个table对应一个ConcurrentLinkedQueue​
  • maxSize:pool的最大尺寸​

2)样例代码

  • 使用多线程访问HTablePool


3)关键点分析

3.1)初始化

HTablePool pool = new HTablePool(conf, 5);

  • 实例化PoolMap
  • ​实例化HTablePool,此时还没有任何HTable实例​,tables为空

3.2)获取table实例

pool.getTable(TEST_TABLE_NAME);​

  • 查看tables是否含有table,如果没有,创建一个HTable实例,HTable的初始化具体的细节见我的博文http://blog.csdn.net/pwlazy/article/details/7417135
  • 将返回HTable实例封装成PooledHTable实例返回
  • PooledHTable是​HTable的一个Wrapper,除了close()不一样,​PooledHTable的close会将​HTable实例返回到上面提到的tables中
  • 所以tables确实存放的是HTable实例,但取出来丢给应用程序的就是PooledHTable实例

3.3)table.get(get);

3.4)table.close();

  • 将table归还到​HTablePool中,如果此时​HTablePool尺寸超过最大尺寸,释放该实例​,
  • 关于释放HTable实例与释放连接的问题
    • HTable实例相关的两个连接,一个是对zookeeper,一个是regionServer
    • 如果没有其他HTable实例​(在HTablePool尺寸大于0的情况不可能出现这种情况),及没有zookeeper的连接计数为0,此时才会释放zookeeper连接
    • ​regionServer的连接有HBaseClient$Connection这个线程单独维护,与HTable实例基本没啥关系,注意HBaseClient$Connection这个线程绑定了连接
4)总体看HTablePool

  • ​容纳了多个HTable实例
  • 多个HTable实例会共享同一个zookeeper连接
  • 多个HTable实例,如果同在一个RegionServer会共享同一个连接HBaseClient$Connection
  • 很容易让人误解每个HTable实例都有一个HBaseClient$Connection,就像连接池那样,其实不是
  • 虽然HTablePool有最大尺寸,但并没有限制HTable实例不得大于这个尺寸,一旦超过这个尺寸就会实例化,但归还到实例池的时候,如果池满了会弃用,因此​HTablePool就是一个对象池而不是连接池
  • 使用HTablePool的意义?《HBase-The-Definitive-Guide​》 作者是这么说的
    • ​实例化HTable实例比较耗时,最好启动时初始化(这个理由不是很充分,完全可以使用HTable单例)
    • HTable实例线程不安全,特别是在auto flash为false的情况,因为存在本地的write buffer ,即使​auto flash为true,也不建议使用(对此作者并没说为什么​)
    • 建议每个线程一个HTable实例
  • HTablePool存在的问题​​​​​
    • ​PooledHTable的代码很恶心,PooledHTable作为一个HTable的wrapper,两者的关系应该是包含,但源码中却是继承
    • ​HTablePool并不是连接池,就是直接使用​HBaseClient$Connection【如果是同一个region的话就是单线程】来完成网络通讯的,后者的问题在​我的博文http://blog.csdn.net/pwlazy/article/details/7417135有提到, 的确存在多个线程使用​单个HBaseClient$Connection而带来同步和阻塞的问题,线上使用必须好好的压力测试一下

你可能感兴趣的:(table)