Besoin de conseils sur les importations incrémentielles Sqoop. Supposons que j'ai un client avec la politique 1 le jour 1 et que j'ai importé ces enregistrements dans HDFS le jour 1 et que je les vois dans les fichiers de pièces.
Le jour 2, le même client ajoute la règle 2 et, après l'exécution incrémentielle de sqoop, obtiendrons-nous uniquement de nouveaux enregistrements dans les fichiers de pièce? Dans ce cas, comment puis-je obtenir les enregistrements anciens et incrémentiels ajoutés/modifiés avec Sqoop?
Considérons une table avec 3 enregistrements que vous avez déjà importés au format hdfs à l'aide de sqoop
+------+------------+----------+------+------------+
| 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
Maintenant, vous avez des enregistrements supplémentaires dans la table, mais pas de mises à jour sur les enregistrements existants
+------+------------+----------+------+------------+
| 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 |
+------+------------+----------+------+------------+
Ici, vous devez utiliser un --incremental append
avec --check-column
qui spécifie la colonne à examiner pour déterminer les lignes à importer.
sqoop import --connect jdbc:mysql://localhost:3306/ydb --table yloc --username root -P --check-column rank --incremental append --last-value 7
Le code ci-dessus insérera toutes les nouvelles lignes en fonction de la dernière valeur.
Maintenant, nous pouvons penser au deuxième cas où il y a des mises à jour dans les lignes
+------+------------+----------+------+------------+
| 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 |
+------+------------+----------+------+------------+
Ici, nous utilisons incrémental lastmodified où nous allons récupérer toutes les lignes mises à jour en fonction de la date.
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
En réponse à votre première question, cela dépend de la manière dont vous exécutez l'instruction d'importation. Si vous utilisez l'option --incremental append
, vous spécifiez vos arguments --check-column
et --last-value
. Ceux-ci dicteront exactement quels enregistrements seront extraits et ils seront simplement ajoutés à votre table. Par exemple: vous pouvez spécifier une colonne de type DATE
pour votre argument --check-column
et une date très précoce (comme '1900-01-01' ou Day1 dans votre cas) pour --last-value
et ceci ne ferait que l'ajouter dans la table source (création de lignes en double) vers votre destination. Dans ce cas, les nouveaux fichiers de pièce créés contiendront nouveaux et anciens enregistrements. Vous pouvez également utiliser une colonne d'identifiant croissant et continuer à saisir le petit identifiant, ce qui aurait le même effet. Toutefois, si --last-value
est Day2, il y aura des fichiers de pièce supplémentaires avec les enregistrements nouveaux uniquement. Je ne sais pas si vous vous demandiez si vous perdriez les anciens dossiers (juste au cas où vous l'auriez), mais ce n'est pas le cas.
L'argument last-modified
pour --incremental
ne serait utile que si, à l'avenir, vous revenez en arrière et mettez à jour certains des attributs d'une ligne existante. Dans ce cas, il remplace les anciennes données de votre table (et ajoute le nouveau matériel) par la version mise à jour de la ligne qui se trouve maintenant dans votre table source. J'espère que cela t'aides!
Oh, tout ceci est basé sur le Guide de l'utilisateur Sqoop, section 7.2.7 https://sqoop.Apache.org/docs/1.4.2/SqoopUserGuide.html#_incremental_imports
et le chapitre 3 du livre de recettes Apache Sqoop (ce chapitre est en fait fantastique!)
Voici un guide étape par étape pour Importations incrémentielles Sqoop .
Pour une vue d'ensemble, vous utilisez le mode Ajout uniquement lorsque les lignes de votre table source ne sont pas mises à jour ou si vous ne vous souciez pas des mises à jour. Toutefois, vous utilisez lastmodified pour mettre à jour les données déjà importées.
Étape 1: La table entière est importée. Ce fichier sera disponible en tant que fichier pièce-m dans l’emplacement HDFS spécifié (par exemple, /user/abc/def/part-m-00000)Etape 2: seuls les enregistrements incrémentiels sont importés. Ce sera disponible dans un autre emplacement (par exemple,/user/abc/def1/part-m-00000)
Maintenant que les deux données sont disponibles, vous pouvez utiliser l'option de fusion sqoop pour les consolider en fonction de la colonne clé.
Voir le doc ci-dessous. pour plus de détails
https://sqoop.Apache.org/docs/1.4.3/SqoopUserGuide.html#_literal_sqoop_merge_literal
Vous pouvez également essayer une requête de forme libre qui va être modifiée en fonction d'une condition spécifique. Vous pouvez écrire un code Java à l'aide de Sqoop Client pour en faire de même: Comment utiliser Sqoop dans un programme Java?
Il y a déjà de bonnes réponses ici. Parallèlement, vous pouvez également essayer Sqoop Query Approach. Vous pouvez personnaliser votre requête en fonction de la condition pour extraire les enregistrements mis à jour.
Exemple 1:
$ sqoop import\ --query 'SELECT a ., b. FROM a JOIN b sur (a.id == b.id) WHERE $ CONDITIONS'\ --split-by a.id --target-dir/tmp/MyNewloc
Exemple 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
_ {N'oubliez pas de fournir $ CONDITIONS dans la clause Where.} _
Veuillez vous référer Sqoop Free Form Import
Vous pouvez le faire en utilisant 2 méthodes.
Méthode 1 - Utilisation de Sqoop Merge
Méthode 2 - Copie des fichiers pièce nouvellement générés dans le répertoire cible de la table d'origine. (Copiez les fichiers de partie-m de/tmp/MyNewloc dans/tmp/MyOriginalLoc /)
1) Créez maintenant une table Hive en utilisant Location comme répertoire cible de la table d'origine, qui contient à la fois les fichiers pièce-m d'origine et les nouveaux fichiers partie-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/';
Dans de tels cas d'utilisation, recherchez toujours les champs qui sont véritablement de nature incrémentielle pour incrémental append . Et pour la dernière apparence modifiée, le champ le mieux adapté est modified_date ou de même certains champs pour ceux qui ont été modifiés depuis que vous les avez vus. seules celles-ci et ces lignes seront mises à jour; l'ajout de nouvelles lignes dans votre emplacement hdfs nécessite l'ajout incrémental.
prenons exemple ici, vous avez une table client avec deux colonnes cust_id et policy, également custid est votre clé primaire et vous voulez simplement insérer des données cust id 100 à partir de
scénario 1: - ajoutez de nouvelles données sur la base du champ cust_id
la phase 1:-
ci-dessous 3 enregistrements sont insérés récemment dans la table des clients que nous voulons importer dans HDFS
| custid | Policy |
| 101 | 1 |
| 102 | 2 |
| 103 | 3 |
voici la commande sqoop pour cela
sqoop import\-- connectez-vous jdbc: mysql: // localhost: 3306/db\-- nom d'utilisateur racine -P\-- table client\-- rép-cible/utilisateur/Ruche/entrepôt //\-- append\-- vérification de la colonne de contrôle\-- incremental append\-- last-value 100
phase2: - ci-dessous 4 enregistrements sont insérés récemment dans la table des clients que nous souhaitons importer dans HDFS
| custid | Policy |
| 104 | 4 |
| 105 | 5 |
| 106 | 6 |
| 107 | 7 |
voici la commande sqoop pour cela
sqoop import\-- connectez-vous jdbc: mysql: // localhost: 3306/db\-- nom d'utilisateur racine -P\-- table client\-- rép-cible/utilisateur/Ruche/entrepôt //\-- append\-- vérification de la colonne de contrôle\-- incremental append\-- last-value 103
de sorte que ces quatre propriétés, nous devrons cosider pour l'insertion de nouveaux enregistrements
--append \
--check-column <primary key> \
--incremental append \
--last-value <Last Value of primary key which sqoop job has inserted in last run>
scénario 2: - ajoute de nouvelles données + met à jour les données existantes en fonction du champ cust_id
ci-dessous 1 nouvel enregistrement avec cust id 108 inséré et cust id 101 et 102 récemment mis à jour dans la table des clients que nous souhaitons importer dans HDFS
| custid | Policy |
| 108 | 8 |
| 101 | 11 |
| 102 | 12 |
sqoop import\-- connectez-vous jdbc: mysql: // localhost: 3306/db\-- nom d'utilisateur racine -P\-- table client\-- rép-cible/utilisateur/Ruche/entrepôt //\-- append\-- vérification de la colonne de contrôle\-- incrémentale lastmodified\-- last-value 107
donc ces quatre propriétés, nous devrons cosider pour insérer/mettre à jour des enregistrements dans la même commande
--append \
--check-column <primary key> \
--incremental lastmodified \
--last-value <Last Value of primary key which sqoop job has inserted in last run>
Je mentionne spécifiquement la clé primaire comme si la table n'avait pas de clé primaire, quelques propriétés supplémentaires doivent être considérées, à savoir: -
plusieurs mappeurs effectuent le travail sqoop par défaut afin que le mappeur ait besoin que les données soient fractionnées sur la base d'une clé afin que
soit nous devons définir spécifiquement l'option --m 1 pour dire qu'un seul mappeur effectuera cette opération
ou nous devons spécifier toute autre clé (en utilisant la propriété sqoop --split-by) avec vous pouvez identifier les données de manière unique, puis vous pouvez utiliser