HTablePool的实现分析
来源:互联网 发布:movielens数据集下载 编辑:程序博客网 时间:2024/06/03 08:17
1)基本概念
HTablePool
- 3种类型
- PoolType.Reusable(默认)一个实例池,多线程复用,内部是每个table一个ConcurrentLinkedQueue装多个实例
- PoolType.ThreadLocal,很奇怪的实现,每个线程只能有一个实例,感觉在多线程的场景没有意义
- PoolType.RoundRobin(没有被使用,就算设置了该类型也没用,见HTablePool的构造函数)
- PoolMap<String, HTableInterface> tables:用于存放table实例,正如上面提到的默认是每个table对应一个ConcurrentLinkedQueue
- maxSize:pool的最大尺寸
2)样例代码
[java] view plaincopy
- public class HTablePoolTest {
- protected static String TEST_TABLE_NAME = "testtable";
- protected static String ROW1_STR = "row1";
- protected static String COLFAM1_STR = "colfam1";
- protected static String QUAL1_STR = "qual1";
- private final static byte[] ROW1 = Bytes.toBytes(ROW1_STR);
- private final static byte[] COLFAM1 = Bytes.toBytes(COLFAM1_STR);
- private final static byte[] QUAL1 = Bytes.toBytes(QUAL1_STR);
- private static HTablePool pool;
- @BeforeClass
- public static void runBeforeClass() throws IOException {
- Configuration conf = HBaseConfiguration.create();
- pool = new HTablePool(conf, 10);
- // 填充pool
- HTableInterface[] tables = new HTableInterface[10];
- for (int n = 0; n < 10; n++) {
- tables[n] = pool.getTable(TEST_TABLE_NAME);
- }
- for (HTableInterface table : tables) {
- table.close();
- }
- }
- @Test
- public void testHTablePool() throws IOException, InterruptedException,
- ExecutionException {
- Callable<Result> callable = new Callable<Result>() {
- public Result call() throws Exception {
- return get();
- }
- };
- FutureTask<Result> task1 = new FutureTask<Result>(callable);
- FutureTask<Result> task2 = new FutureTask<Result>(callable);
- Thread thread1 = new Thread(task1, "THREAD-1");
- thread1.start();
- Thread thread2 = new Thread(task2, "THREAD-2");
- thread2.start();
- Result result1 = task1.get();
- assertThat(Bytes.toString(result1.getValue(COLFAM1, QUAL1)), is("val1"));
- Result result2 = task2.get();
- assertThat(Bytes.toString(result2.getValue(COLFAM1, QUAL1)), is("val1"));
- }
- private Result get() {
- HTableInterface table = pool.getTable(TEST_TABLE_NAME);
- Get get = new Get(ROW1);
- try {
- Result result = table.get(get);
- return result;
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- return null;
- } finally {
- try {
- table.close();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
- 使用多线程访问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);
- 从regionserver获取数据
- 该动作具体的详细细节见我的博文http://blog.csdn.net/pwlazy/article/details/7417135
3.4)table.close();
- 将table归还到HTablePool中,如果此时HTablePool尺寸超过最大尺寸,释放该实例,
- 关于释放HTable实例与释放连接的问题
- HTable实例相关的两个连接,一个是对zookeeper,一个是regionServer
- 如果没有其他HTable实例(在HTablePool尺寸大于0的情况不可能出现这种情况),及没有zookeeper的连接计数为0,此时才会释放zookeeper连接
- regionServer的连接有HBaseClient$Connection这个线程单独维护,与HTable实例基本没啥关系,注意HBaseClient$Connection这个线程绑定了连接
- 容纳了多个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而带来同步和阻塞的问题,线上使用必须好好的压力测试一下
0 0
- HTablePool的实现分析
- HTablePool的实现分析
- HTablePool的实现分析
- HTablePool 的使用方法
- hbase的 HTablePool
- HTablePool 连接池源码分析
- Hbase利用HTablePool实现Htable连接池
- Hbase 的 htablepool的小记录
- HTablePool的替代者HConnection.getTable(String)
- HTablePool简单使用例子
- HTablePool实例代码
- [HBase] HTable && HTablePool
- hbase 客户端HTablePool
- HTablePool简单使用例子
- HBase连接池 -- HTablePool
- HTablePool为何弃用?
- CppUnitLite的实现分析
- 红黑树的实现分析
- QT5 学习之路21---文件对话框
- Android 自定义View (一)
- 【总结】Java基础总结⑷
- var_dump($user);die;
- Gson解析(3)——Map处理数据(上)
- HTablePool的实现分析
- 二维码的生成
- Hadoop Yarn内存使用优化配置
- iOS 关于应用能打包但是不能提交至App Store的解决办法
- Hadoop mapreduce自定义分组RawComparator
- 菜鸟的Linux历程-Apache源码包安装及知识点摘要
- Gson解析(4)——Map处理数据(下)
- Hadoop2.6.0防止误删机制-Trash
- Hadoop2.6.0遇到的问题