Sqoopインクリメンタルインポートに関するアドバイスが必要です。 1日目にポリシー1を持つ顧客がいて、それらのレコードを1日目にHDFSにインポートし、それらをパーツファイルに表示したとします。
2日目に、同じ顧客がポリシー2を追加し、インクリメンタルインポートsqoopを実行した後、パーツファイルの新しいレコードのみを取得しますか?その場合、Sqoopを使用してOldおよびIncrementalの追加/最終変更レコードを取得するにはどうすればよいですか?
Sqoopを使用してhdfsにすでにインポートした3つのレコードを含むテーブルを考えます。
+------+------------+----------+------+------------+
| 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
上記のコードは、最後の値に基づいてすべての新しい行を挿入します。
行に更新がある2番目のケースを考えることができます
+------+------------+----------+------+------------+
| 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 |
+------+------------+----------+------+------------+
ここでは、日付に基づいて更新されたすべての行をフェッチする増分lastmodifiedを使用します。
sqoop import --connect jdbc:mysql://localhost:3306/ydb --table yloc --username root -P --check-column rDate --incremental lastmodified --last-value 2014-01-25 --target-dir yloc/loc
最初の質問への回答では、それはあなたがインポートステートメントを実行する方法に依存します。 --incremental append
オプションを使用する場合は、--check-column
および--last-value
引数を指定します。これらは、どのレコードがプルされるかを正確に指示し、それらは単にテーブルに追加されます。例:--check-column
引数にDATE
タイプの列と非常に早い日付( '1900-01-01'や Day1 など)を指定できます。あなたの場合)--last-value
の場合、これはソーステーブルのすべてを(重複する行を作成して)宛先に追加し続けるだけです。この場合、作成された新しいパーツファイルには新旧両方レコードが保持されます。増加するID列を使用して小さなIDを入力し続けることもできますが、同じ効果があります。ただし、--last-value
が Day2 の場合、only newレコードを含む追加のパーツファイルがあります。古いレコードが失われるのではないかと思っていたのかどうかはわかりません(万が一のために)。しかし、そうではありません。
last-modified
の--incremental
引数は、将来、前の行に戻って既存の行の属性の一部を更新する場合にのみ役立ちます。この場合、テーブル内の古いデータを置き換えて(そして新しいものを追加します)、現在ソーステーブルにある行の更新バージョンで置き換えます。お役に立てれば!
これはすべて、Sqoopユーザーガイドのセクション7.2.7に基づいています https://sqoop.Apache.org/docs/1.4.2/SqoopUserGuide.html#_incremental_imports
そして、Apache Sqoopクックブックの第3章(その章は実際には素晴らしいです!)
Sqoop incremental imports のステップバイステップガイドを次に示します。
概要については、ソーステーブルの行が更新されない場合、または更新を気にしない場合にのみ追加モードを使用しますが、既にインポートされているデータも更新する場合は、lastmodifiedを使用します。
ここで例を挙げましょう。cust_idとpolicyの2つの列を持つcustomerテーブルがあり、custidが主キーであり、cust id 100以降のデータを挿入したいだけです。
シナリオ1:-cust_idフィールドに基づいて新しいデータを追加する
フェーズ1:-
以下の3つのレコードは、HDFSにインポートしたい顧客テーブルに最近挿入されたものです
| 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
新しいレコードを挿入するために考慮しなければならないこれらの4つのプロパティ
--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フィールドに基づいて既存のデータを更新
cust id 108の1つの新しいレコードが挿入され、cust id 101と102がHDFSにインポートする顧客テーブルで最近更新されました
| 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
したがって、これらの4つのプロパティは、同じコマンドでレコードの挿入/更新を考慮する必要があります。
--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オプションを明確に定義して、この操作を実行するマッパーが1人だけであることを示す必要もあります。
または、(sqoopプロパティ--split-byを使用して)他のキーを指定する必要があります。データを一意に識別してから、
ステップ1:テーブル全体がインポートされます。これは、指定したHDFSの場所(/ user/abc/def/part-m-00000など)でpart-mファイルとして使用できます。ステップ2:増分レコードのみがインポートされます。これは別の場所(/ user/abc/def1/part-m-00000など)で利用可能になります
両方のデータが利用可能になったので、sqoopマージオプションを使用して、キー列に基づいて両方を統合できます。
以下のドキュメントを参照してください。詳細については
https://sqoop.Apache.org/docs/1.4.3/SqoopUserGuide.html#_literal_sqoop_merge_literal
また、特定の条件に基づいて変更されるフリーフォームクエリを試すこともできます。 Java Sqoop Clientを使用して同じことを行うコードを記述できます: SqoopをJavaプログラムで使用する方法)
ここにはすでに素晴らしい反応があります。これらに加えて、Sqoopクエリアプローチを試すこともできます。条件に基づいてクエリをカスタマイズし、更新されたレコードを取得できます。
例1:
$ sqoop import \-query 'SELECT a。、b。FROM a JOIN b on(a.id == b.id) WHERE $ CONDITIONS '\ --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自由形式のインポート
2つの方法を使用してこれを行うことができます。
方法1- Sqoop Mergeの使用
方法2-新しく生成されたpart-mファイルを元のテーブルターゲットディレクトリにコピーします。 (part-mファイルを/ tmp/MyNewlocから/ tmp/MyOriginalLoc /にコピーします)
1)次に、元のpart-mファイルと新しいレコードpart-mファイルの両方を含む場所を元のテーブルターゲットディレクトリとして使用して、Hiveテーブルを作成します。
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/';
このような使用例では、常にインクリメンタルアペンドの本質的にインクリメンタルなフィールドを探します。最後に変更されたルックの場合、最も適したフィールドはmodified_dateまたは同様に、sqoopを実行してから変更されたフィールドです。それらとそれらの行のみが更新されます。hdfsの場所に新しい行を追加するには、増分追加が必要です。