web-dev-qa-db-de.com

Airflow protokolliert BrokenPipeException

Ich verwende eine Cluster-Airflow-Umgebung, in der ich vier AWS ec2-Instanzen für die Server habe.

ec2-Instanzen

  • Server 1: Webserver, Scheduler, Redis-Warteschlange, PostgreSQL-Datenbank
  • Server 2: Webserver
  • Server 3: Arbeiter
  • Server 4: Arbeiter

Mein Setup funktioniert jetzt seit drei Monaten einwandfrei. Sporadisch etwa einmal pro Woche bekomme ich eine gebrochene Pipe-Ausnahme, wenn Airflow versucht, etwas zu protokollieren.

*** Log file isn't local.
*** Fetching here: http://ip-1-2-3-4:8793/log/foobar/task_1/2018-07-13T00:00:00/1.log

[2018-07-16 00:00:15,521] {cli.py:374} INFO - Running on Host ip-1-2-3-4
[2018-07-16 00:00:15,698] {models.py:1197} INFO - Dependencies all met for <TaskInstance: foobar.task_1 2018-07-13 00:00:00 [queued]>
[2018-07-16 00:00:15,710] {models.py:1197} INFO - Dependencies all met for <TaskInstance: foobar.task_1 2018-07-13 00:00:00 [queued]>
[2018-07-16 00:00:15,710] {models.py:1407} INFO - 
--------------------------------------------------------------------------------
Starting attempt 1 of 1
--------------------------------------------------------------------------------

[2018-07-16 00:00:15,719] {models.py:1428} INFO - Executing <Task(OmegaFileSensor): task_1> on 2018-07-13 00:00:00
[2018-07-16 00:00:15,720] {base_task_runner.py:115} INFO - Running: ['bash', '-c', 'airflow run foobar task_1 2018-07-13T00:00:00 --job_id 1320 --raw -sd DAGS_FOLDER/datalake_digitalplatform_arl_workflow_schedule_test_2.py']
[2018-07-16 00:00:16,532] {base_task_runner.py:98} INFO - Subtask: [2018-07-16 00:00:16,532] {configuration.py:206} WARNING - section/key [celery/celery_ssl_active] not found in config
[2018-07-16 00:00:16,532] {base_task_runner.py:98} INFO - Subtask: [2018-07-16 00:00:16,532] {default_celery.py:41} WARNING - Celery Executor will run without SSL
[2018-07-16 00:00:16,534] {base_task_runner.py:98} INFO - Subtask: [2018-07-16 00:00:16,533] {__init__.py:45} INFO - Using executor CeleryExecutor
[2018-07-16 00:00:16,597] {base_task_runner.py:98} INFO - Subtask: [2018-07-16 00:00:16,597] {models.py:189} INFO - Filling up the DagBag from /home/ec2-user/airflow/dags/datalake_digitalplatform_arl_workflow_schedule_test_2.py
[2018-07-16 00:00:16,768] {cli.py:374} INFO - Running on Host ip-1-2-3-4
[2018-07-16 00:16:24,931] {logging_mixin.py:84} WARNING - --- Logging error ---

[2018-07-16 00:16:24,931] {logging_mixin.py:84} WARNING - Traceback (most recent call last):

[2018-07-16 00:16:24,931] {logging_mixin.py:84} WARNING -   File "/usr/lib64/python3.6/logging/__init__.py", line 996, in emit
    self.flush()

[2018-07-16 00:16:24,932] {logging_mixin.py:84} WARNING -   File "/usr/lib64/python3.6/logging/__init__.py", line 976, in flush
    self.stream.flush()

[2018-07-16 00:16:24,932] {logging_mixin.py:84} WARNING - BrokenPipeError: [Errno 32] Broken pipe

[2018-07-16 00:16:24,932] {logging_mixin.py:84} WARNING - Call stack:

[2018-07-16 00:16:24,933] {logging_mixin.py:84} WARNING -   File "/usr/bin/airflow", line 27, in <module>
    args.func(args)

[2018-07-16 00:16:24,934] {logging_mixin.py:84} WARNING -   File "/usr/local/lib/python3.6/site-packages/airflow/bin/cli.py", line 392, in run
    pool=args.pool,

[2018-07-16 00:16:24,934] {logging_mixin.py:84} WARNING -   File "/usr/local/lib/python3.6/site-packages/airflow/utils/db.py", line 50, in wrapper
    result = func(*args, **kwargs)

[2018-07-16 00:16:24,934] {logging_mixin.py:84} WARNING -   File "/usr/local/lib/python3.6/site-packages/airflow/models.py", line 1488, in _run_raw_task
    result = task_copy.execute(context=context)

[2018-07-16 00:16:24,934] {logging_mixin.py:84} WARNING -   File "/usr/local/lib/python3.6/site-packages/airflow/operators/sensors.py", line 78, in execute
    while not self.poke(context):

[2018-07-16 00:16:24,934] {logging_mixin.py:84} WARNING -   File "/home/ec2-user/airflow/plugins/custom_plugins.py", line 35, in poke
    directory = os.listdir(full_path)

[2018-07-16 00:16:24,934] {logging_mixin.py:84} WARNING -   File "/usr/local/lib/python3.6/site-packages/airflow/utils/timeout.py", line 36, in handle_timeout
    self.log.error("Process timed out")

[2018-07-16 00:16:24,934] {logging_mixin.py:84} WARNING - Message: 'Process timed out'
Arguments: ()

[2018-07-16 00:16:24,942] {models.py:1595} ERROR - Timeout
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/airflow/models.py", line 1488, in _run_raw_task
    result = task_copy.execute(context=context)
  File "/usr/local/lib/python3.6/site-packages/airflow/operators/sensors.py", line 78, in execute
    while not self.poke(context):
  File "/home/ec2-user/airflow/plugins/custom_plugins.py", line 35, in poke
    directory = os.listdir(full_path)
  File "/usr/local/lib/python3.6/site-packages/airflow/utils/timeout.py", line 37, in handle_timeout
    raise AirflowTaskTimeout(self.error_message)
airflow.exceptions.AirflowTaskTimeout: Timeout
[2018-07-16 00:16:24,942] {models.py:1624} INFO - Marking task as FAILED.
[2018-07-16 00:16:24,956] {models.py:1644} ERROR - Timeout

Manchmal wird der Fehler auch sagen

*** Log file isn't local.
*** Fetching here: http://ip-1-2-3-4:8793/log/foobar/task_1/2018-07-12T00:00:00/1.log
*** Failed to fetch log file from worker. 404 Client Error: NOT FOUND for url: http://ip-1-2-3-4:8793/log/foobar/task_1/2018-07-12T00:00:00/1.log

Ich bin nicht sicher, warum die Protokolle zu 95% der Zeit funktionieren, aber zu anderen Zeitpunkten zufällig ausfallen. Hier sind meine Protokolleinstellungen in meiner Airflow.cfg-Datei.

# The folder where airflow should store its log files
# This path must be absolute
base_log_folder = /home/ec2-user/airflow/logs

# Airflow can store logs remotely in AWS S3 or Google Cloud Storage. Users
# must supply an Airflow connection id that provides access to the storage
# location.
remote_log_conn_id =
encrypt_s3_logs = False

# Logging level
logging_level = INFO

# Logging class
# Specify the class that will specify the logging configuration
# This class has to be on the python classpath
# logging_config_class = my.path.default_local_settings.LOGGING_CONFIG
logging_config_class =

# Log format
log_format = [%%(asctime)s] {%%(filename)s:%%(lineno)d} %%(levelname)s - %%(message)s
simple_log_format = %%(asctime)s %%(levelname)s - %%(message)s

# Name of handler to read task instance logs.
# Default to use file task handler.
task_log_reader = file.task

# Log files for the gunicorn webserver. '-' means log to stderr.
access_logfile = -
error_logfile = 

# The amount of time (in secs) webserver will wait for initial handshake
# while fetching logs from other worker machine
log_fetch_timeout_sec = 5

# When you start an airflow worker, airflow starts a tiny web server
# subprocess to serve the workers local log files to the airflow main
# web server, who then builds pages and sends them to users. This defines
# the port on which the logs are served. It needs to be unused, and open
# visible from the main web server to connect into the workers.
worker_log_server_port = 8793

# How often should stats be printed to the logs
print_stats_interval = 30

child_process_log_directory = /home/ec2-user/airflow/logs/scheduler

Ich frage mich, ob ich vielleicht eine andere Technik für meine Protokollierung ausprobieren sollte, beispielsweise das Schreiben in einen S3-Bucket oder ob ich etwas anderes tun kann, um dieses Problem zu beheben.

Update:

Durch das Schreiben der Protokolle in S3 wurde dieses Problem nicht behoben. Außerdem ist der Fehler jetzt konsistenter (immer noch sporadisch). Es passiert jetzt mehr als 50% der Zeit. Eine Sache, die mir aufgefallen ist, ist, dass es sich bei meiner Aufgabe um die Erstellung einer AWS EMR-Aufgabe handelt. Das Starten eines AWS EMR-Clusters dauert etwa 20 Minuten. Anschließend muss die Task warten, bis die Spark-Befehle im EMR-Cluster ausgeführt werden. Die einzelne Task läuft also etwa 30 Minuten. Ich frage mich, ob dies zu lang ist, um eine Airflow-Aufgabe auszuführen, und ob dies der Grund ist, dass das Schreiben in die Protokolle fehlschlägt. Wenn dies der Fall ist, könnte ich die EMR-Aufgabe unterbrechen, so dass es eine Aufgabe für die EMR-Erstellung gibt, dann eine weitere Aufgabe für die Spark-Befehle im EMR-Cluster.

Hinweis:

Ich habe auch ein neues Bug-Ticket für Jira von Airflow hier erstellt https://issues.Apache.org/jira/browse/AIRFLOW-2844

9

Dieses Problem ist ein Symptom für ein anderes Problem, das ich gerade hier gelöst habe AirflowException: Celery-Befehl ist fehlgeschlagen - Der aufgezeichnete Hostname stimmt nicht mit dem Hostnamen dieser Instanz überein.

Ich habe den AirflowException: Celery-Befehl ist fehlgeschlagen für eine Weile nicht angezeigt, da er in den (Airflow Worker-Protokollen angezeigt wurde. Erst als ich die Protokolle des Airflow-Workers in Echtzeit gesehen habe, als ich den Fehler auslöste, bekam ich auch die BrokenPipeException in meiner Aufgabe.

Es wird aber etwas seltsamer. Ich würde die BrokenPipeException nur dann werfen sehen, wenn ich print("something to log")undder AirflowException: Celery command failed...-Fehler auf dem Worker-Knoten aufgetreten wäre. Wenn ich alle meine Druckanweisungen geändert habe, um import logging ... logging.info("something to log") zu verwenden, würde ich das nicht sehen BrokenPipeException aberdie Aufgabe würde aufgrund des AirflowException: Celery command failed...-Fehlers immer noch fehlschlagen. Wenn ich jedoch nicht gesehen hätte, dass die BrokenPipeException in meinen Airflow-Aufgabenprotokollen ausgelöst wurde, hätte ich nicht gewusst, warum die Aufgabe fehlgeschlagen ist, weil ich die Druckanweisungen einmal beseitigt hatte hat nie einen Fehler in den Airflow-Aufgabenprotokollen festgestellt (nur in den Protokollen $ airflow worker)

Kurz gesagt, es gibt ein paar Take Aways.

  1. Tun Sie dies nicht print("something to log") Verwenden Sie die integrierte Protokollierung von Airflow, indem Sie die Protokollierung importieren und dann die Protokollierungsklasse wie import logging und dann logging.info("something to log") verwenden.

  2. Wenn Sie eine AWS EC2-Instanz als Server für Airflow verwenden, tritt möglicherweise dieses Problem auf: https://github.com/Apache/incubator-airflow/pull/2484 Dieses Problem wurde behoben bereits in Airflow Version 1.10 integriert (derzeit verwende ich Airflow Version 1.9). Aktualisieren Sie daher Ihre Airflow-Version auf 1.10 . Sie können auch den Befehl hierpip install git+git://github.com/Apache/[email protected] verwenden. Wenn Sie Ihre Airflow-Version nicht aktualisieren möchten, können Sie auch die Schritte unter the github issue befolgen, um die Datei entweder manuell mit dem Fix oder mit Airflow zu aktualisieren und den Commit auszuwählen, der sie behebt.

2