使用ImportTsv在hbase中插入数据时出现问题

时间:2013-10-15 11:57:04

标签: hadoop hbase hive

我试图使用以下命令在hbase中插入数据:

hbase org.apache.hadoop.hbase.mapreduce.ImportTsv -Dimporttsv.columns=HBASE_ROW_KEY,f:pageviews,f:visit -Dimporttsv.separator=\001 -Dimporttsv.bulk.output=output modelvar /000000.gz


hbase org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles modelvar output

其中modelvar是最终的hbase表,其中假设存储数据。 output是存储Hfiles的HDFS路径。现在问题是我试图插入的数据是hive的输出。因此,默认分隔符为\001,我无法更改。因此,我将-Dimporttsv.separator=值保持为\001。但是,我们不能将多个字符保留为分隔符。那么,我如何在hbase

写的hive中插入数据

2 个答案:

答案 0 :(得分:1)

IMO,你不能在hadoop配置中使用byte。

但是我们可以注意到org.apache.hadoop.hbase.mapreduce.ImportTsv.SEPARATOR_CONF_KEY定义的属性'importtsv.separator'是org.apache.hadoop.hbase.mapreduce.ImportTsv中的Base64编码:245

public static Job createSubmittableJob(Configuration conf, String[] args)
  throws IOException, ClassNotFoundException {

    // Support non-XML supported characters
    // by re-encoding the passed separator as a Base64 string.
    String actualSeparator = conf.get(SEPARATOR_CONF_KEY);
    if (actualSeparator != null) {
      conf.set(SEPARATOR_CONF_KEY,
               Base64.encodeBytes(actualSeparator.getBytes()));
    }
    ...
}

在org.apache.hadoop.hbase.mapreduce.ImportTsv中解码:92

protected void doSetup(Context context) {
    Configuration conf = context.getConfiguration();

    // If a custom separator has been used,
    // decode it back from Base64 encoding.
    separator = conf.get(ImportTsv.SEPARATOR_CONF_KEY);
    if (separator == null) {
      separator = ImportTsv.DEFAULT_SEPARATOR;
    } else {
      separator = new String(Base64.decode(separator));
    }
    ...
}

最后检查是org.apache.hadoop.hbase.mapreduce.ImportTsv中的单个字节:97

public TsvParser(String columnsSpecification, String separatorStr) {
      // Configure separator
      byte[] separator = Bytes.toBytes(separatorStr);
      Preconditions.checkArgument(separator.length == 1,
        "TsvParser only supports single-byte separators");
      separatorByte = separator[0];
      ...
}

作为一个解决方案,我建议你重新声明一个main方法,它在执行之前修改配置的属性。

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.mapreduce.ImportTsv;

public class ImportTsvByteSeparator extends ImportTsv
{
    /**
     * Main entry point.
     *
     * @param args  The command line parameters.
     * @throws Exception When running the job fails.
     */
    public static void main(String[] args) throws Exception {

      // We just have to modify the configuration
      Configuration conf = HBaseConfiguration.create();
      int byteSeparator = conf.getInt("importtsv.byte_separator", 001);
      String separator = Character.toString((char) byteSeparator);
      conf.set("importtsv.separator", separator);

      // Now we call ImportTsv main's method
      ImportTsv.main(args);
    }
}

由于属性的可见性,我认为我们不能覆盖进程内的某些方法(如createSubmittableJob())。

答案 1 :(得分:1)

最后找到答案,将分隔符替换为$(echo -e "\002")。这适用于所有shell命令。