web-dev-qa-db-fra.com

Comment décharger une table sur RedShift dans un seul fichier CSV?

Je souhaite migrer une table d'Amazon RedShift vers MySQL, mais l'utilisation de "décharger" générera plusieurs fichiers de données qui sont difficiles à importer directement dans MySQL.

Existe-t-il une approche pour décharger la table dans un seul fichier CSV afin de pouvoir l'importer directement dans MySQL?

19
ciphor

Pour envoyer vers un seul fichier, utilisez Parallel Off

unload ('select * from venue')
to 's3://mybucket/tickit/unload/venue_' credentials 
'aws_access_key_id=<access-key-id>;aws_secret_access_key=<secret-access-key>'
parallel off;

Je recommande également d'utiliser Gzip, pour rendre ce fichier encore plus petit à télécharger.

unload ('select * from venue')
to 's3://mybucket/tickit/unload/venue_' credentials 
'aws_access_key_id=<access-key-id>;aws_secret_access_key=<secret-access-key>'
parallel off
gzip;
37

C'est une vieille question à ce stade, mais j'ai l'impression que toutes les réponses existantes sont légèrement trompeuses. Si votre question est: "Puis-je absolument garantir à 100% que Redshift déchargera TOUJOURS un fichier SINGLE dans S3?", La réponse est simplement [~ # ~] non [~ # ~] .

Cela étant dit, dans la plupart des cas, vous pouvez généralement limiter votre requête de manière à vous retrouver avec un seul fichier. Selon la documentation ( https://docs.aws.Amazon.com/redshift/latest/dg/r_UNLOAD.html ), le principal facteur qui limite le nombre de fichiers que vous générez est la taille brute réelle en octets de votre exportation ( [~ # ~] pas [~ # ~] le nombre de lignes). La taille limite d'un fichier de sortie généré par la commande Redshift UNLOAD est de 6,2 Go.

Donc, si vous voulez essayer de garantir que vous obtenez un seul fichier de sortie de UNLOAD, voici ce que vous devez essayer:

  • Spécifiez PARALLEL OFF. Parallèle est "ON" par défaut et écrit généralement sur plusieurs fichiers sauf si vous avez un petit cluster (le nombre de fichiers de sortie avec "PARALLEL ON" défini est proportionnel au nombre de tranches dans votre cluster). PARALLEL OFF écrira les fichiers en série sur S3 plutôt qu'en parallèle et n'utilisera plusieurs fichiers que si vous dépassez la taille limite.
  • Limitez la taille de votre sortie. La taille brute des données doit être inférieure à 6,2 Go si vous souhaitez un seul fichier. Vous devez donc faire en sorte que votre requête contienne une clause WHERE plus restrictive ou utiliser une clause LIMIT pour limiter le nombre d'enregistrements. Malheureusement, aucune de ces techniques n'est parfaite car les lignes peuvent être de taille variable. Je ne sais pas non plus si l'option GZIP affecte la limite de débordement de la taille du fichier de sortie ou non (il n'est pas clair si 6,2 Go est la limite de taille pré-GZIP ou la limite de taille post-GZIP).

Pour moi, la commande UNLOAD qui finissait par générer un seul fichier CSV dans la plupart des cas était:

UNLOAD
('SELECT <fields> FROM <table> WHERE <restrict_query>')
TO 's3://<bucket_name>/<filename_prefix>'
CREDENTIALS 'aws_access_key_id=<access_key>;aws_secret_access_key=<secret_key>'
DELIMITER AS ','
ADDQUOTES
NULL AS ''
PARALLEL OFF;

L'autre effet secondaire agréable de PARALLEL OFF c'est qu'il respectera votre ORDER BY clause si vous en avez un et générez les fichiers dans un ordre qui conserve tous les enregistrements ordonnés, même sur plusieurs fichiers de sortie.

Addendum: Il semble y avoir des connaissances folkloriques sur l'utilisation de LIMIT 2147483647 pour forcer le nœud principal à effectuer tout le traitement et à générer un seul fichier de sortie, mais cela ne semble être documenté nulle part dans la documentation Redshift et en tant que tel, s'appuyer dessus semble être une mauvaise idée car il pourrait changer à tout moment.

9
Brent Writes Code

C'est un peu une solution de contournement, mais vous devez faire de votre requête une sous-requête et inclure une limite. Il sera ensuite sorti dans un fichier. Par exemple.

select * from (select * from bizdata LIMIT 2147483647);

Donc, fondamentalement, vous sélectionnez tout dans un ensemble limité. C'est la seule façon dont cela fonctionne. 2147483647 est votre limite maximale, car une clause limite prend un argument entier non signé.

Ainsi, les éléments suivants seront déchargés dans un fichier:

unload(' select * from (
select bizid, data
from biztable
limit 2147483647);
 ') to 's3://.......' CREDENTIALS 'aws_access_key_id=<<aws_access_key_id>>;aws_secret_access_key=<<aws_secret_access_key>>' csv ; 
3
davefender

Nan. {Vous pouvez tilisez un manifeste et dites à Redshift de diriger toutes les sorties vers un seul fichier. } La réponse précédente était fausse, j'avais utilisé des manifestes pour le chargement mais pas pour le déchargement.

Il semble qu'il y ait 2 façons possibles d'obtenir un seul fichier:

  1. Plus facile: Enroulez une requête SELECT… LIMIT autour de votre requête de sortie réelle, selon cette SO mais cela est limité à ~ 2 milliards de lignes.
  2. Plus difficile: tilisez l'utilitaire Unix cat pour joindre les fichiers ensemblecat File1.txt File2.txt > union.txt. Cela vous demandera de télécharger les fichiers à partir de S3 en premier.
1
Joe Harris

Il n'y a aucun moyen de forcer Redshift à générer un seul fichier de sortie, c'est sûr.

Sous UNLOAD standard, vous aurez des fichiers de sortie créés équivalents au nombre de tranches système, c'est-à-dire qu'un système avec 8 tranches créera 8 fichiers pour une seule commande de déchargement (C'est la méthode la plus rapide pour décharger.)

Si vous ajoutez une clause PARALLEL OFF à la commande de déchargement, votre sortie sera créée sous la forme d'un fichier unique, jusqu'au moment où l'extrait de données ne dépassera pas 6,25 Go, après quoi Redshift divisera automatiquement le fichier en un nouveau bloc .

La même chose est vraie, si vous produisez également des fichiers de sortie compressés (vous aurez bien sûr plus de chances de produire un seul fichier de sortie, étant donné que votre fichier peut contenir plus d’enregistrements).

1
Suvrat