Sqoop安装及MySql数据导入HBase

Sqoop介绍

         Sqoop是一个用来将Hadoop和关系型数据库中的数据相互转移的工具,可以将一个关系型数据库(例如:MySQL ,Oracle ,Postgres等)中的数据导进到Hadoop的HDFS中,也可以将HDFS的数据导进到关系型数据库中。(本文档中使用的是sqoop-1.4.2-cdh4.2.1版本)

为什么要使用sqoop

         因为业务的不断增长导致mysql数据库中数据太多,影响数据查询效率,所以使用sqoop把现有mysql中数据导入到HBase中,使用HBase支撑大数据量的查询。

Sqoop的安装

下载

wget http://archive.cloudera.com/cdh4/cdh/4/sqoop-1.4.2-cdh4.2.1.tar.gz

配置

sqoop-env.sh

cd ${sqoop_home}/conf

复制创建sqoop-env.sh

cp sqoop-env-template.sh       sqoop-env.sh

修改 sqoop-env.sh 加入下面三行,根据集群情况填写

HADOOP_COMMON_HOME=/home/cdh4-test/hadoop-2.0.0-cdh4.2.1

HADOOP_MAPRED_HOME=/home/cdh4-test/hadoop-2.0.0-mr1-cdh4.2.1

HBASE_HOME=/home/cdh4-test/hbase-0.94.2-cdh4.2.1

添加jar包

复制集群中hadoop的core包以及mysql-jdbc包到sqoop-lib目录下。

测试

         进入sqoop-bin目录下执行命令

         ./sqoop-list-tables --connect jdbc:mysql://you_mysql_address:port/you_db_name --username mysqlusername --P

         然后提示输入密码,输入数据库登录密码即可。然后终端显示该数据库下的所有表名称。

         Sqoop安装成功

使用sqoop把mysql中数据导入hbase中

         命令:

         ./sqoop-import --connect jdbc:mysql://xxx.xxx.xxx.xxx/service --table ddt_map_info_copy --hbase-create-table --hbase-table A --column-family info --split-by mapId --username root --P --compression-codec lzo -z

--table ddt_map_info_copy  表示导出gamewaveservice数据库的ddt_map_info_copy表。
--hbase-table A  表示在复制到表A中。
--column-family person 表示在表A中建立列族person。
--hbase-row-key mapId  表示表A的row-key是map_info_copy表的mapId字段。
--hbase-create-table 表示在HBase中建立表。
--username root 表示使用用户root连接Mysql。

-z 表示采用压缩方式

--compression-codec lzo 表示用lzo方式压缩 无效

遇到的问题及结局方案

Q1:需要根据业务逻辑对HBase的row-key做出调整。

A1:有两种解决方案

1)         在数据导入之前对mysql原有表结构做出调整,增加一列存放即将作为Hbase row-key数据。

操作步骤:根据业务逻辑写出sql并update相应表的每一行。

2)         扩展PutTransformer类,自定义导入HBase的put格式。并在执行导入命令时指定该类

操作步骤:

package  com.gamewave.sqoop.extensions.tansformat_row_key;
 
import  java.io.IOException;
import  java.util.Collections;
import  java.util.List;
import  java.util.Map;
import  java.util.TreeMap;
import  org.apache.commons.logging.Log;
import  org.apache.commons.logging.LogFactory;
import  org.apache.hadoop.hbase.client.Put;
import  org.apache.hadoop.hbase.util.Bytes;
import  org.apache.sqoop.hbase.PutTransformer;
 
public  class  DdtMapInfoTransFormat extends  PutTransformer {
 
   public  static  final  Log LOG = LogFactory.getLog(DdtMapInfoTransFormat. class .getName());
   private  Map<String, byte []> serializedFieldNames;
 
   public  DdtMapInfoTransFormat() {
       serializedFieldNames = new  TreeMap<String, byte []>();
   }<br>
   /**
    * Return the serialized bytes for a field name, using the cache if it's
    * already in there.
    */
   private  byte [] getFieldNameBytes(String fieldName) {
       byte [] cachedName = serializedFieldNames.get(fieldName);
       if  ( null  != cachedName) {
           // Cache hit. We're done.
           return  cachedName;
       }
       // Do the serialization and memoize the result.
       byte [] nameBytes = Bytes.toBytes(fieldName);
       serializedFieldNames.put(fieldName, nameBytes);
       return  nameBytes;
   }
 
   @Override
   /** {@inheritDoc} */
   public  List<Put> getPutCommand(Map<String, Object> fields) throws  IOException {
       String rowKeyCol = getRowKeyColumn();
       String colFamily = getColumnFamily();
       byte [] colFamilyBytes = Bytes.toBytes(colFamily);
       Object rowKey = fields.get(rowKeyCol);
       if  ( null  == rowKey) {
           // If the row-key column is null, we don't insert this row.
           LOG.warn( "Could not insert row with null value for row-key column: " + rowKeyCol);
           return  null ;
       }
       Put put = new  Put(Bytes.toBytes(rowKey.toString() + ":custom" ));
       for  (Map.Entry<String, Object> fieldEntry : fields.entrySet()) {
           String colName = fieldEntry.getKey();
           if  (!colName.equals(rowKeyCol)) {
               // This is a regular field, not the row key.
               // Add it if it's not null.
               Object val = fieldEntry.getValue();
               if  ( null  != val) {
                   put.add(colFamilyBytes, getFieldNameBytes(colName),Bytes.toBytes(val.toString()));
               }
           }
       }
       return  Collections.singletonList(put);
   }
}

1、扩展PutTransformer类

上面代码做出示例,红色字体为修改行,蓝底字体为添加内容。

2、包并放进sqoop-lib目录下,执行命令

./sqoop-import -D sqoop.hbase.insert.put.transformer.class=com.gamewave.sqoop.extensions.tansformat_row_key.DdtMapInfoTransFormat –connect jdbc:mysql://xxx.xxx.xxx.xxx/service --table ddt_map_info_copy --hbase-create-table --hbase-table ddt_map_info_copy --column-family info --split-by mapId --username root --P --compression-codec lzo

命令中-D为指定属性名称 参数值为键值对

sqoop.hbase.insert.put.transformer.class属性值为指定格式化类名称

3、验证

进入hbase shell

可以查看得到rowkey后缀均为:custom,修改成功

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值