基本上我的 cron 每 2 分钟更新一次数据库。但我需要运行另一个每 24 小时更新一次数据库的 cron。我需要确保在第二个 cron(每天)运行时没有竞争条件,即两个 cron 不能一起运行并重叠。这需要在 Kubernetes 集群中使用作业来实现。
我的解决方案是每 2 分钟运行一次第一个 cron,但在第二个 cron 运行时(每天)延迟 5 分钟。
欢迎任何替代解决方案。
1 回答
我试图考虑一些可能性,但事情可能会出错,主要是因为你有一份工作需要每 2 分钟运行一次,让我们假设你的日常工作出于任何原因花费的时间比你预期的要多,一份新的 2 分钟工作将开始,这不可能发生。
最好的解决方案是在代码级别解决这个问题。您可以在应用程序中创建一个锁,以防止这些作业同时运行。
如果您真的无法在代码中提出任何解决方案来解决此问题,那么 Kubernetes 上有一种机制可以阻止来自同一个 cronjob 的新作业启动。您可以设置标志spec.concurrencyPolicy: Forbid因此如果您的作业启动时间超过 2 分钟,则将跳过新作业。这不是全局标志,这仅适用于每个 cronjob。
您可以使用spec.initContainers聚合这种可能性,并找到一种方法在同一个 cronjob 中运行这两个任务。
spec.initContainers 是在应用容器之前运行的专用容器。
这是一个例子:
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
concurrencyPolicy: Forbid
schedule: "*/2 * * * *"
jobTemplate:
spec:
template:
spec:
initContainers
- name: hello1
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
containers:
- name: hello2
image: busybox
args:
- /bin/sh
- -c
- DATE=`date +"%H:%M"`; if [[ $DATE == "00:00" ]]; then date; echo Hello from the Kubernetes cluster; fi
restartPolicy: OnFailure
此清单定义了一个 cronJob,它将每 2 分钟运行一次,并将启动一个 initContainer(您的 2 分钟作业),并且还将每 2 分钟运行第二个容器。问题是在第二个容器中,我们有一个 shell 脚本检查它是否是午夜(忽略秒,因为我们不能确定它什么时候开始)。
您可能需要调整这部分代码:
DATE=`date +"%H:%M"; if [[ $DATE == "00:00" ]
假设您的第一个容器执行时间超过一分钟,它将是 00:01,您的第二个作业将永远不会执行。
让我知道这些信息和解决方案是否对您有所帮助。