首页 > 解决方案 > 如何设置 CRON 作业限制以匹配用户?

问题描述

我有一个运行大约 70 个 python 应用程序实例的 bash shell 脚本。每个 python 实例都运行 TensorFlow 2.0,它每小时唤醒一次并做一些工作。bash shell 脚本在用户 shell 中运行良好,但在 cron 中运行时,在作业的第 36 个实例之后核心转储。

我设置了 shell 脚本来完全限定路径,并验证了两个实例中的环境是相同的。

这在 AWS 上运行 Ubuntu 的 36 核机器上运行:#56-Ubuntu SMP Thu Nov 7 16:15:59 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

cron 可以运行的“任务”数量似乎有一些限制。

是否有更改 cron 中允许的任务数的设置?

这是 crontab 条目:

*/5 * * * * /myscripts/watchdog.sh >> /myscripts/watchdog.log 2>&1

因此,它每 5 分钟运行一次,检查正在运行的进程。如果它们没有运行,那么它会启动它们。

#!/bin/bash
# https://serverfault.com/questions/710847/how-to-apply-memory-limits-to-all-cron-jobs

# checking the cron ulimit
#      systemctl status cron

# more /etc/pam.d/cron
# talking about /etc/security/limits.conf
export PATH=/runner/venv/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
/bin/echo "##################### watchdog.sh running now #####################"
/bin/date
export LANG=C.UTF-8
export USER=ubuntu
export HOME=/home/ubuntu
export MAIL=/var/mail/ubuntu
export SHELL=/bin/bash
export LOGNAME=ubuntu

# https://unix.stackexchange.com/questions/162104/how-to-change-the-kernel-max-pid-number
# pid_max is 4194304 for 64 bit
if grep -q 56000 /proc/sys/kernel/pid_max; then
  /bin/echo "/proc/sys/kernel/pid_max = 56000"
else
  /bin/echo 56000 | sudo tee /proc/sys/kernel/pid_max
fi
# https://www.kernel.org/doc/Documentation/cgroup-v1/pids.txt
if grep -q 48000 /sys/fs/cgroup/pids/user.slice/user-1000.slice/pids.max; then
  /bin/echo "/sys/fs/cgroup/pids/user.slice/user-1000.slice/pids.max = 48000"
else
  /bin/echo 48000 | /usr/bin/sudo tee /sys/fs/cgroup/pids/user.slice/user-1000.slice/pids.max
fi
export DEPLOY_ENV="system_one"
export VIRTUAL_ENV="/runner/venv"
hash -r
# see https://stackoverflow.com/questions/51256738/multiple-instances-of-python-running-simultaneously-limited-to-35
#export OPENBLAS_NUM_THREADS=1
#export OMP_NUM_THREADS=1
export AEP="/runner/analyzerengine"
export PID_FILE_DIR="/runner/pids"
export OUT_FILE_DIR="/runner/out"

while read producer; do
    producer="$(/bin/echo $producer| /bin/sed 's/\r//g')"
    export PIDFILE="${PID_FILE_DIR}/${producer}.pid"
    /bin/echo "Checking producer=$producer in file $PIDFILE"
    if [ -e "${PIDFILE}" ] && [ "$(/bin/ps -o pid= -p "$(/bin/sed 's/ //g' < "${PIDFILE}")")" ] ; then
        /bin/echo "${producer} process PID check OK (running) on $(/bin/date) ."
    else
        /bin/echo "Restarting ${producer} process on $(/bin/date)..."
        /bin/echo "executing: ${VIRTUAL_ENV}/bin/python ${AEP}/runnerCode.py --producer=${producer} --deployment=${DEPLOY_ENV} &>  ${OUT_FILE_DIR}/${producer}.log &"
        ${VIRTUAL_ENV}/bin/python ${AEP}/runnerCode.py --producer=${producer} --deployment=${DEPLOY_ENV} >  ${OUT_FILE_DIR}/${producer}.log &
        /bin/echo $! > "${PIDFILE}"
        /bin/chmod 644 ${OUT_FILE_DIR}/${producer}.log
        /bin/chmod 644 "${PIDFILE}"
        /bin/echo "...done."
    fi
done < ${AEP}/producer_list.txt

运行命令:$ systemctl status cron

产生以下输出:

cron.service - Regular background program processing daemon
   Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled)
   Active: active (running) since Sun 2019-11-24 16:59:41 UTC; 2 days ago
     Docs: man:cron(8)
 Main PID: 1191 (cron)
    Tasks: 5391 (limit: 5529)
   CGroup: /system.slice/cron.service
           ├─ 1191 /usr/sbin/cron -f
           ├─40750 /runner/venv/bin/python /runner/analyzerengine/runnerCode.py --producter=customer_A --deployment=system_one
           ├─40791 /runner/venv/bin/python -c from multiprocessing.semaphore_tracker import main;main(3)
     ...

只有 36 个进程将从这个脚本开始。当我以用户 (username=ubuntu) 身份运行此脚本时,我可以毫无问题地启动所有 70 个进程。显然,某些地方设置不正确。

由于 runnerCode.py 的每个实例都会产生几百个线程(TensorFlow 内置的东西我无法控制),我需要将 /proc/sys/kernel/pid_max 设置为 56000 和 /sys/fs/cgroup/pids/user .slice/user-1000.slice/pids.max 到 48000。

systemctl 中是否有一些设置需要更改才能使更多进程运行?

提前致谢!

标签: pythontensorflowcronmulticorecron-task

解决方案


事实证明,我还需要为 eth cron 作业设置 pid 限制。这可以按如下方式完成:

/bin/echo 48000 | /usr/bin/sudo tee /sys/fs/cgroup/pids/system.slice/cron.service/pids.max

这会将 cron 服务的控制组设置为具有 48000 个限制,以便不会达到此配置的线程限制。


推荐阅读