以编程方式从CSV文件格式创建HBase表并加载其内容

时间:2016-11-15 21:27:59

标签: csv hadoop mapreduce cloudera bigdata

您好我是hadoop的新手,我正在尝试使用MapReduce将csv表导入Hbase。

我正在使用Cloudera 5.9

我想首先使用MapReduce以编程方式从CSV表格式创建HBase表(因为我使用由大量列组成的csv文件)然后将CSV文件的内容加载到HBase表

请任何人指导我或告诉我如何解决这个问题

2 个答案:

答案 0 :(得分:1)

HBase表可以用语法创建。有关使用Java API的参考,请参阅https://www.tutorialspoint.com/hbase/hbase_create_table.htm

同样在HBase中创建表时,您不必创建只需要创建列族的所有列(将列族视为一组列并存储在一起.HBase是柱状的)。作为加载内容(PUT)的一部分,可以创建/使用列并插入/更新数据。对于Java API,请参阅 http://hbase.apache.org/apidocs/

答案 1 :(得分:0)

为了将数据上传到群集数据库(HBase),我使用了以下两种方法:

  1. CSV - > HDFS 我经常有CSV格式的数据。事实证明,自动化将CSV文件转换为Hive / Impala数据库表的过程非常棘手。以下是必要的步骤:
  2. 一个。阅读csv文件并进行必要的转换。分析csv文件中数据的列名非常重要,但是,必须创建一个不包含标题行的文件副本。

    湾然后我在集群的名称节点机器上创建一个文件夹(仍然不是HDFS)

    mkdir -p input

    ℃。并使用支持SFTP协议的JSch java库将我的csv文件(没有标题行)复制到上面创建的文件夹中:

    public static void copyFileToLinux(String dest, String user, String password, String file) throws JSchException, SftpException,     FileNotFoundException {
     String destination = "/home/"+user+"/"+dest;
     jsch = new JSch();
     session = jsch.getSession(user,"host",22);
     session.setPassword(password);
     session.setConfig("StrictHostKeyChecking", "no");
     session.connect();
     ChannelSftp channel = null;
     channel = (ChannelSftp)session.openChannel("sftp");
     channel.connect();
     File localFile = new File(file);
     channel.cd(destination);
     channel.put(new FileInputStream(localFile),localFile.getName());
     channel.disconnect();
     session.disconnect();
    }
    

    这是JSCH的依赖:

    <dependency>
     <groupId>com.jcraft</groupId>
     <artifactId>jsch</artifactId>
     <version>0.1.53</version>
    </dependency>
    

    d。当csv文件在linux主机上时,它可以通过以下命令轻松地放入HDFS(我首先删除一个具有相同名称的潜在文件):

    hdfs dfs -rm input/file.csv
    hdfs dfs -mkdir -p input
    hdfs dfs -put input/file.csv input
    

    即一旦文件在HDFS中,我就将权限更改为777(在项目符号g下的说明)

    hdfs dfs -chmod -R 777 /user/vKey/input
    

    F。现在一切都已准备好创建表,可以使用以下bash脚本完成:

    #!/bin/bash
    path=$1
    table_name=$2
    impala-shell -i host -q "DROP TABLE IF EXISTS $2;"
    impala-shell -i host -q "CREATE EXTERNAL TABLE $2 (c1 INTEGER,c2 STRING,c3 INTEGER,c4 INTEGER,c5 STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY ';' LINES TERMINATED BY '\n' STORED AS TEXTFILE LOCATION '/user/vKey/input';"
    

    我以编程方式创建此CreateTable.sh脚本。脚本的列名取自步骤a)。请记住,上传的数据没有列名。对于每一列,了解其类型很重要,这就是为什么我编写了一些代码来分析csv文件的前n行并猜测列中是否有整数,双精度,日期或字符串值。 然后将脚本复制到预先创建的脚本文件夹中:

    mkdir -p scripts
    

    执行脚本:

    sh scripts/CreateTable.sh input/file.csv schema.table
    

    为了执行此脚本,impala用户必须拥有csv文件的必要权限。这就是为什么步骤e)很重要。

    1. JDBC - &gt; HDFS 如果直接从数据库读取数据,则将数据复制到HDFS表要容易得多。因此可以使用工具sqoop。
    2. 在第一步中创建了一个镶木地板文件:

      sqoop import --connect jdbc:oracle:thin:@//host:1521/service --username user -P --table schema.table --target-dir hdfs:////data/schema/table -m 1 --as-parquetfile
      

      然后可以从镶木地板文件中创建表格:

      #!/bin/bash
      
      parquet_path=$1
      table_name=$2
      schema=$3
      
      hadoop fs -setfacl -R -m group:hive:rwx $parquet_path
      
      par_file_list=`hadoop fs -ls $parquet_path | tail -n 1`
      par_file=${par_file_list##* }
      impala-shell -i host -q "DROP TABLE IF EXISTS $schema.$table_name;"
      
      prefix="hdfs://"
      parquet_without_hdfs=${parquet_path#$prefix}
      
      impala-shell -i host -q "CREATE EXTERNAL TABLE $schema.$table_name LIKE PARQUET '$par_file'
      STORED AS PARQUET
      LOCATION '$parquet_path';"
      

      缺点是您通常无法像使用csv文件那样操纵/转换数据,但您更倾向于从数据库中获取数据。可以在sqoop语句中添加where子句,但不能使用特定的select语句。