mysql - Perl mailqueueing with threads 'out of memory' -
mysql - Perl mailqueueing with threads 'out of memory' -
i created mailqueue script checks mysql table mail service has got timestamp in past send. can there more mail service in 'mailqueue' send in 1 time used threads send mail service in batches. when there not much mail service send scheme running steady, other times mailqueue process running (through bash script calls every 30 seconds) getting killed because scheme running out of memory. prevent 'mailqueue' of running out of memory.
i inquire of take code underneath maybe doing wrong.
thanks in advance.
~$ htop pid user pri ni virt res shr s cpu% mem% time+ command 5675 root 20 0 969m 528m 3744 s 0.0 14.1 2:33.05 perl /path/mailqueue.pl server specs: 1 vcpu; 3.75 gib memory;sub start_threads { @threads; # records found $found = 0; $sth = $dbh->prepare("select mail_queue_id, project_id, type, name, email mail_queue timestamp < now() , active = 1 order timestamp asc limit 10"); $sth->execute(); while (my $ref = $sth->fetchrow_hashref()) { # set if records found $found = 1; # set email variables $id = $ref->{'mail_queue_id'}; $project_id = $ref->{'project_id'}; $type = $ref->{'type'}; $name = $ref->{'name'}; $email = $ref->{'email'}; # create array info @select_arr = ($id, $project_id, $type, $name, $email); # start thread send mail service $t = threads->new(\&sendmail, @select_arr); push(@threads,$t); } foreach (@threads) { # mail_queue_id $id = $_->join; print "set email $id in queue inactive\n"; # set mail_queue record inactive -> mysql(event) mailqueue cleanup every 10 minutes $sth = $dbh->prepare("update mail_queue set active = 0 mail_queue_id = ? "); $sth->execute($id); } if($found eq 1) { # homecoming rows in mail_queue < 1 sleep(10); &start_threads; } else { # skip thread, wait 1 minut = sleep(1) select new rows; sleep(30); &start_threads; } } # prepare send e-mail sub sendmail { @select_arr = @_; # queue variables $id = $select_arr[0]; $project_id = $select_arr[1]; $type = $select_arr[3]; $name = $select_arr[4]; $email = $select_arr[5]; print "started sending email " . $id . " \n"; # phone call function sends mail service out $send = &email(@select_arr); # if mail service sent if($send eq 1) { print "done sending email " . $id . "\n"; sleep (1); # homecoming unique id homecoming $id; } } &start_threads;
what you're doing potentially quite expensive - when perl threads creates re-create of process - including imported modules, info states, etc. if table returns lot of rows, eat memory quickly.
you can see doing ps -eft
.
for you're doing, way you're doing bad idea. suggest 2 alternatives:
stick threads, start fixed number (say, 10) , utilize thread::queue
serialise data. limits number of process copies, , thread startup overhead.
switch using fork()
. parallel::forkmanager
more or less want here. fork()
more efficient way of process cloning - it'll re-create memory on demand, meaning sub processes much smaller.
i'll offer examples gave in previous answer: perl daemonize kid daemons
mysql multithreading bash perl email
Comments
Post a Comment