6.windows下开发HBase应用程序,HBase部署在linux环境中,在运行调试时可能会出现无法找到主机,类似异常信息如下:
java.net.UnknownHostException: unknown host: gp-node02
解决办法如下:
在C:\WINDOWS\system32\drivers\etc\hosts文件中添加如下信息:
在linux 的 /etc/hosts也要添加该行信息
192.168.137.139 gp-node02
评注:
其实这个也是网络问题的一种,无论是开发,还是集群搭建,当我们换机器访问的时候,我们需要配置下hosts,如果不配置,就只能使用ip地址访问。
7.执行MapReduce遇到的问题:文件租约超期异常.
org.apache.hadoop.hdfs.server.namenode.LeaseExpiredException
DataNode上有如下信息:IOE:java.io.IOException: xceiverCount 2049 exceeds the limit of concurrent xcievers 2048
原因:
1.执行操作的时候某文件被删的,避免方式:别同时写一个文件
2.dfs.datanode.max.xcievers参数到达上限,增大dfs.datanode.max.xcievers参数值
评注:
dfs.datanode.max.xcievers 对于datanode来说,就如同linux上的文件句柄的限制,当datanode 上面的连接数操作配置中的设置时,datanode就会拒绝连接。
8、所有节点region server进程挂掉,hbase不可访问,查看日志有如下信息:
java.net.SocketException: Too many open files
解决办法:
修改ulimit 值为8192,在master 节点上执行$hbase_home/bin/start-hbase.sh 重启所有节点上的region server,服务恢复.
评注:
在搭建集群的过程中,我们的准备工作中,都需要修改下句柄,防止出现类似问题。
推荐参考:
hbase 0.96整合到hadoop2.2三个节点全分布式安装高可靠文档
https://www.aboutyun.com/forum.php?mod=viewthread&tid=7746
9、HMaster启动之后马上挂掉
查看日志里面报错信息如下:
2015-10-14 17:48:29,476 FATAL [master:hbase1:60000] master.HMaster: Unhandled exception. Starting shutdown.
org.apache.hadoop.hbase.util.FileSystemVersionException: HBase file layout needs to be upgraded. You have version null and I want version 8. Consult http://hbase.apache.org/book.html for further information about upgrading HBase. Is your hbase.rootdir valid? If so, you may need to run 'hbase hbck -fixVersionFile'.
at org.apache.hadoop.hbase.util.FSUtils.checkVersion(FSUtils.java:600)
at org.apache.hadoop.hbase.master.MasterFileSystem.checkRootDir(MasterFileSystem.java:462)
at org.apache.hadoop.hbase.master.MasterFileSystem.createInitialFileSystemLayout(MasterFileSystem.java:153)
at org.apache.hadoop.hbase.master.MasterFileSystem.(MasterFileSystem.java:129)
at org.apache.hadoop.hbase.master.HMaster.finishInitialization(HMaster.java:800)
at org.apache.hadoop.hbase.master.HMaster.run(HMaster.java:605)
at java.lang.Thread.run(Thread.java:744)
解决方案 1:
试过了很多方法,最终通过在hdfs中,删除hbase的目录,然后重启hbase master 解决
那么,hbase的目录是哪一个呢?在 : $HBASE_HOME/conf/hbase-site.xml里面配置,通常为/hbase
hbase.rootdir
/hbase
解决方案 2:
查看目录
bin/hadoop fs -ls /hbase
发现/hbase/hbase.version已经消失了,原来是之前的这个文件可能被损坏了,去/lost+found目录找确实能找到,但是这个文件似乎出了问题,-ls它也看不到。做以下操作:
bin/hadoop fs -mv /hbase /hbase.bk
重启HBase,这时就生成了/hbase/hbase.version文件,然后:
bin/hadoop fs -cp /hbase/hbase.version /hbase.bk/
bin/hadoop fs -rmr /hbase
bin/hadoop fs -mv /hbase.bk /hbase
这样再次重启HBase,发现Hbase开始splitting hlogs,数据得以恢复
评注:
上面是两种解决办法,一个可以在学习环境下,一个是在生产环境下。一个问题解决办法其实有多个,我们如果在有能力的情况,能细致的解决问题,这样可以让我们学习,获取更多的知识。
10、regionserver 频繁挂掉的故障
首先regionserver频繁爆出两类错误:
wal.FSHLog: Error syncing, request close of WAL:
以及出现错误:
org.apache.hadoop.hbase.client.RetriesExhaustedWithDetailsException: Failed 293 actions: NotServingRegionException: 42 times
以及出现regionserver dead 故障:
Region server exiting java.lang.RuntimeException: HRegionServer Aborted
可能导致该问题的原因及解决方法:
tickTime超时:我们的HBase 并没有设置tickTime,最终hbase与zk的会话最大超时时间并不是zookeeper.session.timeout参数决定的,而是有zk的maxSessionTimeout决定。zk会根据minSessionTimeout与maxSessionTimeout两个参数重新调整最后的超时值,minSessionTimeout=2*tickTime, maxSessionTimeout=20*tickTime。我们的大数据集群,zk的tickTime设置为默认值(2000ms)2秒,因此,最终hbase 与 zk的超时时间就为40秒。经过调整zk的tickTime为6秒,相应的zookeeper.session.timeout为120秒,最终解决regionserver 频繁挂掉的故障。
评注:
关于超时时间,确实很多人遇到过,特别是zookeeper的相关问题。有时候我们需要弄清楚配置之间的关系,才能搞明白,到底是哪个配置起了作用。
3.操作故障
1、创建表格失败,提示信息如下:
org.apache.hadoop.hbase.security.AccessDeniedException: Insufficient permissions for user 'mingtong' (action=create)
可能导致该问题的原因及解决方法:
1. linux最常见的权限问题即当前使用的账户没有建表权限——用权限更高的账户对该用户进行赋权
2.另一个可能就是namespace命名空间的限制:也就是说只有按照ns的格式来创建表格,例如: create 'nc_table:table','info'(注意: nc_table是一个已经存在的nc)
评注:
权限问题是最常见的,但也是新手最常犯的,我们在复制,黏贴,移动文件,安装配置集群的时候,涉及权限的地方,都需要核实下。
2、运行hbase shell 输入 list,等基本语句报错
ERROR: Can't get master address from ZooKeeper; znode data == null
可能原因:
1. 时间不同步, hbase集群所有莫名其妙的问题都有可能是时间不同步导致的!!!一定要注意!!
2. hbase-site.xml里面的hbase.rootdir对应的ip与core-site.xml中的fs.defaultFS中的路径不同,或者是与hdfs文件系统的端口号不一致!
评注:
上面是zookeeper常见错误,上面只是解决办法之一,同时上面其实只是错误之一,或则说是被其它错误引发的,所以我们遇到问题的时候,首先要综合排查错误,然后找到根本错误,然后解决问题。
3. 表名找不见的问题
org.apache.hadoop.hbase.TableNotFoundException: ns_wangyou.simu_out_GuangXi
可能导致该问题的原因及解决方法:
这个问题很明显是查询的hbase数据库里面没有相应的表名导致的。检查输入的表名是否正确, 如果正确的话,去创建相应的表即可。
评注:
上面其实是非常简单的错误,可是还是很多新手,遇到后不知所措。遇到错误,我们最基本的,可以见文知意,翻译出来自然之道是什么原因。
4. 类找不见的问题!(自己写的类找不见的问题!)
出现该问题的情形: hbase和hadoop的hdfs,mapreduce整合使用的时候:
18/04/16 18:25:06 INFO mapreduce.JobSubmitter: Cleaning up the staging area /user/mingtong/.staging/job_1522546194099_223330
Exception in thread "main" java.lang.RuntimeException: java.lang.ClassNotFoundException: Class mastercom.cn.bigdata.util.hadoop.mapred.CombineSmallFileInputFormat not found
经过各种测试,最终将问题定位在:这一行代码:
Configuration conf = HBaseConfiguration.create();
只要你的configuration使用的是hbase的,而且后面mapReduce的job用到这个conf,就会报这个问题!
解决方法:
乖乖的使用 Configuration conf = new Configuration(); 来创建conf吧。但是这种方法创建的conf,不会去加载hbase-site.xml配置文件,hbase-site.xml里面重要的参数需要手动set!!否则就无法正确的连接到Hbase!
由于上面介绍的问题还会引发下面的报错:
org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.hdfs.server.namenode.LeaseExpiredException): No lease on /wangyou/mingtong/mt_wlyh/Data/hbase_bulkload/output/4503/inin (inode 1964063475): File does not exist. Holder DFSClient_NONMAPREDUCE_-769553346_1 does not have any open files.
按照上述方法改进后,该问题就得到解决!
评注:
对于上面也是我们刚接触开发时候,所遇到的,还可以在代码中,设置相关配置项。
5、 与hbase相关jar包找不到的问题
Error:java.lang.ClassNotFoundException:org.apache.hadoop.hbase.client.ConnectionFactory
可能导致该问题的原因及解决方法:
1. 打jar包的时候直接把相应的jar包打进来,这样能够解决问题,但是jar包会有200多M
2. 在执行jar包前执行 export HADOOP_CLASSPATH=$HBASE_HOME/lib/*:classpath,简单有效,但是如果创建hbase连接的操作是在map,reduce里,这种方法依然会报错
3. 在hadoop-env.sh里面,引入hbase的lib目录:操作如下:
exportHADOOP_CLASSPATH=$HBASE_HOME/lib/*:$HADOOP_CLASSPATH,所有的节点都要修改,修改完后要重启集群
4. 将$HBASE_HOME/lib目录下的jar包导入到$HADOOP_HOME/lib目录下,但这样很容易引起jar包冲突,不推荐
评注:
一个问题可能有多个方法,对于找不到类其实方法多种,上面多个方法的核心,都是能够让我们找到相关类。
6、.jdk版本冲突的问题
java.lang.UnsupportedClassVersionError: PR/Sort : Unsupported major.minor version 52.0
可能导致该问题的原因及解决方法:
很简单,使用集群里对应的jdk版本编译就好了。右键项目-->BuildPath -->Configure Build Path --> Java Compiler --->将版本调整成为集群里面对应的版本即可-->apply。重新打jar包,放到集群上跑,问题得到解决
评注:
这个问题,相信大家一看就清楚,熟悉解决办法,遇到的时候,能否熟练操作。
7.执行$ hbase hbck 命令时,出现以下提示:
Invalid maximum heap size: -Xmx4096m
The specified size exceeds the maximum representable size.
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
原因:
jvm设置的内存过大,减小配置文件hbase-env.sh内的设置即可。例如:
export HBASE_HEAPSIZE=1024
评注:
这里涉及到虚拟机的相关知识,也是Java的基础,只有我们有比较好的基础,才能更好的理解Hbase,Hadoop,Spark等相关JVM、内存等配置。
更多参考:
深入理解Java虚拟机_JVM高级特性与最佳实践 第2版
https://www.aboutyun.com/forum.php?mod=viewthread&tid=26485
直接下载
https://pan.baidu.com/s/1EbBWkteyk20kLPJJNGfwjg 提取码: 889n
8、查询hbase的时候报错:
Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.apache.hadoop.hbase.util.ByteStringer
这个空指针异常也是挺恶心的,我已经正常连接到了hbase,而且表名也是正常的...原来是代码不够严谨: 在一些情况下,根据行键进行查询,可能得到的结果集是null,但是我的代码里并没有加上对可能出现的空指针异常进行处理的机制,然后使用for循环遍历这个空的结果集for (Result result : results)
遍历一个空的结果集当然会报错啦!
解决方法:
前面加上一个判断,就解决了!
评注:
上面表面来看其实是缺包,这是我们排查的第一步,如果确定不缺包的视情况下,我们需要进一步的想,是否是错误,引发了这个错误。所以我们要根据错误,并且推断错误是由什么引发的。
9.连接Hbase时, 明明hbase.zookeeper.quorum 和hbase.zookeeper.property.clientPort的设置都是正确的,却总是报错 INFO client.ZooKeeperRegistry: ClusterId read in ZooKeeper is null
首先,这种情况出现在: 使用的configuration 是 new configuration这种方式获得的.这里: 涉及到一个关键的配置:
zookeeper.znode.parent --> 这个值的默认值是/hbase
但是如果集群里面设置的值不是这个的话,就会抛出这个异常!比如说我们的集群:因为使用 new Configuration()获得的configuration对象是不会读取Hbase的配置文件hbase-site.xml文件的.在代码中将该配置按照hbase-site.xml里面配置的添加进来即可conf.set("zookeeper.znode.parent", "/hbase-unsecure");这样,该问题得到解决!
评注:
这个错误跟第四个问题其实是差不多的,如果配置没有生效,我们可以在代码中设置。确保生效。同时配置也是域的,在代码的设置,会替代配置文件的中的设置。
10、使用bulkload入库遇到的另外一个问题!报错信息如下所示:
Exception in thread "main" java.lang.IllegalArgumentException: Can not create a Path from a null string
由报错信息上可以看出来:是在HFileOutputFormat2类里面出现的错误
这个类是使用bulkload方式进行入库的很关键的类
我们接下来一步一步的去定位错误:
抛出来的错误信息是来自于path类的这个方法:
private void checkPathArg( String path ) throws IllegalArgumentException { // disallow construction of a Path from an empty string if ( path == null ) { throw new IllegalArgumentException( "Can not create a Path from a null string"); } if( path.length() == 0 ) { throw new IllegalArgumentException( "Can not create a Path from an empty string"); } }
根据界面上的报错结合一下: 可以得到path是一个null,
那么这个空是从何而来,我们继续看源码
static void configurePartitioner(Job job, List<ImmutableBytesWritable> splitPoints) throws IOException { Configuration conf = job.getConfiguration(); // create the partitions file FileSystem fs = FileSystem.get(conf); Path partitionsPath = new Path(conf.get("hbase.fs.tmp.dir"), "partitions_" + UUID.randomUUID()); fs.makeQualified(partitionsPath); writePartitions(conf, partitionsPath, splitPoints); fs.deleteOnExit(partitionsPath); // configure job to use it job.setPartitionerClass(TotalOrderPartitioner.class); TotalOrderPartitioner.setPartitionFile(conf, partitionsPath); }
分析上面的源码,能够产生null的又和path相关的,显然是这行代码:
Path(conf.get("hbase.fs.tmp.dir"), "partitions_" + UUID.randomUUID());
我们不妨测试一下,在获得conf对象后,打印一下hbase.fs.tmp.dir的值,果然为空!
那么问题已经确认,只需要在代码里面加上这行!
conf.set("hbase.fs.tmp.dir", "/wangyou/mingtong/mt_wlyh/tmp/hbase-staging");
问题便得到解决,入库工作得以正常运行!
评注:
当我们编程过程中,产生问题的时候,有些老铁不知所措,然后就在群里提问,这样其实很少人会回答这类问题,而且即使回答,也是不对口的。对于一些异常错误,直接贴出来,其实能解决的概率是非常小的。我们VIP群中,也有成员遇到异常,都是语音远程解决,这里面产生一个错误,可能会有更多相关错误,一个错误,除了非常简单外,很少能推断出到底是哪里的问题。
11、gz压缩文件损坏导致入库失败的问题
ERROR hdfs.DFSClient: Failed to close inode 16886732
org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.hdfs.server.namenode.LeaseExpiredException): No lease on /hbase_bulkload/output/inin (inode 16886732): File does not exist. Holder DFSClient_NONMAPREDUCE_1351255084_1 does not have any open files.
该问题的场景是在对大量的小的.gz压缩文件进行入库的时候,个别压缩文件损坏导致的,解决的方法就是找到那些出错的.gz文件删除掉.
解决方法:
1. 首先去界面查看相应的job执行的日志,日志里有可能会有出错的.gz文件的id信息,找到将其删除.
2. 将入库的文件夹下面的文件按照文件大小进行排序,一般来说,大小为0KB的都是有问题的.. 将其get下来,查看能否解压,不能正常解压就干掉
3. 可以使用命令: hdfs fsck path -openforwrite
检测某个文件夹下面文件是否正常
评注:
从上面错误,让我想起了另外一个相关的问题。就是我们的代码从一定意义上来说是没有问题的,可是数据一多或则一乱就产生问题,这就是由于数据格式不一致,造成我们程序的异常。所以这个问题,问别人,是不可能一下子推断出来的,只能是我们慢慢查找,debug,才能发现。
4.关闭故障
1、停止HBase时报错
stop-hbase.sh
stopping hbasecat: /tmp/hbase-root-master.pid: No such file or directory
原因:
默认情况下pid文件保存在/tmp目录下,/tmp目录下的文件很容易丢失
解决办法:
在hbase-env.sh中修改pid文件的存放路径:
export HBASE_PID_DIR=/data/hadoop/pids
评注:
pid文件记录了该进程的ID,所以我们不要放到临时目录很容易重启被删除,所以我们尽量保存在非临时目录中。