Hbase应用的一次错误处理

在实现《Hadoop高级编程》一书中第9章的一个例子:将HBase用于图片管理系统中,遇到了一个很让人头疼的问题:FileNotFoundException。虽然异常很简单,可是文件确实存在那了。因而开始了长时间的排错之旅。java

该例子是将一堆小图片文件合成一个大文件,并将各个小文件的位置索引存入HBase中。有一个DatedPhoto类,用于存放时间(long)以及图片(byte[]);还有一个PhotoLocation类,用于存放位置(long)、时间(long)和文件名(String)。位置是小文件在大文件中的字节位置,文件名是合成的大文件名,按序号命名。PhotoLocation类还提供了toBytesfromBytes函数,用于将三种信息字节化后写入HBase以及从HBase中读出索引信息后还原成位置, 时间文件名 信息。其他为写入类,读出类。总体很是简单。编程

写的时候彻底没有问题,文件成功生成,HBase中保存了索引。可是读取的时候,出现问题:一直报FileNotFoundException异常,而路径并未出错并且文件存在。数组

这究竟是怎么一回事呢?由于用的是SequenceFile中的内部类ReaderWriter,而Hadoop 2.2.0的API中并无找到这两个东西,便从源码入手看看是否是这个类的问题。按照执行流程过了一遍,任何问题都没发现。因为错误定位在SequenceFile.Reader的构造函数中getFileStatus上,便从新写了一个类测试FileSystem类的getFileStatus类,发现彻底没有问题,不是这出的错误。函数

PhotoDataReader类是辅助读出数据的类,被PhotoReader类调用。错误就定位在了该类的构造上。查看PhotoDataReader类构造函数,其功能就是接受参数,调用SequenceFile.Reader的构造函数。输出PhotoDataReader接收到的参数:fileString)、userUUID)、confConfiguration),三者都没问题,可是出现了一个很奇怪的现象:oop

执行测试

System.out.println("file:"+ _file + "sadasdsasdssssss");

时,后面的那一串字符串竟然不显示!code

看来问题就出如今_file参数上面。可是无论怎么输出_file的值,的确就是我要的那个文件名的字符串。彷佛这是个根本就不该该出现的问题。而后输出_file的字符串长度,明明只有1个字符的文件名,显示的长度为112!看来问题就在这!索引

问题究竟出如今哪呢?继续向上找,发现参数是PhotoReader传给它的;PhotoReader又经过读取HBase中的索引记录获得后用PhotoLocationfromBytes函数获得…… fromBytes函数?其实现的是将一个包含索引位置时间文件名的128位字符数组分开而后生成三个值。索引位置与时间均为long型,字符数组均为8位,没有问题。可是文件名为字符串,合成字符数组时用的length函数,可是还原时就把除索引位置与时间的16位排除后剩下的112位所有用来生成字符串了!生成字符串用Bytes.bytes()new String均没法生成原长度的字符串。图片

既然知道了缘由,解决也好办了。要么设个长度位,要么用定长字符串,要么干脆在HBase分开存储。看来,有时候报错,问题每每出如今细节上,仔细思考每一处细节,能够减小不少的排错时间。至少此次我花了很多时间。字符串

相关文章
相关标签/搜索