why the celery worker take so much memory useage - python-3.x

Now I am using celery 5.1.2 and Python 3.9 to run some task concurrency, this is my start script:
export LC_ALL=en_US.utf-8 \
&& export LANG=en_US.utf-8 \
&& nohup celery -A dolphin.tasks.tasks worker \
--loglevel=INFO -n worker2 -Q non_editor_pick_and_diff_pull --concurrency 2 > /dev/null &
export LC_ALL=en_US.utf-8 \
&& export LANG=en_US.utf-8 \
&& nohup celery -A dolphin.tasks.tasks worker \
--loglevel=INFO -n worker3 -Q non_editor_pick_and_non_diff_pull --concurrency 3 > /dev/null &
to my surprise, the celery worker take 100MB+ for each worker, why the celery take so much RAM memory? Is it possible to make the memory lower,10MB or less? I just run a function in the celery task, really need 100MB? This is the top command output:
24073 root 25 5 677220 139988 4456 S 0.0 7.4 22:14.10 /usr/bin/python3 /usr/local/bin/celery -A dolphin.tasks.tasks worker --loglevel=INFO -n worker2 -Q non_editor_pick_and_diff_pull --concurrency 2
24076 root 25 5 677024 139744 4412 S 0.0 7.4 22:11.04 /usr/bin/python3 /usr/local/bin/celery -A dolphin.tasks.tasks worker --loglevel=INFO -n worker2 -Q non_editor_pick_and_diff_pull --concurrency 2
24078 root 25 5 676848 134760 3848 S 0.0 7.2 93:01.93 /usr/bin/python3 /usr/local/bin/celery -A dolphin.tasks.tasks worker --loglevel=INFO -n worker3 -Q non_editor_pick_and_non_diff_pull --concurrency 3
24072 root 25 5 675332 133964 4560 S 7.3 7.1 173:10.84 /usr/bin/python3 /usr/local/bin/celery -A dolphin.tasks.tasks worker --loglevel=INFO -n worker3 -Q non_editor_pick_and_non_diff_pull --concurrency 3
24075 root 25 5 670876 128804 3860 S 0.0 6.8 129:24.36 /usr/bin/python3 /usr/local/bin/celery -A dolphin.tasks.tasks worker --loglevel=INFO -n worker3 -Q non_editor_pick_and_non_diff_pull --concurrency 3
24071 root 25 5 655128 123692 4132 S 0.0 6.6 13:17.96 /usr/bin/python3 /usr/local/bin/celery -A dolphin.tasks.tasks worker --loglevel=INFO -n worker1 -Q editor_pick_and_diff_pull --concurrency 2
24074 root 25 5 646624 120068 4272 S 0.0 6.4 13:04.01 /usr/bin/python3 /usr/local/bin/celery -A dolphin.tasks.tasks worker --loglevel=INFO -n worker1 -Q editor_pick_and_diff_pull --concurrency 2
24000 root 25 5 624856 98748 2728 S 0.0 5.2 9:41.82 /usr/bin/python3 /usr/local/bin/celery -A dolphin.tasks.tasks worker --loglevel=INFO -n worker1 -Q editor_pick_and_diff_pull --concurrency 2
24001 root 25 5 624868 98724 2716 S 0.0 5.2 12:43.68 /usr/bin/python3 /usr/local/bin/celery -A dolphin.tasks.tasks worker --loglevel=INFO -n worker2 -Q non_editor_pick_and_diff_pull --concurrency 2
24002 root 25 5 624840 98708 2676 S 1.3 5.2 44:47.66 /usr/bin/python3 /usr/local/bin/celery -A dolphin.tasks.tasks worker --loglevel=INFO -n worker3 -Q non_editor_pick_and_non_diff_pull --concurrency 3
24005 root 25 5 624696 98060 2412 S 0.0 5.2 7:59.62 /usr/bin/python3 /usr/local/bin/celery -A dolphin.tasks.tasks worker --loglevel=INFO -n worker4 -Q cert_expire_check --concurrency 1

Related

How to create alias command to stop celery

Following this solution from another post I've made an alias in my .zshrc (I use ohmyzsh) to stop my celery workers:
alias stopcelery="ps auxww | grep 'celery' | awk '{print $2}' | xargs kill -9"
However when I have running celery workers, using this command fails:
➜ stopcelery
kill: invalid argument
Usage:
kill [options] <pid> [...]
Options:
<pid> [...] send signal to every <pid> listed
-<signal>, -s, --signal <signal>
specify the <signal> to be sent
-l, --list=[<signal>] list all signal names, or convert one to a name
-L, --table list all signal names in a nice table
-h, --help display this help and exit
-V, --version output version information and exit
For more details see kill(1).
The workers are still running:
➜ ps auxww | grep 'celery'
myuser 49126 67.0 0.5 189132 92280 ? S 15:59 0:02 /home/myuser/.local/share/virtualenvs/myproject-JLNbaOhA/bin/python -m celery worker -A wsgi.celery --loglevel=INFO --logfile=/tmp/celery.log --pidfile=celeryd.pid
myuser 49304 0.0 0.5 188160 85060 ? S 15:59 0:00 /home/myuser/.local/share/virtualenvs/myproject-JLNbaOhA/bin/python -m celery worker -A wsgi.celery --loglevel=INFO --logfile=/tmp/celery.log --pidfile=celeryd.pid
myuser 49305 0.0 0.5 188164 84844 ? S 15:59 0:00 /home/myuser/.local/share/virtualenvs/myproject-JLNbaOhA/bin/python -m celery worker -A wsgi.celery --loglevel=INFO --logfile=/tmp/celery.log --pidfile=celeryd.pid
myuser 49306 0.0 0.5 188168 84848 ? S 15:59 0:00 /home/myuser/.local/share/virtualenvs/myproject-JLNbaOhA/bin/python -m celery worker -A wsgi.celery --loglevel=INFO --logfile=/tmp/celery.log --pidfile=celeryd.pid
myuser 49307 0.0 0.5 188172 84844 ? S 15:59 0:00 /home/myuser/.local/share/virtualenvs/myproject-JLNbaOhA/bin/python -m celery worker -A wsgi.celery --loglevel=INFO --logfile=/tmp/celery.log --pidfile=celeryd.pid
myuser 49312 0.0 0.0 20556 2924 pts/8 S+ 15:59 0:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox celery
But using the actual command it works:
➜ ps auxww | grep 'celery' | awk '{print $2}' | xargs kill -9
kill: (48078): No such process
Indeed, checking again:
➜ ps auxww | grep 'celery'
myuser 49782 0.0 0.0 20556 664 pts/8 S+ 16:03 0:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox celery
So what is the difference, why using the alias does not having the same effect?
As #Philippe has pointed out, I forgot to escape the $ sign as I was using double quotes.

why defunct process generate when call exec in shell script?

why defunct process generate when call exec in shell script?
Because some extra configure and sharelib should be set and preload before starting snmpd,
so I use shell script like bellow, but the problem is that a zombie process was generated every time when start the shell script.
as far as I know, exec will replace the original shell process 26452, why a child process 26453 generate and become zombie?
$# ps -ef | grep snmpd
root 26452 12652 0 10:24 pts/4 00:00:00 snmpd udp:161,udp6:161 -f -Ln -I -system_mib ifTable -c /opt/snmp/config/snmpd.conf
root 26453 26452 0 10:24 pts/4 00:00:00 [snmpd_wapper.sh] <defunct>
how to avoid the zombie process, pls help!
cat /home/xpeng/snmpd_wapper.sh
#!/bin/bash
( sleep 2;/opt/snmp/bin/snmpusm -v 3 -u myuser -l authNoPriv -a MD5 -A xpeng localhost create top myuser >/dev/null 2>&1; \
/opt/snmp/bin/snmpvacm -v 3 -u myuser -l authNoPriv -a MD5 -A xpeng localhost createSec2Group 3 top RWGroup >/dev/null 2>&1; \
/opt/snmp/bin/snmpvacm -v 3 -u myuser -l authNoPriv -a MD5 -A xpeng localhost createView all .1 80 >/dev/null 2>&1; \
/opt/snmp/bin/snmpvacm -v 3 -u myuser -l authNoPriv -a MD5 -A xpeng localhost createAccess RWGroup 3 1 1 all all none >/dev/null 2>&1 ) &
LIBRT=/usr/lib64
if [ "$(. /etc/os-release; echo $NAME)" = "Ubuntu" ]; then
LIBRT=/usr/lib/x86_64-linux-gnu
fi
echo $$>/tmp/snmpd.pid
export LD_PRELOAD=$LD_PRELOAD:$LIBRT/librt.so:/opt/xpeng/lib/libxpengsnmp.so
exec -a "snmpd" /opt/snmp/sbin/snmpd udp:161,udp6:161 -f -Ln -I -system_mib,ifTable -c /opt/snmp/config/snmpd.conf
It's a parent process' responsibility to wait for any child processes. The child process will be a zombie from the time it dies until the parent waits for it.
You started a child process, but then you used exec to replace the parent process. The new program doesn't know that it has children, so it doesn't wait. The child therefore becomes a zombie until the parent process dies.
Here's a MCVE:
#!/bin/sh
sleep 1 & # This process will become a zombie
exec sleep 30 # Because this executable won't `wait`
You can instead do a double fork:
#!/bin/sh
( # Start a child shell
sleep 1 & # Start a grandchild process
) # Child shell dies, grandchild is given to `init`
exec sleep 30 # This process now has no direct children

How can I stop a gunicorn process on a server

On my website I have this message "Internal Server Error". How can I kill a process in linux. so that I can run the proccess manually /usr/bin/gunicorn --workers 3 flaskodesiapp:create_app
root#localhost:/flask_app_project# ps -A | grep gunicorn
13210 ? 00:00:00 gunicorn3
13212 ? 00:00:00 gunicorn3
13215 ? 00:00:00 gunicorn3
13216 ? 00:00:00 gunicorn3
root#localhost:/flask_app_project# sudo killall gunicorn3
root#localhost:/flask_app_project# ps -A | grep gunicorn
13232 ? 00:00:00 gunicorn3
13234 ? 00:00:00 gunicorn3
13235 ? 00:00:00 gunicorn3
13236 ? 00:00:00 gunicorn3
/etc/systemd/system/gunicorn.service
[Service]
User=root
Group=root
WorkingDirectory=/flask_app_project
Restart=on-failure
ExecStart= /usr/bin/gunicorn --workers 3 flaskodesiapp:create_app
[Install]
WantedBy=multi-user.target
supervisord /etc/supervisor/conf.d/flask_app.conf
[program:flask_app]
directory=/flask_app_project
command=gunicorn3 --workers=3 flaskodesiapp:create_app
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
stderr_logfile=/var/log/flask_app/flask_app.err.log
stdout_logfile=/var/log/flask_app/flask_app.out.log
I had to stop supversisord first
ps -ef | grep supervisord
root 12836 1 0 01:38 ? 00:00:00 /usr/bin/python3 /usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf
root 13310 13127 0 02:13 pts/0 00:00:00 grep --color=auto supervisord
kill -s SIGTERM 12836
ps -ef | grep supervisord
root 13325 13127 0 02:14 pts/0 00:00:00 grep --color=auto supervisord
sudo killall gunicorn3

Give variable or name to process to kill not every process by this instance, but only with given name(variable)?

I have many processes by one program ( in this case node.js processes) running. Some times i need to run several ( for example 10 nodejs processes) , i start them with Makefile. I want to be able with some bash command within my Makefile to turn off those 10 process when needed, but i dont want to kill other node.js running processes. So i can use pkill node but it will kill every node processes, how can i give some name or some variable for this 10 processes, to kill only them with kill -9 or pkill?
You can store the PIDs of your child processes in a file and use it to kill them later. Example with sleep child processes:
$ cat Makefile
all: start-1 start-2 start-3
start-%:
sleep 100 & echo "$$!" >> pids.txt
kill:
kill -9 $$( cat pids.txt ); rm -f pids.txt
$ make
sleep 100 & echo "$!" >> pids.txt
sleep 100 & echo "$!" >> pids.txt
sleep 100 & echo "$!" >> pids.txt
$ ps
PID TTY TIME CMD
30331 ttys000 0:00.49 -bash
49812 ttys000 0:00.00 sleep 100
49814 ttys000 0:00.00 sleep 100
49816 ttys000 0:00.00 sleep 100
$ make kill
kill -9 $( cat pids.txt ); rm -f pids.txt
$ ps
PID TTY TIME CMD
30331 ttys000 0:00.50 -bash
Note: if you use parallel make you should pay attention to race conditions on pids.txt accesses.
You could try killing the processes by there PID (Process ID):
for example:
# ps -ax | grep nginx
22546 ? Ss 0:00 nginx: master process /usr/sbin/nginx
22953 pts/2 S+ 0:00 grep nginx
29419 ? Ss 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
29420 ? S 1:59 nginx: worker process
29421 ? S 1:54 nginx: worker process
29422 ? S 1:56 nginx: worker process
29423 ? S 1:49 nginx: worker process
29425 ? S 0:09 nginx: cache manager process
30796 ? S 1:49 nginx: worker process
and then you can kill the process with:
kill 22546; kill 22953; kill ...
You can also capture just the PID with:
# ps -ax | grep nginx | cut -d' ' -f1 |
22546
24582
29419
29420
29421
29422
29423
29425
30796
update:
you can write the PIDs to a file and pull them back in make like this:
pids:
echo ps -ax | grep nginx | cut -d' ' -f1 | > PIDs.txt \
FILE="/location/of/PIDs.txt" \
old_IFS=$IFS \
IFS=$'\n' \
lines=($(cat FILE)) \
IFS=$old_IFS \
PID=$(echo {line[4]}) \
kill $PID

pgrep command not returning PID

I am trying to find the PID of a process (motion_sensor.py), but pgrep returns nothing. Why does it not return the process id?
pgrep -u www-data motion_sensor.py
ps -ef | grep "motion_sensor" returns
root 7149 1 93 Apr25 ? 15:59:08 python motion_sensor.py
www-data 31872 23531 0 14:09 ? 00:00:00 sh -c sudo python /home/pi/Desktop/PiControl/motion_sensor.py
root 31873 31872 0 14:09 ? 00:00:00 sudo python /home/pi/Desktop/PiControl/motion_sensor.py
root 31874 31873 47 14:09 ? 00:14:30 python /home/pi/Desktop/PiControl/motion_sensor.py
pi 32645 32202 0 14:39 pts/0 00:00:00 grep --color=auto motion_sensor.py
Normally pgrep applies the search pattern to process names. The process name in this case is python and not motion_sensor.py. If you want to grep for the full path rather than just the process name you need to pass -f:
pgrep -u www-data -f motion_sensor.py
Check man pgrep
the requirement is to find out PID of a process,
So you can try :
ps aux | grep www-data motion_sensor.py

Resources