Java操作HBase时报NotServingRegionException异常

目前开始学习Hbase,通过API在HBase中建表,代码如下:

Configuration conf = HBaseConfiguration.create();		
		conf.set("hbase.zookeeper.quorum", "cmaster1.hadoop.xxt.cn,cmaster0.hadoop.xxt.cn,cslave0.hadoop.xxt.cn");

		Connection connection = null;
		Admin admin = null;
		try {
			connection = ConnectionFactory.createConnection(conf);
			admin = connection.getAdmin();
			
			TableName tn = TableName.valueOf(tableName);
			
			if (!admin.tableExists(tableName)) {	
			HTableDescriptor tableDesc =  new HTableDescriptor(tableName);
			HColumnDescriptor columnDesc = new HColumnDescriptor(Bytes.toBytes(familyName));
			columnDesc.setCompressionType(Algorithm.SNAPPY);
			tableDesc.addFamily(columnDesc);
			byte[][] splitKey = new byte[][]{Bytes.toBytes("000001000000"),Bytes.toBytes("000010000000"),
				Bytes.toBytes("000050000000"), Bytes.toBytes("000100000000")};
				
			admin.createTable(tableDesc, splitKey);
			log.info("create table success");
		}
			
		} catch (IOException e) {
			log.error("Clicklog bulkload job execute failed!", e);
			throw new RuntimeException("Clicklog bulkload job execute failed!", e);
		}
在eclipse中可以正常执行,打成jar放在集群中,却一直报错。错误日志如图:

网上也搜了下解决办法,原因也比较多,总结如下:

可能原因1:
zookeeper引起的,通常这种情况往往是在你正在运行一个进程正在操作hbase数据库的时候,hbase进程被杀掉或hbase服务被停掉所引起的,如果是hbase自身管理的zookeeper
解决方法1:
可以将hbase的zookeeper目录下的文件全都删除掉,然后再重启hbase服务就可以了.
解决方法2:
检查一下是否只有master创建了zookeeper目录
注释:
配置zookeeper的的目录为属性hbase.zookeeper.property.dataDir


可能原因2:
数据损坏导致当前数据存放的regin无法使用,使用hadoop fsck检查是否有损坏块


解决方案:
此时使用hadoop fsck 进行分析 就能看到CORRUPT 的storefile路径 hadoop fs -rm 当前storefile


其中,最有可能的情况是第一种,在操作之前,先搞清楚zookeeper和hbase是什么关系?

HBase中有两张特殊的Table,-ROOT-和 .META.

  .META.: 记录了用户表的Region信息,.META. 可以有多个region 

  -ROOT:记录了 .META. 表的Region的信息, -ROOT-只有一个Region

Zookeeper 中记录了 -ROOT-表的location,具体信息默认在/hbase目录下,

客户端连接Zookeeper的时候,先连接 -ROOT- 再找 .META, 就可定位到需要请求的数据在那一台服务器上面。

Zookeeper为HBase提供了稳定的服务和failover 机制,具体职责:

1. 选举集群中的Master,Master与RegionServers 启动时会向ZooKeeper注册。 
2. 存储所有Region的寻址入口。 
3. 实时监控Region server状态并实时通知Master。 
4. 存储HBase的schema和table元数据。 
5. 使Master不存在单点故障。

通过zkCli.sh进入到zookeeper目录管理界面,

ls /  可以看到很多目录


执行 rmr  /hbase删掉管理的hbase目录(注意此时hbase服务要先停掉)。重启HBase后,会在zookeeper下重新注册。


于是我按照这个步骤开始执行,重启HBase后却发现/hbase目录不再创建,可以HBase却正常运行。这个问题很困扰,搜了很多资料都没能解决。


最后发现zookeeper目录下有个/hbase-unsecure目录,猜想可能与这个有关。

我的集群是用Ambari搭建的,搜一下Ambari与这个目录相关的东西,果然Ambari默认HBase在zookeeper下存放位置正是hbase-unseure。

至此,困扰许久的问题终于得以解决,原来一开始我的问题并不是由于其他问题造成的,而是该路径不对。集群通过zookeeper获取hbase元数据,默认是找/hbase目录,估计之前搭建过hbase环境,保留了部分东西,才导致这个错误,希望zookeeper找/hbase-secure时只需要在代码中加上conf.set("zookeeper.znode.parent", "/hbase-unsecure");

就ok了。


你可能感兴趣的:(hbase)