CDH自带两个版本sqoop组件
这里选择1.4.6版本也就是sqoop1,1.99.5版本是sqoop2,是半成品,不支持关系型DB到Hive跟Hbase,故不推荐使用
sqoop list-databases --connect jdbc:mysql://192.168.20.160/angel --username root –P111111
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正常。
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,因此导入的是普通表而不能为外部表。
以下简要列举了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方式)。
举个栗子,有一个订单表,里面每个订单有一个唯一标识自增列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
此方式要求原有表中有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 任务上去跑,避免数据倾斜。