HBase写入操作卡住长时间不返回的原因分析

本文讨论了在使用HBase时遇到的表创建失败问题,分析了问题原因在于hosts文件配置错误导致的主机名解析问题,并提供了解决步骤。

本文出处:http://blog.youkuaiyun.com/chaijunkun/article/details/44238163,转载请注明。由于本人不定期会整理相关博文,会对相应内容作出完善。因此强烈建议在原始出处查看此文。


这些天研究HBase,写了一段Demo代码,具体如下:

@Test
public void doTest() throws MasterNotRunningException, ZooKeeperConnectionException, IOException {
	Configuration config = HBaseConfiguration.create();
	config.set(zkSetKey, zkConn);
	HBaseAdmin hBaseAdmin = null;
	try{
		hBaseAdmin = new HBaseAdmin(config);
		ClusterStatus clusterStatus = hBaseAdmin.getClusterStatus();
		ServerName master = clusterStatus.getMaster();
		log.info("Master主机:{},端口号:{}", master.getHostname(), master.getPort());
		Collection<ServerName> servers = clusterStatus.getServers();
		for (ServerName serverName : servers) {
			log.info("Region主机{},端口号:{}", serverName.getHostname(), serverName.getPort());
		}
		HTableDescriptor targetTableDesc = null;
		try{
			targetTableDesc = hBaseAdmin.getTableDescriptor(TableName.valueOf(tableName));
			log.info("表已经存在,显示信息");
			log.info("属性:{}", targetTableDesc.toString());
		}catch(TableNotFoundException notFound){
			log.info("表不存在,创建");
			HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(tableName));
			HColumnDescriptor hcd_info = new HColumnDescriptor("info");
			hcd_info.setMaxVersions(3);
			HColumnDescriptor hcd_data = new HColumnDescriptor("data");
			htd.addFamily(hcd_info);
			htd.addFamily(hcd_data);
			hBaseAdmin.createTable(htd);
			log.info("创建成功");
			targetTableDesc = hBaseAdmin.getTableDescriptor(TableName.valueOf(tableName));
			log.info("属性:{}", targetTableDesc.toString());
		}
		TableName[] listTableNames = hBaseAdmin.listTableNames();
		if (listTableNames == null){
			log.info("无表");
		}else{
			for (TableName tableName : listTableNames) {
				log.info("表名:{}", tableName.getNameAsString());
			}
		}
	}finally{
		IOUtils.closeQuietly(hBaseAdmin);
		log.info("结束");
	}
}
运行这段代码 程序会卡在第28行不动,也就是创建表操作,并且没有报出任何异常,其它的读取操作却很快(例如获取集群状态、列出所有表等操作)。于是本人陷入了深深地思考……

在优快云找到了一种类似的情况:http://blog.youkuaiyun.com/lxpbs8851/article/details/8287471

主要是说HBase所依赖的HDFS进入了安全模式,需要手动退出该模式(运行命令:hdfs dfsadmin -safemode leave)。可是我查询当前的HDFS安全模式状态(hdfs dfsadmin -safemode get)时得到的信息是:Safe mode is OFF,也就是说根本没在安全模式下。


后来偶然地过了一段时间再去看日志发现如下信息:

#1, waiting for some tasks to finish. Expected max=0, tasksSent=9, tasksDone=8, currentTasksDone=8, retries=8 hasError=false, tableName=demo_table
#1, waiting for some tasks to finish. Expected max=0, tasksSent=10, tasksDone=9, currentTasksDone=9, retries=9 hasError=false, tableName=demo_table
#1, table=demo_table, attempt=10/35 failed 1 ops, last exception: java.net.UnknownHostException: unknown host: admin.demo.com on admin.demo.cn,5020,1426211698289, tracking started Fri Mar 13 11:41:19 CST 2015, retrying after 10037 ms, replay 1 ops.


最后一行的主机名:admin.demo.com和admin.demo.cn引起了我的注意。因为我的测试环境为3台实体服务器,配置如下:

IP地址hosts文件配置的主机名linux系统的hostnameHBase角色HDFS角色
192.168.1.21hd-21test-21MasterServerNameNode、DataNode、ZooKeeper
192.168.1.22hd-22test-22RegionServerNameNode、DataNode、ZooKeeper
192.168.1.23hd-23test-23RegionServerDataNode、ZooKeeper
另外,因为是测试环境,在192.168.1.22这台机器上还添加了如下hosts信息:

192.168.1.22 admin.demo.com
192.168.1.22 admin.demo.cn
简单来说就是hosts文件中配置的主机名和真实主机名不一致,并且还加入了额外的hosts配置信息干扰到了正确解析主机名。

运行demo程序的工作机没有配置任何额外的hosts,连接ZooKeeper时直接使用的IP地址,但是HBase Client 底层在进行操作时可能引入了主机名反向连接,作为完全干净的工作机当然找不到对应的服务器,就不断地在后台重试导致生成了上述的日志。当我把出现问题的两个hosts记录加入到工作机后,问题解决


经验:通过上述错误可知,Hadoop集群中hostname一定要与hosts文件中配置的名称一致,并且力求保证集群映射关系的纯净,不要把其他不相干的业务也部署在其中,引起不必要的麻烦。

### HBase Shell 卡住的可能原因及解决方案 HBase Shell 卡住的问题可能是由多种原因引起的,以下是一些常见的原因和解决方法: #### 1. **ZooKeeper 连接问题** 如果 ZooKeeper 集群可用或连接稳定,HBase Shell 可能会卡住。这是因为 HBase 依赖 ZooKeeper 来管理集群状态和元数据[^3]。 - 检查 ZooKeeper 的日志文件,确保没有错误信息。 - 使用 `echo stat | nc <zk_host> <zk_port>` 命令检查 ZooKeeper 的状态。 - 如果发现 ZooKeeper 可用,请重启 ZooKeeper 集群。 #### 2. **HBase RegionServer 或 Master 可用** HBase Shell 需要与 HBase Master 和 RegionServer 通信。如果这些服务可用,Shell 可能会卡住[^1]。 - 检查 HBase Master 和 RegionServer 的日志文件,查找错误信息。 - 使用命令 `jps` 检查 HBase Master 和 RegionServer 是否正在运行。 - 如果发现问题,请重启相关服务: ```bash $ $HBASE_HOME/bin/stop-hbase.sh $ $HBASE_HOME/bin/start-hbase.sh ``` #### 3. **网络延迟或超时** 高网络延迟或超时可能导致 HBase Shell 卡住。这通常发生在分布式环境中[^2]。 - 检查网络连接是否正常。 - 调整 HBase 的超时配置参数,例如 `hbase.client.operation.timeout` 和 `zookeeper.session.timeout`。 - 编辑 `hbase-site.xml` 文件并重新启动 HBase 集群: ```xml <property> <name>hbase.client.operation.timeout</name> <value>60000</value> </property> <property> <name>zookeeper.session.timeout</name> <value>60000</value> </property> ``` #### 4. **资源足** 如果服务器资源(如内存、CPU 或磁盘 I/O)足,HBase Shell 可能会卡住。 - 检查服务器的资源使用情况,确保有足够的内存和 CPU。 - 使用命令 `top` 或 `htop` 监控系统资源。 - 如果资源足,请优化 HBase配置或增加硬件资源。 #### 5. **HBase Shell 内部问题** 有时 HBase Shell 自身可能存在 bug 或者未正确初始化。 - 尝试退出并重新进入 HBase Shell: ```bash $ hbase shell ``` - 如果仍然卡住,可以尝试清理 HBase 的临时文件: ```bash $ rm -rf /tmp/hbase* ``` #### 6. **数据一致或损坏** 如果 HDFS 上的数据块损坏或 HBase Region 数据一致,可能会导致 Shell 卡住。 - 检查 HDFS 的健康状态: ```bash $ hdfs fsck / ``` - 如果发现损坏的数据块,请修复或删除它们。 - 重启 HBase 集群以确保数据一致性。 --- ### 示例代码:调整 HBase 超时配置 以下是一个示例,展示如何通过修改 `hbase-site.xml` 来调整超时设置: ```xml <configuration> <property> <name>hbase.client.operation.timeout</name> <value>120000</value> </property> <property> <name>zookeeper.session.timeout</name> <value>120000</value> </property> </configuration> ``` --- ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值