Der Ausdruck */30 * * * *
*/30 * * * * löst in Minute 0 und Minute 30 jeder Stunde aus, insgesamt 2 Läufe pro Stunde, 48 pro Tag. Der Schritt */30 beginnt bei 0 (dem Minimum des Minutenfeldes) und erhöht sich um 30, was genau zwei Werte ergibt: 0 und 30.
Der Zeitplan ist so einfach wie es nur geht: zur vollen und zur halben Stunde, jede Stunde, den ganzen Tag. Es gibt keine Unklarheit darüber, welche Minuten ausgewählt sind, und keine Grenzfälle bezüglich Feldbereichen.
*/30 vs 0,30: Welche verwenden
Beide Ausdrücke erzeugen denselben Zeitplan. Die Wahl betrifft die Kommunikation der Absicht:
*/30 * * * * # "alle 30 Minuten"
0,30 * * * * # "in Minute 0 und Minute 30"
Die explizite 0,30 Form ist argumentativ defensiver. Sie lässt keinen Raum für Fehlinterpretationen. Ein Entwickler, der mit der Schrittsyntax nicht vertraut ist, kann 0,30 * * * * * auf den ersten Blick richtig lesen. */30 erfordert das Wissen, dass der Schritt bei 0 im Minutenfeld beginnt.
In Codekommentaren oder Runbooks, in denen das Publikum auch Nicht-Cron Experten umfasst, ist 0,30 die sicherere Wahl. In einem Team von Ingenieuren, die mit der Cron Syntax vertraut sind, ist */30 in Ordnung und das, wonach die meisten greifen.
Anwendungsfälle für halbstündliche Zeitpläne
Digest E-Mails und Benachrichtigungen
Viele Benachrichtigungssysteme bündeln Updates und senden Zusammenfassungen in einem halbstündlichen Rhythmus. Ein 30 Minuten Fenster ist lang genug, um sinnvolle Inhalte zu sammeln, aber kurz genug, dass sich Benutzer nicht abgehängt fühlen. Zweimal stündliche Digests sind ein gängiger Standard in Alarmierungs- und Newsletter Plattformen.
Berichterstellung
Dashboards, die “letzte 30 Minuten” Metriken anzeigen, passen sich natürlich an einen halbstündlichen Erstellungszeitplan an. Die Ausführung des Berichts um :00 und :30 bedeutet, dass die Daten höchstens 30 Minuten veraltet sind, was für die meisten internen Berichte akzeptabel ist.
Datensynchronisation mit moderater Aktualisierungshäufigkeit
Wenn ein Quellsystem alle 15 bis 20 Minuten aktualisiert wird, bedeutet ein 30 Minuten Sync, dass du höchstens einen Update Zyklus zurückliegst. Dies ist oft der richtige Kompromiss, wenn der Sync einen nicht trivialen Datenbankschreibvorgang oder Dateitransfer beinhaltet.
Caching und Index Refresh
Für Suchindizes oder materialisierte Ansichten, deren Neuerstellung teuer ist, begrenzt der zweimal stündliche Refresh den Schaden eines langsamen Rebuilds, während die Inhalte einigermaßen aktuell bleiben.
Die Phase verschieben
Der Standard */30 löst immer um :00 und :30 aus. Wenn du den halbstündlichen Job von der vollen Stunde versetzen möchtest, verwende einen expliziten Start:
15,45 * * * * # löst um :15 und :45 aus
Dies ist äquivalent zu 15/30 * * * *, aber 15,45 ist lesbarer.
Phasenverschobene Zeitpläne sind nützlich, wenn du mehrere halbstündliche Jobs hast und die Last verteilen möchtest:
0,30 * * * * /opt/jobs/report-generator
15,45 * * * * /opt/jobs/data-sync
7,37 * * * * /opt/jobs/cache-warmer
Diese drei Jobs sind jetzt gleichmäßig über das 30 Minuten Fenster verteilt. Keine zwei lösen zur selben Minute aus.
Vergleich mit @hourly
@hourly (expandiert zu 0 * * * *) löst 24 Mal pro Tag aus. */30 * * * * löst 48 Mal pro Tag aus, genau doppelt so oft.
Die Wahl zwischen stündlich und halbstündlich hängt von deinem akzeptablen Veralterungsfenster ab. Wenn der Job einen Cache verwaltet und sich die zugrunde liegenden Daten schneller als jede Stunde ändern, hält der halbstündliche Rhythmus den Cache frischer. Wenn sich die Daten höchstens einmal pro Stunde ändern, ist @hourly ausreichend und erzeugt halb so viel Last.
Keines ist immer richtig. Miss, wie oft sich deine Datenquelle tatsächlich ändert, bevor du das Intervall wählst.
Den Job ausführen vs @hourly: Seite an Seite
0 * * * * # @hourly: 00:00, 01:00, 02:00 ... (24/Tag)
0,30 * * * * # zweimal stündlich: 00:00, 00:30, 01:00, 01:30 ... (48/Tag)
Wenn du von stündlich auf halbstündlich umstellst, überprüfe, ob der Job idempotent oder für die doppelt so häufige Ausführung ausgelegt ist. Manche Jobs (wie das Senden einer Zusammenfassungs E-Mail) sollten nur einmal pro Auslöser feuern, und die zweimalige Ausführung pro Stunde würde die E-Mails verdoppeln. Andere (wie ein Cache Refresh) können problemlos häufiger ausgeführt werden.
Den Zeitplan überprüfen
from croniter import croniter
from datetime import datetime
cron = croniter("*/30 * * * *", datetime.now())
for _ in range(6):
print(cron.get_next(datetime))
Dies gibt die nächsten 6 Ausführungszeiten aus, die drei Stunden Daten abdecken und das :00/:30 Muster deutlich zeigen. Vergleiche es mit 15,45 * * * *, um zu sehen, wie sich eine Phasenverschiebung auf die Ausgabe auswirkt.
Um zu bestätigen, dass der Job auf einem Live System läuft:
journalctl -u cron --since "3 hours ago" | grep myjob | wc -l
Über 3 Stunden solltest du genau 6 Einträge sehen. Weniger deutet darauf hin, dass der Job fehlschlägt oder ohne Ausgabe beendet wird; mehr deutet auf doppelte Einträge in der crontab hin.