使用HBase importtsv工具从Java代码批量加载数据

时间:2016-05-31 14:21:08

标签: java eclipse hadoop hbase

我正在尝试使用Apache HBase附带的importtsvLoadIncrementalHFiles工具将csv文件批量加载到hbase。

我们可以在以下页面找到这些教程:clouderaapache

我正在使用Apache hadoop和hbase。

两个来源都解释了如何通过命令提示符使用这些工具。但是,我希望从Java代码中完成此操作。我知道我可以编写自定义地图缩小,如cloudera页面上所述。但是我想知道我是否可以直接在我的Java代码中使用与这些工具相对应的类。

我的群集在虚拟分布式模式下在VMWare内的Ubuntu VM上运行,而我的Java代码在Windows主机上运行。通过命令提示符在运行集群的同一台计算机上执行此操作时,我们运行以下命令:

$HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase classpath` ${HADOOP_HOME}/bin/hadoop jar ${HBASE_HOME}/hbase-server-1.2.1.jar importtsv -Dimporttsv.columns=HBASE_ROW_KEY,d:c1,d:c2 -Dimporttsv.bulk.output=hdfs://192.168.23.128:9000/bulkloadoutputdir datatsv  hdfs://192.168.23.128:9000/bulkloadinputdir/

如上所示,我们设置HADOOP_CLASSPATH。就我而言,我想我必须将所有xyz-site.xml hadoop配置文件复制到我的Windows机器上,并将包含它的目录设置为HADOOP_CLASSPATH环境变量。所以我将粘贴的core-site.xml, hbase-site.xml, hdfs-site.xml复制到我的Windows机器上,将目录设置为Windows环境变量HADOOP_CLASSPATH。除此之外,我还将所有必需的JAR添加到eclipse项目的构建路径中。

但是在运行项目后我遇到了以下错误:

Exception in thread "main" org.apache.hadoop.hbase.client.RetriesExhaustedException: Can't get the locations
    at org.apache.hadoop.hbase.client.RpcRetryingCallerWithReadReplicas.getRegionLocations(RpcRetryingCallerWithReadReplicas.java:319)
    at org.apache.hadoop.hbase.client.ScannerCallableWithReplicas.call(ScannerCallableWithReplicas.java:156)
    at org.apache.hadoop.hbase.client.ScannerCallableWithReplicas.call(ScannerCallableWithReplicas.java:60)
    at org.apache.hadoop.hbase.client.RpcRetryingCaller.callWithoutRetries(RpcRetryingCaller.java:200)
    at org.apache.hadoop.hbase.client.ClientScanner.call(ClientScanner.java:326)
    at org.apache.hadoop.hbase.client.ClientScanner.nextScanner(ClientScanner.java:301)
    at org.apache.hadoop.hbase.client.ClientScanner.initializeScannerInConstruction(ClientScanner.java:166)
    at org.apache.hadoop.hbase.client.ClientScanner.<init>(ClientScanner.java:161)
    at org.apache.hadoop.hbase.client.HTable.getScanner(HTable.java:794)
    at org.apache.hadoop.hbase.MetaTableAccessor.fullScan(MetaTableAccessor.java:602)
    at org.apache.hadoop.hbase.MetaTableAccessor.tableExists(MetaTableAccessor.java:366)
    at org.apache.hadoop.hbase.client.HBaseAdmin.tableExists(HBaseAdmin.java:403)
    at org.apache.hadoop.hbase.mapreduce.ImportTsv.createSubmittableJob(ImportTsv.java:493)
    at org.apache.hadoop.hbase.mapreduce.ImportTsv.run(ImportTsv.java:737)
    at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70)
    at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:84)
    at org.apache.hadoop.hbase.mapreduce.ImportTsv.main(ImportTsv.java:747)
    at HBaseImportTsvBulkLoader.createStoreFilesFromHdfsFiles(HBaseImportTsvBulkLoader.java:36)
    at HBaseImportTsvBulkLoader.main(HBaseImportTsvBulkLoader.java:17)

所以某种程度上importtsv仍然无法找到群集的位置。

这就是我的基本代码:

1    import java.io.IOException;
2    
3    import org.apache.hadoop.conf.Configuration;
4    import org.apache.hadoop.hbase.mapreduce.ImportTsv;
5    import org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles;
6    import org.apache.hadoop.conf.Configuration;
7    import org.apache.hadoop.fs.FileStatus;
8    import org.apache.hadoop.fs.FileSystem;
9    import org.apache.hadoop.fs.Path;
10    
11    public class HBaseImportTsvBulkLoader {
12      static Configuration config;
13        
14        public static void main(String[] args) throws Exception {
15          config = new Configuration();
16              copyFileToHDFS();
17          createStoreFilesFromHdfsFiles();
18          loadStoreFilesToTable();
19      }
20        
21        private static void copyFileToHDFS() throws IOException
22        {
23          config.set("fs.defaultFS","hdfs://192.168.23.128:9000"); //192.168.23.128       
24          FileSystem hdfs = FileSystem.get(config);
25          Path localfsSourceDir = new Path("D:\\delete\\bulkloadinputfile1");
26          Path hdfsTargetDir = new Path (hdfs.getWorkingDirectory() + "/");       
27          hdfs.copyFromLocalFile(localfsSourceDir, hdfsTargetDir);
28        }
29        
30        private static void createStoreFilesFromHdfsFiles() throws Exception
31        {
32          String[] _args = {"-Dimporttsv.bulk.output=hdfs://192.168.23.128:9000/bulkloadoutputdir",
33                  "-Dimporttsv.columns=HBASE_ROW_KEY,d:c1,d:c2",
34                  "datatsv",
35                  "hdfs://192.168.23.128:9000/bulkloadinputdir/"};    
36          ImportTsv.main(_args);                                 //**throws exception**
37          
38        }
39        
40        private static void loadStoreFilesToTable() throws Exception
41        {
42          String[] _args = {"hdfs://192.168.23.128:9000/hbasebulkloadoutputdir","datatsv"};
43          LoadIncrementalHFiles.main(_args);
44        }
45    }
46    

问题

  1. 需要所有xyz-site.xml个fiels?

  2. 我应该以什么方式指定HADOOP_CLASSPATH

  3. 我是否可以将所需的参数传递给main()的{​​{1}}方法,例如下面ImportTsv

    -Dhbase.rootdir
  4. 我可以使用String[] _args = {"-Dimporttsv.bulk.output=hdfs://192.168.23.128:9000/bulkloadoutputdir", "-Dimporttsv.columns=HBASE_ROW_KEY,d:c1,d:c2", "-Dhbase.rootdir=hdfs://192.168.23.128:9000/hbase", "datatsv", "hdfs://192.168.23.128:9000/bulkloadinputdir/"}; 设置相同的内容吗?

0 个答案:

没有答案