我正在处理sqoop增量作业,将数据从mysql加载到hdfs。以下是以下方案。
场景1: 下面是在mysql中的示例表中插入的记录。
select * from sample;
+-----+--------+--------+---------------------+
| id | policy | salary | updated_time |
+-----+--------+--------+---------------------+
| 100 | 1 | 4567 | 2017-08-02 01:58:28 |
| 200 | 2 | 3456 | 2017-08-02 01:58:29 |
| 300 | 3 | 2345 | 2017-08-02 01:58:29 |
+-----+--------+--------+---------------------+
下面是mysql中的示例表的表结构:
create table sample (id int not null primary key, policy int, salary int, updated_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
我试图通过创建一个sqoop作业将其导入hdfs,如下所示
sqoop job --create incjob -- import --connect jdbc:mysql://localhost/retail_db --username root -P --table sample --merge-key id --split-by id --target-dir /user/cloudera --append --incremental lastmodified --check-column updated_time -m 1
执行sqoop job后,下面是hdfs中的输出记录。
$ hadoop fs -cat /user/cloudera/par*
100,1,4567,2017-08-02 01:58:28.0
200,2,3456,2017-08-02 01:58:29.0
300,3,2345,2017-08-02 01:58:29.0
场景2:插入少量新记录并更新样本表中的现有记录。以下是样本表。
select * from sample;
+-----+--------+--------+---------------------+
| id | policy | salary | updated_time |
+-----+--------+--------+---------------------+
| 100 | 6 | 5638 | 2017-08-02 02:01:09 |
| 200 | 2 | 7654 | 2017-08-02 02:01:10 |
| 300 | 3 | 2345 | 2017-08-02 01:58:29 |
| 400 | 4 | 1234 | 2017-08-02 02:01:17 |
| 500 | 5 | 6543 | 2017-08-02 02:01:18 |
+-----+--------+--------+---------------------+
在下面运行相同的sqoop作业之后是hdfs中的记录。
hadoop fs -cat /user/cloudera/par*
100,1,4567,2017-08-02 01:58:28.0
200,2,3456,2017-08-02 01:58:29.0
300,3,2345,2017-08-02 01:58:29.0
100,6,5638,2017-08-02 02:01:09.0
200,2,7654,2017-08-02 02:01:10.0
400,4,1234,2017-08-02 02:01:17.0
500,5,6543,2017-08-02 02:01:18.0
这里将mysql中更新的记录作为新记录插入到hdfs中,而不是更新hdfs中的现有记录。我在我的sqoop job conf中使用了--merge-key和--append。可以帮助我解决这个问题。
答案 0 :(得分:1)
您正在使用--merge-key
--append
和lastmodified
。这是不对的。
--incremental append
模式将数据附加到HDFS中的现有数据集。您应该在导入表时指定追加模式,其中不断添加新行并增加行ID值
--incremental lastmodified
模式 - 您可以在更新源表的行时使用此项,并且每次更新都会将最后修改的列的值设置为当前时间戳。
--merge-key
- 合并工具运行一个MapReduce作业,该作业将两个目录作为输入:一个较新的数据集,一个较旧的数据集。这些分别用--new-data和--onto指定。 MapReduce作业的输出将放在--target-dir
指定的HDFS目录中。
--last-value
(value)指定上一次导入的检查列的最大值。如果从命令行运行sqoop,没有Sqoop作业,则必须添加--last-value
参数
在您的情况下,有一些新记录,一些记录也会更新,因此您需要使用lastmodified
模式。
您的Sqoop命令将是:
sqoop job --create incjob -- import --connect jdbc:mysql://localhost/retail_db --username root -P --table sample --merge-key id --target-dir /user/cloudera --incremental lastmodified --check-column updated_time -m 1
由于您只指定了一个映射器,因此不需要--split-by
。
答案 1 :(得分:0)