web-dev-qa-db-fra.com

Airflow S3KeySensor - Comment continuer à fonctionner

Avec l'aide de ce post Stackoverflow Je viens de créer un programme (celui montré dans le post) où lorsqu'un fichier est placé dans un compartiment S3, une tâche dans l'un de mes DAG en cours d'exécution est déclenchée, puis je effectuer certains travaux à l'aide de BashOperator. Une fois terminé, le DAG n'est plus en cours d'exécution mais passe à un état de réussite et si je veux qu'il récupère un autre fichier, je dois effacer tous les 'Passé', 'Futur', 'En amont', ' Activité en aval. Je voudrais que ce programme soit toujours en cours d'exécution et chaque fois qu'un nouveau fichier est placé dans le compartiment S3, le programme démarre les tâches.

Puis-je continuer à utiliser le S3KeySenor pour ce faire ou dois-je trouver un moyen de configurer un déclencheur externe pour exécuter mon DAG? Pour l'instant, mon S3KeySensor est assez inutile s'il ne doit fonctionner qu'une seule fois.

from airflow import DAG
from airflow.operators import SimpleHttpOperator, HttpSensor, EmailOperator, S3KeySensor
from datetime import datetime, timedelta
from airflow.operators.bash_operator import BashOperator

default_args = {
    'owner': 'airflow',
    'depends_on_past': False,
    'start_date': datetime(2018, 5, 29),
    'email': ['[email protected]'],
    'email_on_failure': False,
    'email_on_retry': False,
    'retries': 5,
    'retry_delay': timedelta(minutes=5)
}

dag = DAG('s3_triggered_emr_cluster_dag', default_args=default_args, schedule_interval= '@once')

# This Activity runs a Python script that creates an AWS EMR cluster and then does EMR activity on the EMR cluster.
t2 = BashOperator(
    task_id='create_emr_cluster_1',
    bash_command='python /home/ec2-user/aws-python-sample/Create_EMR_Then_Do_EMR_Activities.py',
    retries=1,
    dag=dag)

t1 = BashOperator(
    task_id='success_log',
    bash_command='echo "Dag ran successfully" >> /home/ec2-user/s3_triggered_dag.txt',
    dag=dag)

sensor = S3KeySensor(
    task_id='new_s3_file_in_foobar-bucket',
    bucket_key='*',
    wildcard_match=True,
    bucket_name='foobar-bucket',
    s3_conn_id='s3://foobar-bucket',
    timeout=18*60*60,
    poke_interval=120,
    dag=dag)

t1.set_upstream(sensor)
t2.set_upstream(t1)

Je me demande si ce n'est pas possible car il ne s'agirait pas alors d'un graphe acyclique dirigé mais plutôt d'une boucle qui répéterait sensor -> t1 -> t2 -> sensor -> t1 -> t2 -> capteur -> ... continuez à répéter .

Mise à jour:

Mon cas d'utilisation est assez simple, chaque fois qu'un nouveau fichier est placé dans un compartiment AWS S3 désigné, je veux que mon DAG soit déclenché et démarre mon processus de diverses tâches. Les tâches consistent à instancier un nouveau cluster AWS EMR, extraire les fichiers du compartiment AWS S3, effectuer certaines activités AWS EMR, puis arrêter le cluster AWS EMR. À partir de là, le DAG retournerait dans un état d'attente où il attendrait l'arrivée de nouveaux fichiers dans le compartiment AWS S3, puis répéterait le processus indéfiniment.

17
Kyle Bridenstine

Dans Airflow, aucun concept ne correspond à un DAG toujours en cours d'exécution. Vous pouvez faire exécuter un DAG très fréquemment comme toutes les 1 à 5 minutes si cela convient à votre cas d'utilisation.

L'essentiel ici est que le S3KeySensor vérifie jusqu'à ce qu'il détecte que le premier fichier existe dans le chemin générique de la clé (ou timeout), puis il s'exécute. Mais lorsqu'un deuxième, un troisième ou un quatrième fichier atterrit, le capteur S3 aura déjà terminé son exécution pour cette exécution DAG. Il ne sera pas planifié de s'exécuter à nouveau jusqu'à la prochaine exécution du DAG. (L'idée de bouclage que vous avez décrite est à peu près équivalente à ce que fait le planificateur lorsqu'il crée des exécutions DAG, sauf pas pour toujours.)

Un déclencheur externe semble définitivement la meilleure approche pour votre cas d'utilisation, que ce déclencheur provienne de la commande trigger_dag de la CLI d'Airflow ($ airflow trigger_dag ...):

https://github.com/Apache/incubator-airflow/blob/972086aeba4616843005b25210ba3b2596963d57/airflow/bin/cli.py#L206-L222

Ou via l'API REST:

https://github.com/Apache/incubator-airflow/blob/5de22d7fa0d8bc6b9267ea13579b5ac5f62c8bb5/airflow/www/api/experimental/endpoints.py#L41-L89

Les deux se retournent et appellent le trigger_dag fonction dans l'API commune (expérimentale):

https://github.com/Apache/incubator-airflow/blob/089c996fbd9ecb0014dbefedff232e8699ce6283/airflow/api/common/experimental/trigger_dag.py#L28-L67

Vous pouvez, par exemple, configurer une fonction AWS Lambda, appelée lorsqu'un fichier atterrit sur S3, qui exécute l'appel DAG de déclenchement.

11
Taylor Edmiston