Hbase使用问题记录

1、java使用HTable创建客服端

        最开始的想法是做一个HTable池,对同一张表创建多个HTable:

       config = new Configuration();
      config.set("hbase.zookeeper.quorum", "127.0.0.1"));
    config.set("hbase.zookeeper.property.clientPort", "2181"));
       HTable table1 = new HTable(conf, "myTable");
       HTable table2 = new HTable(conf, "myTable");

      似乎是没有问题,我做测试的时候也是符合预想的。但是最后部署在服务器,在并发访问的情况下,服务器出现cpu被占用完的情况(gc任务占用)。

    (1)、第一次定位问题

      经过不断的调试最后定位在HTable池的问题,测试发现只有在对同一张表创建唯一HTable时才不会出现问题。在(http://blog.csdn.net/u010967382/article/details/38046821)中得到config的属性相同则CONNECTION_INSTANCES.get返回同一个connection实例,个人认为与connection唯一有关。如果使用创建多个config也是线程不安全的,具体还不知道,只有求教各位大神!!!

     (2)、第二次定位问题

     经过严格的测试发现依然没有解决问题。看到博客(http://blog.csdn.net/pwlazy/article/details/7417135)如下:

HBase server 基本上由zookeeper和HRegion server组成
前者主要是用于监控和管理HRegion server,后者才是提供数据服务的
HRegion server又分为master+server,master用于维护meta信息,
master和server的确定使用了leader follow方式,任何HRegion server都有可能成为Master

HTable模型

  • HTable: 客户端API
  • HConnection: HTable对zookeeper的网络连接
  • ServerCallable:抽象一次和Region Server的交互,因此它需要有HConnection和HRegionLocation,同时需要有一个访问Region Server的接口
  • HRegionInterface  HRegionLocation: Region Server的地址
  • HRegionInfo: Region Server的信息 
  • HRegionInterface:访问Region Server的接口的动态代理
  • WritableRpcEngine$Invoker:动态代理的相关handle
  • HBaseClient:Region Server的客户端
  • 其他的就不解释了

HTable runtime

1)HTable的初始化step1     

  • 初始化对zookeeper的连接
  • 会调用zookeeper的api,启动两个线程,一个是sendthread,一个是eventhtread,
  • sendthread专门维护对zookeeper的连接,并且会监听zookeeper 的事件,比如节点变化的通知,一旦接到通知会将通知转发给eventhtread
  • eventhtread处理zookeeper的变化
2)HTable的初始化step2
  • 从zookeeper获取到root HRegionLocation[region=-ROOT-,,0.70236052, hostname=localhost, port=33032] 并cache
  • 从root HRegion中获取到meta  HRegionLocation[region=.META.,,1.1028785192, hostname=localhost, port=33032] 并cache
  • 从meta HRegion 取更多hregion信息缓存到本地(见HConnectionManager$HConnectionImplementation.prefetchRegionCache)
  •  从meta HRegion中获取表所在的HRegionLocation[region=testtable,,1332256150817.5c8417fb964377174f649af04a70ad5e., hostname=localhost, port=33032]并cache

3) HTable.get到底干了什么

  • 从cache中获取表对应的HRegionLocation
  • 从cache中获取HRegionLocation对应的Region server【一个实现了HRegionInterface的动态代理,使用了WritableRpcEngine$Invoker作为InvocationHandler】
  • 调用动态代理的get,解下来就会调用WritableRpcEngine$Invoker的invoke
  • 调用HBaseClient.call
4)仔细看看HBaseClient.call
    • 初始化一个Call实例(封装了请求和响应)
    • 连接到Region server(见HBaseClient.getConnection)得到HBaseClient.Connection实例,此时会启动一个读线程(每个region一个),专门读取服务端的响应,也会将请求写入读线程的队列中
    • 发请求,见【HBaseClient.Connection.sendParam(call)】,如果是多个请求线程,由于此时共用一个连接,还存在同步问题,且网络写也是阻塞的,写完了还得等通知
    • 读线程会不断的读取响应,读取一个相应响应就将请求队列中对应的请求删除,并通知主线程即客户端线程,如果读线程空闲超时会自动回收
    • 客户端线程和读线程采用传统的wait + notify 通信,这也意味着客户端线程会阻塞

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值