【问题标题】:Sqoop incremental load lastmodified not working on updated recordsSqoop 增量加载 lastmodified 不适用于更新的记录
【发布时间】:2017-08-03 21:40:40
【问题描述】:

我正在做一个 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作业后下面是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 作业 conf 中同时使用了 --merge-key 和 --append。能否帮助我解决此问题。

【问题讨论】:

    标签: mysql hadoop sqoop


    【解决方案1】:

    您正在同时使用 --merge-key --appendlastmodified。这也不对。

    • --incremental append 模式 将数据附加到 HDFS 中的现有数据集。您应该在导入表时指定附加模式,在该表中,随着行 ID 值的增加,新行不断添加

    • --incremental lastmodified 模式 - 当源表的行可能会更新时,您应该使用此模式,并且每次此类更新都会将 last-modified 列的值设置为当前时间戳。

      李>
    • --merge-key - 合并工具运行 MapReduce 作业,该作业将两个目录作为输入:一个较新的数据集和一个较旧的数据集。这些分别用 --new-data 和 --onto 指定。 MapReduce 作业的输出将放在 HDFS 中--target-dir 指定的目录中。

    • --last-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

    【讨论】:

    • 对于 sqoop 作业,不建议提及 last-value,因为每次执行时都会更新它。它从 sqoop 元存储中获取最后一个值。
    • 理想情况下,您应该以这种方式指定--last-value,以确保您只导入新的或更新的数据。这是通过将增量导入创建为保存的作业来自动处理的,这是执行循环增量导入的首选机制。
    • True.. 但这对我不起作用。我尝试了很多方法,但无法通过 sqoop 增量更新 hdfs 中的现有记录
    • 您正在同时使用--merge-key--append。请删除--append
    • --append - 将数据附加到 HDFS 中的现有数据集,因此您不会得到想要的结果。
    【解决方案2】:
    1. 我了解到,只要源 MySQL 表发生变化,您就会尝试更新 HDFS 中的现有记录。
    2. 仅当您不想更新源表中已更改的记录时才应使用 --append。
    3. 另一种方法是您可以尝试将单独目录中的更改记录迁移为 delta_records,然后将其与 base_records 连接。请参阅 hortonworks link 了解更多信息

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多