hbase连接java时,zookeeper总是连接不上,但是确实已经启动,每次连接,都报错

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hbase连接java时,zookeeper总是连接不上,但是确实已经启动,每次连接,都报错相关的知识,希望对你有一定的参考价值。

hadoop 2.7 java 1.7 hbase1.2.3 zookeeper内置的。2017-04-13 08:05:37,242 WARN [NioserverCxn.Factory:0.0.0.0/0.0.0.0:2181] server.NIOServerCnxn: caught end of stream exceptionEndOfStreamException: Unable to read additional data from client sessionid 0x15b67d839510006, likely client has closed socket at org.apache.zookeeper.server.NIOServerCnxn.doIO(NIOServerCnxn.java:228) at org.apache.zookeeper.server.NIOServerCnxnFactory.run(NIOServerCnxnFactory.java:208) at java.lang.Thread.run(Thread.java:745)

参考技术A HBase的安装包里面有自带zookeeper的。很多系统部署也是直接启动上面的zookeeper。 本来也是没有问题的,想想吧,系统里也只有hbase在用zookeeper。先启动zookeeper,再将hbase起来就好了 ? 但是今天遇到了一个很蛋疼的问题。和同事争论了很久。 ? 因为我们是好多hbase集群共用一个zookeeper的,其中一个集群需要从hbase 0.90.二 升级到hbase 0.9二上,自然,包也要更新。但是其中一台regionserver上面同时也有跑zookeeper,而zookeeper还是用hbase 0.90.二 自带的zookeeper在跑。 ? 现在好了,升级一个regionserver,连着zookeeper也要受到牵连,看来必须要重启,不然,jar包替换掉,可能会影响到zk正在跑的经常。但是重启zk毕竟对正在连接这个zk的client端会有短暂的影响

HiveServer2中使用jdbc访问hbase时导致ZooKeeper连接持续增加的解决

最近在监控中发现HiveServer2连接到zookeeper里的连接持续上涨,很奇怪,虽然知道HiveServer2支持并发连接,使用ZooKeeper来管理Hive表的读写锁,但我们的环境并不需要这些,我们已经关闭并发功能,以下是线上的配置,甚至把这些值都改成final了。

技术分享


但是zookeeper连接依然会涨。后来想想,我们要访问的表是hive去映射的hbase,hiveserver2什么时候去连接zookeeper,它连接zookeeper干么,先从日志下手,将线上日志级别改为了debug,然后在hiveserver2.log发现了如下信息:

2016-02-23 14:03:30,271 DEBUG [HiveServer2-Background-Pool: Thread-598-SendThread(hadoop002:2181)]: zookeeper.ClientCnxn (ClientCnxn.java:readResponse(717)) - Got ping response for sessionid: 0x252fd37100600d2 after 0ms
2016-02-23 14:03:30,325 DEBUG [HiveServer2-Background-Pool: Thread-797-SendThread(hadoop003:2181)]: zookeeper.ClientCnxn (ClientCnxn.java:readResponse(717)) - Got ping response for sessionid: 0x352fd3707b600e3 after 0ms
2016-02-23 14:03:30,626 DEBUG [HiveServer2-Background-Pool: Thread-1138-SendThread(hadoop003:2181)]: zookeeper.ClientCnxn (ClientCnxn.java:readResponse(717)) - Got ping response for sessionid: 0x352fd3707b600e8 after 0ms
2016-02-23 14:03:30,768 DEBUG [HiveServer2-Background-Pool: Thread-730-SendThread(hadoop001:2181)]: zookeeper.ClientCnxn (ClientCnxn.java:readResponse(717)) - Got ping response for sessionid: 0x152fd3707c800db after 0ms
2016-02-23 14:03:32,751 DEBUG [HiveServer2-Background-Pool: Thread-461-SendThread(hadoop001:2181)]: zookeeper.ClientCnxn (ClientCnxn.java:readResponse(717)) - Got ping response for sessionid: 0x152fd3707c800d5 after 0ms
2016-02-23 14:03:33,057 DEBUG [HiveServer2-Background-Pool: Thread-1211-SendThread(hadoop002:2181)]: zookeeper.ClientCnxn (ClientCnxn.java:readResponse(717)) - Got ping response for sessionid: 0x252fd37100600dd after 0ms


这是个线程池,由SessionManager创建,但它是在何时创建的,从日志里一时不好看出来,所以在我们测试环境里对HiveServer2搞了个远程调试,启用远程调试步骤:

在/etc/hive/conf/conf.server下hive-env.sh里上方添加:#add by lidong for remote debug
export HADOOP_OPTS="$HADOOP_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8888 -XX:NewRatio=12 -XX:MaxHeapFreeRatio=40 -XX:MinHeapFreeRatio=15 -XX:-UseGCOverheadLimit"

又经过近2天的折腾,终于搞明白了这个zookeeper连接是在Hive工程里的MapRedTask的execute(DriverContext driverContext) 方法里创建的:

...

      if (!runningViaChild) { //这句很重要,解决就靠它了
        // we are not running this mapred task via child jvm
        // so directly invoke ExecDriver
        return super.execute(driverContext);//就是这句,会调用hadoop里的JobClient去submitJob(job);  然后zookeeper连接就产生了
      }


...

后面也再没去清理zookeeper的连接,导致就留下了

原因都清楚了,我选择了更为简单的处理办法,让控制runningViaChild的参数为true,让每个job在hiveserver2里都是子进程去提交,子进程结束,所有的资源都释放了



解决办法就是:

在hive-site.xml里,把

hive.exec.submitviachild 设置为true



调试的堆栈信息留个纪念:

技术分享

以上是关于hbase连接java时,zookeeper总是连接不上,但是确实已经启动,每次连接,都报错的主要内容,如果未能解决你的问题,请参考以下文章

HBase单节点下JavaAPI连接

如何使用hbase自带的zookeeper

错误 HBASE-ZOOKEEPER:连接太多

连接HBase的正确姿势

HBase连接数据库(集群)

在 HappyBase HBase 客户端中设置 Zookeeper 节点(znode)设置