在查看bulk load的源碼瞭解到,其默認的分隔符爲\t,也就是說如果數據是tab鍵分割的,就不需要指定分隔符了,如果需要換成其它分割符,在執行時加上-Dimporttsv.separator=",",則變成了以","分割。
前兩天,無意間使用bulk load導入數據,導入的數據是以“\t”分割的,我在命令中指定了-Dimporttsv.separator="\t",怪事就出現了,報出異常:
java.lang.IllegalArgumentException: TsvParser only supports single-byte separators
at com.google.common.base.Preconditions.checkArgument(Preconditions.java:88)
at org.apache.hadoop.hbase.mapreduce.ImportTsv$TsvParser.<init>(ImportTsv.java:88)
at org.apache.hadoop.hbase.mapreduce.ImportTsv$TsvImporter.setup(ImportTsv.java:218)
at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:142)
at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:621)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:305)
at org.apache.hadoop.mapred.Child.main(Child.java:170)
跟蹤了一下源碼,發現是類TsvParser的構造函數中對分隔符的長度進行了驗證。
public TsvParser(String columnsSpecification, String separatorStr) {
// Configure separator
byte[] separator = Bytes.toBytes(separatorStr);
Preconditions.checkArgument(separator.length == 1,//如果separator.length == 1爲false的話,將會報出上面的異常
"TsvParser only supports single-byte separators");
separatorByte = separator[0];
。。。。。
}
這樣看來是“\t”轉化爲byte數組後的長度不是1導致的,跟蹤看到“\t”作爲參數傳進來後,java轉義成“\\t”,這樣造成了長度爲2的情形,所以報出了以上異常信息。
所以在使用hbase的bulk load時,如果數據是"\t"分割的,建議不要加參數-Dimporttsv.separator,其一hbase默認就是製表符,其二會出現上面的異常。
現在比較理解爲什麼bulk load不用逗號、分號或者其他的作爲默認的分隔符了,或許這就是其中的緣由吧!