Sqoop增量导入

时间:2014-04-09 17:06:55

标签: sqoop

需要有关Sqoop增量进口的建议。 假设我在第1天有一个策略1的客户,我在第1天将这些记录导入HDFS,我在Part Files中看到它们。
在第2天,同一客户添加了策略2,在增量导入sqoop运行之后,我们是否只获得部分文件中的新记录? 在这种情况下,如何使用Sqoop获取旧的和增量的附加/最后修改记录?

7 个答案:

答案 0 :(得分:21)

考虑一个包含3条记录的表,您已使用sqoop

将其导入hdfs
SELECT REPLACE(col,'/','')

现在您在表格中有其他记录,但现有记录没有更新

+------+------------+----------+------+------------+
| sid  | city       | state    | rank | rDate      |
+------+------------+----------+------+------------+
|  101 | Chicago    | Illinois |    1 | 2014-01-25 |
|  101 | Schaumburg | Illinois |    3 | 2014-01-25 |
|  101 | Columbus   | Ohio     |    7 | 2014-01-25 |
+------+------------+----------+------+------------+

sqoop import --connect jdbc:mysql://localhost:3306/ydb --table yloc --username root -P

在这里,您应该使用+------+------------+----------+------+------------+ | sid | city | state | rank | rDate | +------+------------+----------+------+------------+ | 101 | Chicago | Illinois | 1 | 2014-01-25 | | 101 | Schaumburg | Illinois | 3 | 2014-01-25 | | 101 | Columbus | Ohio | 7 | 2014-01-25 | | 103 | Charlotte | NC | 9 | 2013-04-22 | | 103 | Greenville | SC | 9 | 2013-05-12 | | 103 | Atlanta | GA | 11 | 2013-08-21 | +------+------------+----------+------+------------+ --incremental append,它指定在确定要导入的行时要检查的列。

--check-column

上面的代码将根据最后一个值插入所有新行。

现在我们可以想到行中有更新的第二种情况

sqoop import --connect jdbc:mysql://localhost:3306/ydb --table yloc --username root -P --check-column rank --incremental append --last-value 7

这里我们使用增量lastmodified,我们将根据日期获取所有更新的行。

+------+------------+----------+------+------------+
| sid  | city       | state    | rank | rDate      |
+------+------------+----------+------+------------+
|  101 | Chicago    | Illinois |    1 | 2015-01-01 |
|  101 | Schaumburg | Illinois |    3 | 2014-01-25 |
|  101 | Columbus   | Ohio     |    7 | 2014-01-25 |
|  103 | Charlotte  | NC       |    9 | 2013-04-22 |
|  103 | Greenville | SC       |    9 | 2013-05-12 |
|  103 | Atlanta    | GA       |   11 | 2013-08-21 |
|  104 | Dallas     | Texas    |    4 | 2015-02-02 |
|  105 | Phoenix    | Arzona   |   17 | 2015-02-24 |
+------+------------+----------+------+------------+

答案 1 :(得分:3)

在回答第一个问题时,这取决于您如何运行import语句。如果您使用--incremental append选项,则会指定--check-column--last-value个参数。这些将准确地指示拉出哪些记录,它们将简单地附加到您的表格中。 例如:您可以为DATE参数和非常早的日期指定--check-column类型列(例如' 1900-01-01'或 Day1 在你的情况下)--last-value这将继续将源表中的所有内容(创建重复的行)附加到目的地。在这种情况下,创建的新零件文件将包含新旧记录。您还可以使用增加的ID列并继续输入小ID,这将具有相同的效果。但是,如果--last-value Day2 ,则会有其他部分文件包含仅新记录。我不确定你是否想知道你是否会丢失旧记录(以防万一),但事实并非如此。

last-modified的{​​{1}}参数只有在将来返回并更新现有行的某些属性时才有用。在这种情况下,它会将表中的旧数据(并添加新内容)替换为源表中现在的行的更新版本。希望这有帮助!

哦,所有这些都是基于The Sqoop用户指南第7.2.7节https://sqoop.apache.org/docs/1.4.2/SqoopUserGuide.html#_incremental_imports

和Apache Sqoop Cookbook的第3章(该章实际上太棒了!)

答案 2 :(得分:1)

让我们在这里举例说明,您的客户表包含两列cust_id和策略,custid也是您的主键,您只想向前面插入数据100

方案1: - 根据cust_id字段附加新数据

阶段1: -

最近在我们想要在HDFS中导入的客户表中插入了3条记录

| custid | Policy |
| 101 | 1 |
| 102 | 2 | 
| 103 | 3 |

这是

的sqoop命令
sqoop import \ 
--connect jdbc:mysql://localhost:3306/db \ 
--username root -P \ 
--table customer \ 
--target-dir /user/hive/warehouse/<your db>/<table> \
--append \
--check-column custid \
--incremental append \
--last-value 100

阶段2: - 最近在客户表中插入了4条记录,我们要在HDFS中导入

| custid | Policy |
| 104 | 4 |
| 105 | 5 | 
| 106 | 6 | 
| 107 | 7 | 

这是

的sqoop命令
sqoop import \ 
--connect jdbc:mysql://localhost:3306/db \
--username root -P \ 
--table customer \ 
--target-dir /user/hive/warehouse/<your db>/<table> \ 
--append \
--check-column custid \
--incremental append \
--last-value 103

所以这四个属性我们将需要cosider来插入新记录

--append \
--check-column <primary key> \
--incremental append \
--last-value <Last Value of primary key which sqoop job has inserted in last run>

方案2: - 附加新数据+根据cust_id字段更新现有数据

以下1个新记录,其中已插入cust id 108,并且最近在我们要在HDFS中导入的customer表中更新了cust id 101和102

| custid | Policy |
| 108 | 8 |
| 101 | 11 | 
| 102 | 12 | 

sqoop import \ 
--connect jdbc:mysql://localhost:3306/db \ 
--username root -P \ 
--table customer \ 
--target-dir /user/hive/warehouse/<your db>/<table> \
--append \
--check-column custid \
--incremental lastmodified \
--last-value 107

所以这四个属性我们将在同一个命令中用于插入/更新记录的cosider

--append \
--check-column <primary key> \
--incremental lastmodified \
--last-value <Last Value of primary key which sqoop job has inserted in last run>

我特别提到主键,好像表没有主键,那么需要考虑的更多属性是: -

多个映射器默认执行sqoop作业,因此映射器需要根据某些键拆分数据,所以

要么我们必须专门定义-m 1选项来说只有一个映射器将执行此操作

或者我们必须指定任何其他键(通过使用sqoop属性--split-by),您可以唯一地标识数据然后可以使用

答案 3 :(得分:1)

步骤1:导入整个表。这将作为指定HDFS位置的part-m文件提供(例如/ user / abc / def / part-m-00000) 步骤2:仅导入增量记录。这将在另一个位置(例如/ user / abc / def1 / part-m-00000)

现在两个数据都可用,您可以使用sqoop merge选项根据键列合并两者。

请参阅以下文档。了解更多详情

https://sqoop.apache.org/docs/1.4.3/SqoopUserGuide.html#_literal_sqoop_merge_literal

答案 4 :(得分:0)

您还可以尝试自由格式查询,该查询将根据特定条件进行更改。您可以使用Sqoop Client编写Java代码来执行相同的操作: How to use Sqoop in Java Program?

答案 5 :(得分:0)

在这种用例中,总是寻找增量附加的真正增量字段。 并且对于最后修改的外观,最适合的字段是modified_date,或者同样是某些字段,用于自sqoop-ed以来已更改的字段。只有那些和那些行将被更新,在hdfs位置添加更新的行需要增量追加。

答案 6 :(得分:0)

这里已经有很好的回应。除了这些,您还可以尝试Sqoop查询方法。您可以根据条件自定义查询以检索更新的记录。

步骤1:从数据库表导入新记录:

示例1:

$ sqoop导入\   -从(a.id == b.id)WHERE $ CONDITIONS的JOIN b中查询'SELECT a。,b。   --split-by a.id --target-dir / tmp / MyNewloc

示例2:

sqoop import --connect "jdbc:jtds:sqlserver://MYPD22:1333;databaseName=myDb"   --target-dir /tmp/MyNewloc --fields-terminated-by \| --username xxx --password='xxx' --query "select * from Policy_Table where Policy_ID > 1 AND \$CONDITIONS"  -m1 

不要忘记在Where子句中提供$ CONDITIONS。

请参考Sqoop Free Form Import

步骤2:合并基本表(原始数据)和新表(新记录)的部分M文件

您可以使用2种方法执行此操作。

方法1 -Using Sqoop Merge

方法2 -将新生成的part-m文件复制到原始表目标目录中。 (将部分M文件从/ tmp / MyNewloc复制到/ tmp / MyOriginalLoc /)

步骤3:创建HIVE表

1)现在使用“位置”作为原始表目标目录创建一个配置单元表,其中包含原始part-m文件和新记录part-m文件。

CREATE  EXTERNAL TABLE IF NOT EXISTS Policy_Table(
Policy_ID string,
Customer_Name string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '|'
STORED AS TEXTFILE
LOCATION '/tmp/MyOriginalLoc/';