Weiter zum Inhalt
Datentechnik

Cronjobs im Data Engineering: So planst du Datenpipelines

Lerne, wie du Cronjobs im Data Engineering einsetzt – ideal, um Routineaufgaben zu automatisieren, Zuverlässigkeit zu erhöhen und Workflows zu optimieren.
Dario Radečić's photo
Dario Radečić
Aktualisiert · 15 Min. lesen

Entdecke KI

ChatGPTClaudePerplexity

Erstelle dein kostenloses Konto

Üben und Lernpfad deinen Fortschritt.

Weiter Mit Google
Durch Klick auf die Schaltfläche akzeptierst du unsere Nutzungsbedingungen, unsere Datenschutzrichtlinie und die Speicherung deiner Daten in den USA.

Wenn du wiederkehrende Aufgaben oft per Hand erledigst, weißt du: Es ist nicht nur mühsam – es führt zu verpassten Deadlines und instabilen Datenpipelines.

Cronjobs sind die Standardlösung, um wiederkehrende Aufgaben auf Unix-Systemen zu automatisieren. Damit planst du Befehle oder Skripte zu festen Zeitpunkten. Mit dem einfachen und flexiblen Zeitplansystem von cron automatisierst du alles – von der Datenerfassung bis zu komplexen ETL-Workflows, die sonst ständige manuelle Eingriffe bräuchten. Automatisierte Abläufe reduzieren menschliche Fehler und sorgen dafür, dass deine Datenpipelines konstant und zuverlässig laufen.

Cronjobs zu beherrschen ist für Data-Engineering-Profis in Unix-Umgebungen essenziell. Die Möglichkeit, Aufgaben zu terminieren und zu steuern, verbessert deinen Workflow enorm und senkt den Wartungsaufwand deutlich.

In diesem Leitfaden zeige ich dir alles, was du über Cronjobs im Data Engineering wissen musst – von der Einrichtung über fortgeschrittene Use Cases bis zu Best Practices.

>Ganz neu im Data Engineering? Unser Kurs macht die Buzzwords greifbar und erklärt die Konzepte.

Was ist ein Cronjob?

Ein Cronjob ist ein zeitbasierter Scheduler in Unix-Betriebssystemen, der Befehle automatisch zu festgelegten Zeiten, an bestimmten Tagen oder in Intervallen ausführt. 

Stell dir cron als deinen persönlichen Assistenten vor, der Aufgaben genau dann ausführt, wann du es willst – ganz ohne manuelles Zutun. Für Data Engineers heißt das: Datenbank-Backups, Datentransfers, Reportgenerierung und vieles mehr laufen automatisch.

Cronjobs stehen in einer einfachen Textdatei namens „crontab“ (cron table). Jede Zeile repräsentiert eine geplante Aufgabe und folgt einem Format mit sechs Komponenten:

* * * * * command-to-execute
│ │ │ │ │
│ │ │ │ └─── Day of week (0-6, where 0 is Sunday)
│ │ │ └───── Month (1-12)
│ │ └─────── Day of month (1-31)
│ └───────── Hour (0-23)
└─────────── Minute (0-59)

Die ersten fünf Felder geben an, wann der Befehl laufen soll. Du kannst konkrete Werte, Bereiche (z. B. 1-5), Listen (z. B. 1, 3, 5) oder Sterne (*) für „jede“ Zeiteinheit nutzen. Die sechste Komponente ist der eigentliche auszuführende Befehl.

Wenn du beispielsweise ein Python-Skript jeden Tag um Mitternacht starten willst, um Daten aus einer API zu ziehen, sähe dein Cronjob so aus:

0 0 * * * /usr/bin/python3 /home/username/scripts/extract_data.py

Das weist cron an, das Skript um 0 Minuten, 0 Uhr (Mitternacht), an jedem Tag, in jedem Monat und an jedem Wochentag auszuführen. Absolute Pfade für den Python-Interpreter und dein Skript stellen sicher, dass der Job unabhängig von der Umgebung korrekt läuft.

Du kannst auch komplexere Zeitpläne erstellen. Angenommen, du willst eine Datenbankbereinigung jeden Montag, Mittwoch und Freitag um 15:30 Uhr ausführen, sähe der Cron-Ausdruck so aus:

30 15 * * 1,3,5 /path/to/cleanup_script.sh

Jeder Stern fungiert als Platzhalter und erlaubt flexible Zeitpläne nach deinem Bedarf. Es gibt auch Abkürzungen wie @daily, @weekly oder @monthly für gängige Muster.

Das waren die Basics. Als Nächstes zeige ich dir Schritt für Schritt, wie du Cronjobs für Data-Engineering-Aufgaben nutzt.

Cronjob für Data-Engineering-Aufgaben einrichten

Du kennst nun cron – richten wir deinen ersten automatisierten Task ein. Das geht schnell und erfordert nur wenige Befehle.

Die crontab-Datei bearbeiten

Zum Erstellen oder Anpassen von Cronjobs öffnest du deine crontab mit crontab -e:

crontab -e

Image 1 - Editing a crontab file

Bild 1 – Eine crontab-Datei bearbeiten

Der Befehl öffnet den vi-Editor, in dem du geplante Tasks hinzufügen, ändern oder entfernen kannst.

Wenn du die crontab noch nie genutzt hast, ist sie möglicherweise leer. Füge eine neue Zeile nach der eben beschriebenen Cron-Syntax hinzu. Jede Zeile muss Zeitplan und Befehl enthalten.

Beispiel: Um ein Skript täglich um 3 Uhr auszuführen, füge diese Zeile ein:

0 3 * * * /path/to/your/command

Speichere und beende den Editor. Cron installiert die neue crontab automatisch und führt die Jobs zum festgelegten Zeitpunkt aus.

Eine einfache Data-Engineering-Aufgabe terminieren

Starten wir praktisch: Wir planen ein Python-Skript, das Daten aus einer API jede Minute abruft. Das Python-Skript verbindet sich mit einem REST-Endpoint, holt Objektdaten und speichert sie als CSV – stelle sicher, dass requests und pandas installiert sind:

# fetch_api_data.py

import requests
import pandas as pd
import os
from datetime import datetime

# Create a timestamp for the filename
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")

# Set file paths - CHANGE THIS
data_dir = "/Users/dradecic/Desktop/cron/data"
output_file = f"{data_dir}/objects_{timestamp}.csv"

# Make sure the data directory exists
os.makedirs(data_dir, exist_ok=True)

# Fetch data from the API
try:
    response = requests.get("https://jsonplaceholder.typicode.com/posts")
    if response.status_code == 200:
        data = response.json()
        
        # Check if we have data
        if data:
            df = pd.DataFrame([
                {
                    "id": row.get("id", ""),
                    "user_id": row.get("userId", ""),
                    "title": row.get("title", ""),
                    "body": row.get("body", "")
                } for row in data
            ])

            df.to_csv(output_file, index=False)
            
            print(f"Data successfully saved to {output_file}")
        else:
            print("API returned empty data")
    else:
        print(f"API request failed with status code: {response.status_code}")
except Exception as e:
    print(f"Error occurred: {str(e)}")

Um das Skript nun per cron jeden Tag um 2 Uhr laufen zu lassen:

* * * * * /Users/dradecic/miniforge3/bin/python /Users/dradecic/Desktop/cron/fetch_api_data.py

Image 2 - Listing active crontabs

Bild 2 – Aktive crontabs auflisten

Diese Zeile startet dein Python-Skript jede Minute – jeden Tag. Verwende unbedingt absolute Pfade – sowohl für den Interpreter (/Users/dradecic/miniforge3/bin/python in meinem Fall) als auch für das Skript (/Users/dradecic/Desktop/cron/fetch_api_data.py).

Warum absolute Pfade? Cron läuft mit einer eingeschränkten Umgebung. Es kennt weder deine PATH-Variable noch dein aktuelles Verzeichnis. Ohne absolute Pfade kann dein Job fehlschlagen, weil cron Befehle oder Dateien nicht findet.

Während du das hier liest, sind ein paar CSV-Dateien in meinem Ordner data gelandet – ein gutes Zeichen, dass der Cronjob wie erwartet läuft:

Image 3 - Saved CSV files

Bild 3 – Gespeicherte CSV-Dateien

ETL-Aufgaben planen

Für komplexere Workflows wie ETL (Extract, Transform, Load) kannst du cron nutzen, um mehrstufige Prozesse zu planen. Häufig packst du alle ETL-Schritte in ein Shellskript und planst dieses mit cron.

Im folgenden .sh-Skript ist der Code der Übersicht halber theoretisch und verbindet sich mit keiner Datenquelle:

#!/bin/bash
# etl_pipeline.sh

# Extract data from source
/usr/bin/psql -U username -d source_db -c "COPY (SELECT * FROM source_table) TO '/tmp/extracted_data.csv' WITH CSV HEADER;"

# Transform data
/usr/bin/python3 /home/username/scripts/transform_data.py

# Load data into target
/usr/bin/psql -U username -d target_db -c "\COPY target_table FROM '/tmp/transformed_data.csv' WITH CSV HEADER;"

# Log completion
echo "ETL job completed at $(date)" >> /home/username/logs/etl_job.log

Als Nächstes machst du das Skript ausführbar:

chmod +x /home/username/scripts/etl_pipeline.sh

Und planst es schließlich, zum Beispiel an Werktagen um 1 Uhr:

0 1 * * 1-5 /home/username/scripts/etl_pipeline.sh

Als Data Engineer profitierst du beim Planen von ETL-Aufgaben mit cron von:

  • Komplexe Workflows bleiben in einem gut lesbaren Skript gebündelt.
  • Fehlerbehandlung und Logging direkt im Skript.
  • Manuelles Testen ist einfach, indem du das Skript direkt ausführst.
  • Die crontab bleibt aufgeräumt und übersichtlich.

Für größere ETL-Prozesse solltest du Fehlerbehandlung ergänzen:

#!/bin/bash
# etl_pipeline.sh

# Set error handling
set -e  # Exit immediately if any command fails

# Execute ETL steps
# ...

# If we get here, all steps succeeded
echo "ETL job completed successfully at $(date)" >> /home/username/logs/etl_job.log

Das war’s! Deine ETL-Pipeline läuft fortan automatisch, verarbeitet Daten und protokolliert den Status fürs Monitoring.

Cronjobs verwalten und überwachen

Sind Cronjobs eingerichtet, musst du sie verwalten und überwachen, damit sie zuverlässig laufen. 

Das heißt: geplante Jobs prüfen, veraltete entfernen und die Ausführung beobachten. In diesem Abschnitt findest du die wichtigsten Befehle und Kniffe für die mühelose Pflege deiner Cronjobs.

Vorhandene Cronjobs anzeigen

Alle aktuell geplanten Cronjobs listest du mit crontab -l auf:

crontab -l

Der Befehl zeigt den Inhalt deiner crontab – also alle Jobs mit Zeitplan und Befehl. Ideal, um schnell zu prüfen, was aktiv ist, ohne in den Editiermodus zu gehen.

So könnte die Ausgabe aussehen, wenn du die Schritte oben befolgt hast:

Image 4 - Active cron jobs

Bild 4 – Aktive Cronjobs

Möchtest du Cronjobs eines anderen Users prüfen (Root-Rechte nötig), nutze:

sudo crontab -u username -l

Cronjobs entfernen oder deaktivieren

Cronjobs kannst du auf mehrere Arten entfernen oder temporär abschalten. Zum Entfernen eines bestimmten Jobs öffnest du die crontab und löschst die Zeile:

crontab -e

Um einen Job vorübergehend zu deaktivieren, kommentierst du die Zeile mit # aus:

Image 5 - Temporarily disabling a cron job

Bild 5 – Cronjob temporär deaktivieren

Der auskommentierte Job bleibt zur Referenz erhalten, wird aber nicht ausgeführt.

Willst du deine komplette crontab löschen (alle Jobs), nutze die Option -r:

crontab -r

Image 6 - Deleting the entire crontab

Bild 6 – Gesamte crontab löschen

Vorsicht – dieser Befehl entfernt alle Jobs ohne Rückfrage. Um versehentliches Löschen zu vermeiden, sichere vorher deine crontab:

crontab -l > my_crontab_backup

So speicherst du die aktuelle crontab in einer Datei, um sie bei Bedarf wiederherzustellen:

crontab my_crontab_backup

Image 7 - Restoring a crontab from a backup

Bild 7 – crontab aus Backup wiederherstellen

Cronjob-Ausgaben überwachen

Standardmäßig versucht cron, Ausgaben per E-Mail an den Besitzer der crontab zu senden. Das setzt jedoch ein konfiguriertes Mailsystem voraus. Stattdessen kannst du Ausgaben in Logdateien umleiten – einfacher zu prüfen und zu debuggen.

Um Standardausgabe und Fehler gemeinsam zu erfassen, nutze diese Umleitung:

* * * * * /Users/dradecic/miniforge3/bin/python /Users/dradecic/Desktop/cron/fetch_api_data.py >> /Users/dradecic/Desktop/cron/logs/api_fetch.log 2>&1

Die Umleitung wirkt auf den ersten Blick komplex, daher kurz erklärt:

  • >> hängt Ausgaben an die angegebene Datei an.
  • 2>&1 leitet stderr (Fehler) an dasselbe Ziel wie stdout (Standardausgabe) weiter.

Image 8 - Capturing cron job logs

Bild 8 – Cronjob-Logs erfassen

Für besseres Log-Management kannst du Zeitstempel ergänzen:

* * * * * /Users/dradecic/miniforge3/bin/python /Users/dradecic/Desktop/cron/fetch_api_data.py >> /Users/dradecic/Desktop/cron/logs/api_fetch.log 2>&1 && echo "Job completed at $(date)" >> /Users/dradecic/Desktop/cron/logs/api_fetch.log

Image 9 - Capturing cron job logs with timestamps

Bild 9 – Cronjob-Logs mit Zeitstempeln

Wenn du separate Logdateien für Output und Fehler willst, nutze:

* * * * * /Users/dradecic/miniforge3/bin/python /Users/dradecic/Desktop/cron/fetch_api_data.py >> /Users/dradecic/Desktop/cron/logs/api_fetch.log 2>> /Users/dradecic/Desktop/cron/logs/api_fetch_errors.log

Image 10 - Cron job log and error files

Bild 10 – Log- und Fehlerdateien für Cronjobs

Für kritische Jobs kannst du E-Mail-Benachrichtigungen einrichten. Vorausgesetzt, ein Mail Transfer Agent (z. B. postfix oder sendmail) ist installiert, kannst du E-Mails nur bei Fehlschlägen senden lassen:

* * * * * /Users/dradecic/miniforge3/bin/python /Users/dradecic/Desktop/cron/fetch_api_data.py >> /Users/dradecic/Desktop/cron/logs/api_fetch.log 2>&1 || echo "API fetch failed on $(date)" | mail -s "Cron Job Failed" your-email@example.com

Hier kommt der Operator || zum Einsatz und bedeutet: „Führe den Mail-Befehl nur aus, wenn der vorherige Befehl fehlschlägt.“

Für Erfolgsmeldungen nutzt du:

* * * * * /Users/dradecic/miniforge3/bin/python /Users/dradecic/Desktop/cron/fetch_api_data.py >> /Users/dradecic/Desktop/cron/logs/api_fetch.log 2>&1 && echo "API fetch completed successfully on $(date)" | mail -s "Cron Job Succeeded" your-email@example.com

Du kannst auch fortgeschrittenes Monitoring einsetzens wie Prometheus mit Node Exporter oder dedizierte Cron-Monitoring-Dienste. Für viele Data-Engineering-Anforderungen reichen jedoch Logging und E-Mail-Benachrichtigungen aus.

Fortgeschrittene Cronjob-Use-Cases im Data Engineering

Du kennst nun die Grundkommandos und Muster fürs Logging. Für Produktionsszenarien lohnt sich ein Blick auf fortgeschrittene Befehle und die Integration mit Containern.

In diesem Abschnitt zeige ich dir, wie du deine Cron-Implementierung für anspruchsvollere Workflows ausbaust.

Cronjobs mit mehreren Befehlen

Du kannst mehrere Befehle in einem Cronjob verketten und so komplexe Workflows ohne separates Shellskript bauen. 

Es gibt verschiedene Möglichkeiten zu kombinieren.

Mit Semikolons führst du Befehle nacheinander aus – unabhängig vom Erfolg vorheriger Befehle:

* * * * * cd /path/to/data && python3 extract.py; python3 transform.py; python3 load.py

Oder du nutzt &&, um nur bei Erfolg des vorherigen Befehls fortzufahren (Stop bei erstem Fehler):

* * * * * cd /path/to/data && python3 extract.py && python3 transform.py && python3 load.py >> /path/to/logs/etl.log 2>&1

Alternativ setzt du || ein, um einen Befehl nur bei Fehlschlag des vorherigen auszuführen (Fehlerbehandlung):

* * * * * python3 /path/to/critical_job.py || python3 /path/to/send_alert.py "Critical job failed"

Für komplexeres Chaining kannst du Befehle mit Klammern gruppieren:

* * * * * (cd /path/to/data && python3 extract.py && echo "Extraction complete") && (python3 transform.py && echo "Transform complete") >> /path/to/logs/etl.log 2>&1

Für sehr umfangreiche Pipelines mit vielen Schritten, Bedingungen oder aufwendiger Fehlerbehandlung ist ein dediziertes Shellskript dennoch die bessere Wahl.

Cronjobs mit Docker

Docker-Container sind aus modernen Data-Engineering-Stacks nicht wegzudenken. Du kannst cron auf mehrere Arten mit Docker kombinieren, um geplante Aufgaben in konsistenten, isolierten Umgebungen laufen zu lassen.

Zur Demo passe ich fetch_api_data.py leicht an: eigene Verzeichnisse für Daten und Logs sowie Pfade, die im Container funktionieren:

# fetch_api_data.py

import requests
import pandas as pd
import os
import uuid
from datetime import datetime

# Set file paths
data_dir = "/app/data"
log_dir = "/app/logs"
output_file = f"{data_dir}/objects_{str(uuid.uuid4())}.csv"

# Make sure the data directory exists
os.makedirs(data_dir, exist_ok=True)
os.makedirs(log_dir, exist_ok=True)


def log_message(message):
    print(f"{datetime.now().isoformat()}: {message}")


# Fetch data from the API
try:
    log_message("Starting API data fetch")
    response = requests.get("https://jsonplaceholder.typicode.com/posts")
    if response.status_code == 200:
        data = response.json()

        # Check if we have data
        if data:
            df = pd.DataFrame(
                [
                    {
                        "id": row.get("id", ""),
                        "user_id": row.get("userId", ""),
                        "title": row.get("title", ""),
                        "body": row.get("body", ""),
                    }
                    for row in data
                ]
            )

            df.to_csv(output_file, index=False)

            log_message(f"Data successfully saved to {output_file}")
        else:
            log_message("API returned empty data")
    else:
        log_message(f"API request failed with status code: {response.status_code}")
except Exception as e:
    log_message(f"Error occurred: {str(e)}")

Damit werden Daten und Logs im Ordner /app/runs gespeichert.

Als Nächstes erstellst du ein Dockerfile – eine Datei, die Docker anweist, wie das Image gebaut und der Container gestartet wird:

FROM python:3.12-slim

# Install cron and required packages
RUN apt-get update && apt-get -y install cron \
    && pip install requests pandas \
    && rm -rf /var/lib/apt/lists/*

# Set up directories
WORKDIR /app
RUN mkdir -p /app/runs/data /app/runs/logs

# Copy our script
COPY fetch_api_data.py /app/

# Make the script executable
RUN chmod +x /app/fetch_api_data.py

# Create the crontab file
RUN echo "* * * * * root /usr/local/bin/python /app/fetch_api_data.py >> /app/runs/logs/api_fetch.log 2>&1" | tee /etc/cron.d/api-cron
RUN chmod 0644 /etc/cron.d/api-cron

# Create a startup script
RUN echo '#!/bin/sh' > /app/start.sh && \
    echo 'mkdir -p /app/runs/logs' >> /app/start.sh && \
    echo 'touch /app/runs/logs/api_fetch.log' >> /app/start.sh && \
    echo 'tail -f /app/runs/logs/api_fetch.log &' >> /app/start.sh && \
    echo 'cron -f' >> /app/start.sh
RUN chmod +x /app/start.sh

# Set entry point
CMD ["/app/start.sh"]

Fast fertig. Mit folgendem Befehl baust du das Image und startest den Container:

docker build --no-cache -t api-cron-job . && \
docker run --rm --name api-fetcher api-cron-job

Verbinde dich mit dem Container und du siehst, dass das Skript minütlich ausgeführt wird:

Image 11 - Cron job running in Docker container

Bild 11 – Cronjob im Docker-Container

Möchtest du hingegen eine Data-Engineering-Pipeline per Docker-Container nach Cron-Zeitplan ausführen, lässt du fetch_api_data.py unverändert und passt nur das Dockerfile an:

# Use Python 3.12 slim as base image
FROM python:3.12-slim

# Install required Python packages
RUN pip install --no-cache-dir requests pandas

# Set working directory
WORKDIR /app

# Copy the script into the container
COPY fetch_api_data.py /app/

# Set execution permissions
RUN chmod +x /app/fetch_api_data.py

# Run the script
CMD ["/usr/local/bin/python", "/app/fetch_api_data.py"]

Dann ergänzt du in der crontab deines Systems Folgendes:

*/2 * * * * cd /path/to/root/project/folder && docker build --no-cache -t api-cron-job . && docker run --rm --name api-fetcher api-cron-job

Damit wird der Build angestoßen und der Container alle 2 Minuten gestartet.

Cronjobs auf Remote-Servern ausführen

In verteilten Workflows müssen Prozesse oft auf Remote-Servern laufen. Cronjobs können diese Remote-Aktionen via SSH anstoßen.

Beispiel: So führst du einen Cronjob auf einem Remote-Server aus:

0 5 * * * ssh username@remote-server 'python3 /path/to/remote_job.py' >> /path/to/logs/remote_job.log 2>&1

Damit das ohne Passwortabfrage funktioniert, richtest du SSH-Authentifizierung mit Schlüsseln zwischen den Servern ein.

Für geplante Datentransfers zwischen Servern nutzt du z. B.:

0 6 * * * scp /path/to/local/data.csv username@remote-server:/path/to/destination/ >> /path/to/logs/data_transfer.log 2>&1

Für komplexere Remote-Abläufe kombinierst du SSH mit Shellskripten:

#!/bin/bash
# remote_etl.sh

# Run extraction on the data source server
ssh username@source-server 'python3 /path/to/extract.py'

# Transfer the extracted data to the processing server
scp username@source-server:/path/to/extracted_data.csv /local/temp/

# Run transformation locally
python3 /path/to/transform.py

# Transfer the transformed data to the warehouse server
scp /local/temp/transformed_data.csv username@warehouse-server:/path/to/data/

# Trigger the load process on the warehouse server
ssh username@warehouse-server 'python3 /path/to/load.py'

Und planst das Skript anschließend per cron:

0 7 * * * /path/to/remote_etl.sh >> /path/to/logs/remote_etl.log 2>&1

So orchestrierst du mehrstufige, serverübergreifende Pipelines direkt mit Cronjobs. Es funktioniert – aber für sehr komplexe verteilte Workflows sind Orchestrierungs tools wie Apache Airflow oder Prefect eine Überlegung wert.

Best Practices für Cronjobs im Data Engineering

Selbst gut gebaute Cronjobs können ohne saubere Betriebspraktiken scheitern oder Probleme verursachen. 

Als Data Engineer sorgst du dafür, dass geplante Tasks zuverlässig laufen, Fehler elegant behandeln und genügend Einblick für die Analyse liefern. So setzt du es um:

Sauberes Logging einrichten

Logging ist für unbeaufsichtigte Prozesse unverzichtbar. Ohne Logs ist die Fehlersuche bei Cronjobs kaum möglich.

Für Basis-Logging leitest du Standardausgabe und Fehler gemeinsam um:

* * * * * /Users/dradecic/miniforge3/bin/python /Users/dradecic/Desktop/cron/fetch_api_data.py >> /Users/dradecic/Desktop/cron/logs/script.log 2>&1

Image 12 - Cron job logging configuration (1)

Bild 12 – Logging-Konfiguration für Cronjobs (1)

Der Befehl führt dein Skript jede Minute aus und hängt die Ausgabe an die Logdatei an. >> hängt an, statt zu überschreiben, und 2>&1 leitet Fehler- und Standardausgabe in dieselbe Datei um.

Für strukturiertere Logs kannst du Zeitstempel und Job-IDs ergänzen:

* * * * * (echo "=== Job started at $(date) ==="; /Users/dradecic/miniforge3/bin/python /Users/dradecic/Desktop/cron/fetch_api_data.py; echo "=== Job finished at $(date) with exit code $? ===") >> /Users/dradecic/Desktop/cron/logs/script.log 2>&1

Image 13 - Cron job logging configuration (2)

Bild 13 – Logging-Konfiguration für Cronjobs (2)

Der Befehl setzt einen Startmarker mit Zeitstempel, führt dein Skript aus und schreibt einen Endmarker mit Zeitstempel und Exit-Code. Die Klammern gruppieren die Befehle, sodass alles gemeinsam in die Logdatei umgeleitet wird. $? enthält den Exit-Code des letzten Befehls (0 = Erfolg, ungleich 0 = Fehler).

Damit Logs nicht zu viel Speicher schlucken, richtest du Logrotation ein. Nutze logrotate, das auf den meisten Linux-Distributionen vorhanden ist:

Erstelle eine Konfigurationsdatei unter /etc/logrotate.d/cron-jobs:

/path/to/logs/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0640 username groupname
}

Diese Konfiguration bewirkt:

  • Tägliche Rotation (daily)
  • Kein Fehler, wenn Logs fehlen (missingok)
  • 14 Versionen aufbewahren (rotate 14)
  • Alte Logs komprimieren (compress)
  • Komprimierung um einen Tag verzögern (delaycompress)
  • Rotation überspringen, wenn leer (notifempty)
  • Neue Dateien mit bestimmten Rechten/Eigentümern anlegen (create 0640 username groupname)

Der Systemdienst logrotate übernimmt das automatisch, meist einmal täglich: umbenennen, ältere komprimieren, sehr alte löschen und neue Logdateien anlegen.

Fehler und Retries handhaben

Robuste Workflows brauchen Strategien für Fehlerfälle. Du kannst Retry-Logik in Skripte integrieren oder Cronjobs mit Monitoring verknüpfen.

Hier sind die Optionen im Überblick – inklusive Beispielcode.

Eingebaute Retry-Logik kannst du direkt in Python umsetzen, z. B. so:

import time
import random

def fetch_data_with_retry(max_attempts=3, backoff_factor=1.5):
    attempt = 1
    while attempt <= max_attempts:
        try:
            # Try to fetch data
            return fetch_data()
        except Exception as e:
            print(f"Attempt {attempt} failed: {str(e)}")
            # Calculate backoff time with jitter
            backoff_time = backoff_factor ** (attempt - 1) * (random.uniform(0.8, 1.2))
            if attempt < max_attempts:
                print(f"Retrying in {backoff_time:.2f} seconds...")
                time.sleep(backoff_time)
            else:
                print("Max retry attempts reached. Giving up.")
                raise
        attempt += 1

Diese Funktion implementiert exponentielles Backoff mit Jitter. Kurz gesagt:

  • Es wird bis zu max_attempts Mal versucht (Standard 3).
  • Bei Fehlern wird eine Wartezeit berechnet und erneut versucht.
  • Die Wartezeit steigt exponentiell (Backoff-Faktor hoch Versuch-1).
  • Zufälliger Jitter (80–120%) verhindert gleichzeitige Lastspitzen.
  • Nach dem letzten Versuch wird der Fehler erneut geworfen.

Ideal bei kurzfristigen Ausfällen wie Netzwerkproblemen oder API-Rate-Limits. Exponentielles Warten gibt dem Fremdsystem Zeit zur Erholung, Jitter verhindert „Herdeneffekte“.

Cron-basierte Retries sind ebenfalls möglich. Du planst den Job einfach häufiger ein als nötig.

Ein Beispiel mit zwei Cronjobs:

  1. Ein Skript läuft alle 10 Minuten. Bei Erfolg wird eine success_flag-Datei erstellt, die einen erneuten Lauf in den nächsten 10 Minuten verhindert.
  2. Um Mitternacht wird die Flag-Datei gelöscht, sodass der erste Job am nächsten Tag wieder laufen kann.
*/10 * * * * [ ! -f /path/to/success_flag ] && python /path/to/script.py && touch /path/to/success_flag
0 0 * * * rm -f /path/to/success_flag 

Zur Erläuterung des ersten Jobs:

  1. Prüft, ob die Flag-Datei existiert ([ ! -f /path/to/success_flag ])
  2. Falls nicht, läuft dein Skript (/path/to/script.py).
  3. Bei Erfolg wird die Flag-Datei angelegt (touch /path/to/success_flag).
  4. Der zweite Job löscht die Flag um Mitternacht (0 0 * * *).

Nützlich für Tasks, die einmal täglich erledigt werden müssen, aber temporär scheitern können. Der Job versucht es über den Tag hinweg, bis er einmal erfolgreich war.

Monitoring-Integration verbindet Cronjobs mit Systemen wie Prometheus. Hier nur ein Überblick.

Das folgende Skript ist ein Wrapper um deinen eigentlichen Job und sendet Metriken an Prometheus. Es:

  1. notiert die Startzeit,
  2. führt deinen Job aus,
  3. erfasst den Exit-Code,
  4. berechnet die Dauer,
  5. schiebt drei Metriken (Dauer, Exit-Code, Zeitpunkt) zur Pushgateway,
  6. und beendet sich mit demselben Exit-Code wie der Job.
#!/bin/bash
# monitored_job.sh

# Define pushgateway URL
PUSHGATEWAY="http://prometheus-pushgateway:9091"

# Start time in seconds
START_TIME=$(date +%s)

# Run the actual job
/path/to/actual_job.sh
EXIT_CODE=$?

# End time in seconds
END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))

# Push metrics to Prometheus
cat <<EOF | curl --data-binary @- ${PUSHGATEWAY}/metrics/job/cron_job/instance/$(hostname)
# HELP cron_job_duration_seconds How long the cron job took to execute
# TYPE cron_job_duration_seconds gauge
cron_job_duration_seconds{name="data_extraction"} ${DURATION}

# HELP cron_job_exit_code Exit code of the cron job
# TYPE cron_job_exit_code gauge
cron_job_exit_code{name="data_extraction"} ${EXIT_CODE}

# HELP cron_job_last_run_timestamp Timestamp of last job run
# TYPE cron_job_last_run_timestamp gauge
cron_job_last_run_timestamp{name="data_extraction"} ${END_TIME}
EOF

exit ${EXIT_CODE}

Diese Metriken ermöglichen dir:

  • Alerts bei Fehlschlägen (Exit-Code ≠ 0).
  • Laufzeittrends beobachten und Performance-Probleme erkennen.
  • Ausführungen verifizieren und den letzten erfolgreichen Lauf nachhalten.
  • Dashboards zum Zustand aller geplanten Jobs aufbauen.

Die Pushgateway fungiert als Zwischenstation: Kurzlebige Cronjobs pushen Metriken dorthin, Prometheus holt sie ab und speichert sie für Alarme und Visualisierung.

Zeitzonen beachten

Zeitzonen sind im Data Engineering oft knifflig – besonders mit globalen Datenquellen oder verteilten Systemen. 

Wie zu erwarten, reagieren Cronjobs sensibel auf Zeitzoneneinstellungen.

Standardmäßig nutzt cron die lokale Systemzeitzone. Mit diesem Linux-Befehl prüfst du sie:

timedatectl

Er zeigt aktuelle Uhrzeit und Zeitzone. Ist der Server z. B. auf America/New_York eingestellt, interpretiert cron alle Zeitangaben in dieser Zeitzone.

Für konsistente Zeitpläne – unabhängig vom Serverstandort oder Sommerzeit – nutze UTC:

# Set the CRON_TZ environment variable at the top of your crontab
CRON_TZ=UTC

# Now all job schedules will use UTC
0 0 * * * /path/to/daily_job.sh

Mit CRON_TZ=UTC weist du cron an, alle Zeitangaben als UTC zu interpretieren. 

So läuft der Job täglich um Mitternacht UTC – unabhängig von lokaler Zeitzone oder Sommerzeit. UTC ändert sich nie, ist also der verlässliche Referenzpunkt.

Fazit: Cronjobs für Data Engineers

Für Data Engineers sind Cronjobs ein unverzichtbares Werkzeug.

Sie automatisieren Routineaufgaben und helfen dir, stabile Datenpipelines zu bauen. Mit cron planst du Skripte zuverlässig und orchestrierst mehrstufige ETL-Prozesse. Die Syntax wirkt am Anfang ungewohnt, geht aber schnell in Fleisch und Blut über.

Wichtig ist, dass du bei der Umsetzung Best Practices für Logging, Fehlerbehandlung und Zeitzonen beachtest. Gutes Logging schafft Transparenz und erleichtert die Analyse. Solide Fehlerbehandlung mit Retries macht deine Pipelines fehlertolerant. Sorgfältige Zeitzonensteuerung hält Zeitpläne konsistent – besonders bei globalen Datenquellen oder verteilten Teams.

>Du willst 2025 als Data Engineer durchstarten? Diese 5 Kompetenzen brauchst du unbedingt.

Klar, spezialisierte Orchestrierungstools wie Apache Airflow oder Prefect bieten für komplexe Pipelines mehr Features, aber cron bleibt für viele Aufgaben relevant: einfach, zuverlässig und ressourcenschonend – ideal für Automatisierung.

Wenn du mehr über Data Engineering lernen willst, melde dich für diese DataCamp-Kurse an:

Lass dich für deine Traumrolle als Data Engineer zertifizieren

Unsere Zertifizierungsprogramme helfen dir, dich von anderen abzuheben und potenziellen Arbeitgebern zu beweisen, dass deine Fähigkeiten für den Job geeignet sind.

Hol Dir Deine Zertifizierung
Timeline mobile.png

FAQs

Was ist ein Cronjob und warum ist er für Data Engineers nützlich?

Ein Cronjob ist ein zeitbasierter Scheduler in Unix-Betriebssystemen, der Befehle automatisch zu festgelegten Zeiten, an bestimmten Tagen oder in Intervallen ausführt. Für Data Engineers sind Cronjobs besonders nützlich, weil sie wiederkehrende Aufgaben wie Datenextraktion, Datenbank-Backups, Reportgenerierung und ETL-Workflows automatisieren – das sorgt für Konsistenz und Zuverlässigkeit und reduziert manuellen Aufwand.

Wie lege ich fest, wann ein Cronjob laufen soll?

Cronjobs verwenden eine Syntax mit fünf Zeitfeldern: Minute (0–59), Stunde (0–23), Tag im Monat (1–31), Monat (1–12) und Wochentag (0–6, wobei 0 Sonntag ist). Du kannst konkrete Werte, Bereiche (1–5), Listen (1,3,5) oder Sterne (*) für „jede“ Einheit nutzen. Beispiel: 0 2 * * * führt einen Job täglich um 2:00 Uhr aus.

Welche Best Practices gibt es für das Logging von Cronjobs?

Best Practices fürs Logging umfassen: Umleitung von Standardausgabe und Fehlern in Logdateien via >> und 2>&1, Zeitstempel hinzufügen, Logrotation einrichten, um Speicher zu sparen, und Logs so strukturieren, dass die Fehlersuche leicht fällt. Für kritische Jobs sind E-Mail-Benachrichtigungen bei Fehlschlägen sinnvoll.

Wie gehe ich bei Cronjobs mit Fehlern und Retries um?

Fehler kannst du auf mehreren Wegen handhaben: Retry-Logik direkt in Skripten (z. B. exponentielles Backoff), cron-seitige Retries mithilfe von Erfolgs-Flags, Integration mit Monitoring (z. B. Prometheus) zur Statusüberwachung oder ein „Dead Letter“-Muster, das fehlgeschlagene Inputs zur Analyse bewahrt.

Wie funktionieren Docker-Container zusammen mit Cronjobs?

Docker-Container lassen sich auf zwei Arten mit Cronjobs kombinieren: Entweder läuft cron im Container zusammen mit deiner Anwendung (praktisch, um Zeitpläne inkl. Umgebung zu paketieren), oder die Cronplanung erfolgt auf dem Host und startet Container zu bestimmten Zeiten. Beides sorgt für Konsistenz und Isolation und macht geplante Tasks portabel und wartbar.


Dario Radečić's photo
Author
Dario Radečić
LinkedIn
Senior Data Scientist mit Sitz in Kroatien. Top Tech Writer mit über 700 veröffentlichten Artikeln, die mehr als 10 Millionen Mal aufgerufen wurden. Buchautor von Machine Learning Automation with TPOT.
Themen
Datentechnik

Vertiefe dein Wissen im Data Engineering mit diesen Kursen!

Kurs

Einführung in Apache Airflow mit Python

4 Std.
65.3K
Dieser Kurs zeigt dir, wie du Data-Engineering-Workflows implementierst und planst.
Details anzeigenKurs Starten

Erstelle dein kostenloses Konto

Üben und Lernpfad deinen Fortschritt.

Weiter Mit Google
Durch Klick auf die Schaltfläche akzeptierst du unsere Nutzungsbedingungen, unsere Datenschutzrichtlinie und die Speicherung deiner Daten in den USA.
Mehr anzeigen
Ähnlich

Blog

Die 20 besten Snowflake-Interview-Fragen für alle Niveaus

Bist du gerade auf der Suche nach einem Job, der Snowflake nutzt? Bereite dich mit diesen 20 besten Snowflake-Interview-Fragen vor, damit du den Job bekommst!
Nisha Arya Ahmed's photo

Nisha Arya Ahmed

15 Min.

Blog

Lehrer/innen und Schüler/innen erhalten das Premium DataCamp kostenlos für ihre gesamte akademische Laufbahn

Keine Hacks, keine Tricks. Schüler/innen und Lehrer/innen, lest weiter, um zu erfahren, wie ihr die Datenerziehung, die euch zusteht, kostenlos bekommen könnt.
Nathaniel Taylor-Leach's photo

Nathaniel Taylor-Leach

4 Min.

Tutorial

Python Datenstrukturen Tutorial

Mach dich mit Python-Datenstrukturen vertraut: Lerne mehr über Datentypen und primitive sowie nicht-primitive Datenstrukturen wie Strings, Listen, Stapel usw.
Sejal Jaiswal's photo

Sejal Jaiswal

24 Min.

Tutorial

Loop-Schleifen in Python-Tutorial

Lerne, wie du For-Schleifen in Python umsetzt, um eine Sequenz oder die Zeilen und Spalten eines Pandas-DataFrame zu durchlaufen.
Aditya Sharma's photo

Aditya Sharma

5 Min.

Tutorial

Python Switch Case Statement: Ein Leitfaden für Anfänger

Erforsche Pythons match-case: eine Anleitung zu seiner Syntax, Anwendungen in Data Science und ML sowie eine vergleichende Analyse mit dem traditionellen switch-case.
Matt Crabtree's photo

Matt Crabtree

5 Min.

Tutorial

30 coole Python-Tricks für besseren Code mit Beispielen

Wir haben 30 coole Python-Tricks zusammengestellt, mit denen du deinen Code verbesserst und deine Python-Kompetenzen ausbaust.
Kurtis Pykes 's photo

Kurtis Pykes

15 Min.

Mehr anzeigen