CDH中Sqoop的使用心得

Sqoop服务添加

Sqoop版本选择

CDH自带两个版本sqoop组件

这里选择1.4.6版本也就是sqoop1,1.99.5版本是sqoop2,是半成品,不支持关系型DB到Hive跟Hbase,故不推荐使用

Sqoop导入mySql数据到Hive操作

1、测试MySQL连接

sqoop list-databases --connect jdbc:mysql://192.168.20.160/angel --username root –P111111

2、检验SQL语句

sqoop eval --connect jdbc:mysql://192.168.20.160/angel --username root--password 111111/ 
--query "SELECT xi.*, jing.name,wang.latitude,wang.longitude / 
    FROM xi ,jing, wang / 
WHERE xi.id=jing.foreignId AND wang.id=xi.id AND xi.date>='2015-09-01' AND xi.date<='2015-10-01'"

以上Sqoop语句执行过后,可以确认Sqoop运行正常,Sqoop连接MySQL正常。

3、导入数据

qoop eval --connect jdbc:mysql://192.168.20.160/angel --username root--password 111111 / 
--query "SELECT xi.*, jing.name,wang.latitude,wang.longitude / 
    FROM xi ,jing, wang / 
    WHERE xi.id=jing.foreignId AND wang.id=xi.id AND xi.date>='2015-09-01' AND xi.date<='2015-10-01' / 
    AND /$CONDITIONS" / 
--split-by date --hive-import -m 5 / 
--target-dir /user/hive/warehouse/anqi_wang / 
--hive-table anqi_wang

注意:
由于使用Sqoop从MySQL导入数据到Hive需要指定target-dir,因此导入的是普通表而不能为外部表。

4、执行过程

以下简要列举了Sqoop的执行过程:

BoundingValsQuery: SELECT MIN(date), MAX(date) FROM (SELECT xi.*, jing.name,wang.latitude,wang.longitude FROM xi ,jing, wang WHERE xi.id=jing.foreignId AND wang.id=xi.id AND xi.date>='2015-09-01' AND xi.date<='2015-10-01' AND  (1 = 1) ) AS t1
15/10/13 13:11:47 INFO mapreduce.JobSubmitter: number of splits:5
15/10/12 13:40:28 INFO mapreduce.Job:  map 0% reduce 0% 
15/10/12 13:40:39 INFO mapreduce.Job:  map 20% reduce 0% 
15/10/12 13:40:40 INFO mapreduce.Job:  map 40% reduce 0% 
15/10/12 13:40:47 INFO mapreduce.Job:  map 60% reduce 0% 
15/10/12 13:40:48 INFO mapreduce.Job:  map 80% reduce 0% 
15/10/12 13:40:52 INFO mapreduce.Job:  map 100% reduce 0%

可以看出,–split-by设置后,job按设置值切分,切分个数为-m设置值(-m 5 不设置的话默认job切分数是4)。经检验,此种较复杂的SQL语句,Sqoop支持得很好。

可以看出MySQL的decimal类型变成了Hive中的double类型。此时需要在导入时通过–map-column-hive 作出映射关系指定,如下所示:

sqoop import / 
--connect jdbc:mysql://192.168.184.12/angel --username anqi --password anqi_mima / 
--query "SELECT * FROM xi WHERE date>='2015-09-16' AND date<='2015-10-01' / 
    AND /$CONDITIONS" / 
--split-by date --hive-import -m 5 / 
--map-column-hive cost="DECIMAL",date="DATE" / 
--target-dir /user/hive/warehouse/xi / 
--hive-table xi

以上命令可以执行成功,然而Hive列类型设置为DECIMAL时,从Mysql[decimal(12,2)]–>Hive[decimal]会导致导入后小数丢失。

增量导入

事实上,在生产环境中,系统可能会定期从与业务相关的关系型数据库向Hadoop导入数据,导入数仓后进行后续离线分析。故我们此时不可能再将所有数据重新导一遍,此时我们就需要增量数据导入这一模式了。

增量数据导入分两种,一是基于递增列的增量数据导入(Append方式)。二是基于时间列的增量数据导入(LastModified方式)。

1、Append方式

举个栗子,有一个订单表,里面每个订单有一个唯一标识自增列ID,在关系型数据库中以主键形式存在。之前已经将id在0~5201314之间的编号的订单导入到Hadoop中了(这里为HDFS),现在一段时间后我们需要将近期产生的新的订单数据导入Hadoop中(这里为HDFS),以供后续数仓进行分析。此时我们只需要指定–incremental 参数为append,–last-value参数为5201314即可。表示只从id大于5201314后开始导入。

Append方式的全量数据导入

 sqoop import /
   --connect jdbc:mysql://192.168.20.160:3306/testdb /
   --username root /
   --password 123456 /
   --query “select order_id, name from order_table where /$CONDITIONS” /
   --target-dir /user/root/orders_all / 
   --split-by order_id /
   -m 6  /
   --incremental append /
   --check-column order_id /
   --last-value 5201314

重要参数说明:

2、lastModify方式

此方式要求原有表中有time字段,它能指定一个时间戳,让Sqoop把该时间戳之后的数据导入至Hadoop(这里为HDFS)。因为后续订单可能状态会变化,变化后time字段时间戳也会变化,此时Sqoop依然会将相同状态更改后的订单导入HDFS,当然我们可以指定merge-key参数为orser_id,表示将后续新的记录与原有记录合并。

将时间列大于等于阈值的数据增量导入HDFS

sqoop import /
  --connect jdbc:mysql://192.168. 20.160:3306/testdb /
  --username root /
  --password transwarp /
  --query “select order_id, name from order_table where /$CONDITIONS” /
  --target-dir /user/root/order_all / 
  --split-by id /
  -m 4  /
  --incremental lastmodified /
  --merge-key order_id /
  --check-column time /
  # remember this date !!!
  --last-value “2014-11-09 21:00:00” 

重要参数说明:

并发导入参数设置

我们知道通过 -m 参数能够设置导入数据的 map 任务数量,即指定了 -m 即表示导入方式为并发导入,这时我们必须同时指定 - -split-by 参数指定根据哪一列来实现哈希分片,从而将不同分片的数据分发到不同 map 任务上去跑,避免数据倾斜。

猜你喜欢

转载自blog.csdn.net/qq_42694052/article/details/89957840