[Mailman-Developers] Problem with qrunner and too much
incoming mail
Chuq Von Rospach
chuqui@plaidworks.com
Mon, 6 Nov 2000 23:00:32 -0800
At 11:59 PM -0500 11/6/00, Barry A. Warsaw wrote:
>experience with Wikis, which everybody at my new employer simply raves
>about. Please visit
>
> http://www.zope.org/Members/bwarsaw/MailmanDesignNotes
got that bookmarked. Looks interesting.
>mistake was in making the delivery module part of that pipeline. What
>Mailman's pipeline ought to do is the prep-work on the message only:
That's pretty much what I do now on my big mother machine. There's a
web page for posting, and it spawns a script that creates a message
file (with full headers already finished), then sucks the subscriber
list out of an SQL database, generates a set of commandfiles and
subscriber lists, and throws them in a queueing system. it's
configurable on the fly (FWIW, I use QPS for queueing, I didn't write
one. Gnu Queue was my first choice, but it has problems on solaris I
didn't have time to debug...)
>spam and privacy filtering, setting headers, updating per-list
>counters, appending to digests, etc. Anything that does not require
>writing list-specific data could be pulled out of the pipeline. I'm
>thinking about specifically about nntp posting and the mta-handoff.
I'm beginning to think that "mailman 3.0" may end up being NOTHING
but APIs and enough glue to interface them. that way, *any* piece can
be swapped out for something equivalent if we want to, and we can
strongly isolate interactions and keep each code-base simple. A
subscription API, a spam API, a digest API, etc, etc, etc. It's not
at all that simple in practive, but in theory, you ultimately have a
set of Python classes that define a MLM...
> E.g. our whizzymailer would
>know the details of Mailman so when it got errors during the smtp
>transaction, it could update the db's directly. This isn't as likely
>to happen when we handoff to a localhost MTA, unless they support DSN
>and we run them synchronously (which clobbers the current
>architecture, as we're seeing).
this is nice in theory, but again, you start BEING an MTA, and the
subtleties are going to whack you up side the head. I looked at this
a while back, and decided that was a place I didn't want to go. I
really think we need to be careful about optimization by subverting
the MTA, because down that path lies sendmail -- which does
everything known to mankind, but nobody can figure out the
documentation...
Let the MTA be an MTA, and simply hand stuff off and process the
returns. That gives you the ability to build tools that leverage
other people's strength's, whether it's Postfix or smartbounce.
Otherwise, you're asking for a LOT of work that you don't think
you're going to need to do yet. I didn't realize that until I *did*
start designing sendmail out of my system and saw the results -
slower, uglier and I got to maintain the code myself...
> Would there be any disk persistence in
>case of system failure?
There has to be, but one thing sendmail did with 8.10 to boost
performance was to figure out what needed to be on disk for recovery,
and keeping the rest in memory. For their purposes, that was the df
and qf files, and they do all of the locking and status files via
what's effectively an in-sendmail RAM-based pseudo disk for all of
the other files, like lock files. so stuff relevant to the current
delivery attempt is in RAM, the stuff you need ot decide whether ot
deliver or how to deliver is on disk. In a crash, you only lose data
that's not relevant after a crash.
the big problem I see on sendmail 8.9 is inode locking, especially
when it's updating the /var/spool/mqueue directory inode. sendmail
8.10 goes a long way towards fixing that with the /var/spool/mqueue/*
setup -- you can imagine the fun of 400 sendmails all trying to
update their queue files in the same directory inode. (wince).
So before we get into fancy hashing systems, let's see how we do with
the basics -- split in/out/bounce into separate qfiles, split
content/metadata/status/lock into separate subdirectories, and if
necessary, allow multiple directories to further split the directory
contention.
In fact, a really simply way to parallelize Mailman would be to allow
multiple qfiles, and every time qrunner is spawned from cron, it
creates one instance per directory. that way, you distribute the load
out evenly and can rearrange it as you need by adding or removing
directories. No funky config file issues.
>Then again, since most messages don't live for very long in the queue,
>maybe the elimination of the disk i/o is worth a little instability or
>larger memory footprint.
Before you make that decision, we need to know whether the I/O is
actually significant, and which pieces of the I/O can safely be held
off. But in reality, I'll bet you won't find a Mailman site where the
mailman directories are I/O bound in an significant way. We shouldn't
try to optimize things that aren't the bottlenecks....
>Forking is pretty heavyweight, and threading has its problems too.
But for what we're talking about, the fork overhead is pretty
trivial. Forking is bad for lots of little, short-lived things.
Forking is good for relatively few, long-lived things. Given what the
processing cost of delivering 500 pieces of email will be, the
overhead of the fork is non-existant. If we were forking a process
per address, I'd worry about it. Forking a process per message isn't.
Reality is somewhere in the middle -- but the trick is to find the
slow parts and speed them up, rather than just try to speed up
various things we guess might be slow.
> CVR> Splitting the inbound and outbound queue would be my first
> CVR> thing here, and probably split bounces into a third
> CVR> queue.
>
>Great idea. Each queue has it's own requirements, e.g. there's
>definitely been complaints about the minimum 1-minute delay outgoing
>messages.
the outbound queue is a perfect place for a daemon to sit, and make
sure there are always up to "N" messages being processed (we might
want to amend that so only one message is in process at a time for a
given list. Hmm, does it make sense to split the outqueue into
subdirs (see above) by list name? the outqueue daemon could then
round-robin the lists, to prevent a busy list from stuffing the other
lists into a corner...
>Agreed. I also want that feedback for list-bound messages so that
>Mailman can be notified directly from the MTA about certain types of
>delivery failures.
I wouldn't worry about this. the programming complexity makes this a
false economy. It sounds nice in theory, but I wouldn't make it a
design goal until we get other stuff in place -- if then. Bounces are
a pain in the neck, but not that nasty to deal with, and the places
where simply background processing bounces falls down, this isn't
really likely to help, because it's the guy three forwards away from
the subscribed address, behind a firewall, on a Notes server, who
changed his name when he got married four months ago...
What you're really proposing, Barry, is to have to implement TWO
bounce processing systems. One for stuff where the delivery attempt
fails locally, and a second one for stuff where the mail is delivered
to an agent that then sends a reject back. and that latter includes
all of the major ISPs (especially AOL and MSN), most major
corporations (including Apple), and basically every large site with
firewalls and mail relays through them. So you're doubling your work
writing bounce processing code, and it buys you very, very little.
And the real trouble cases won't be helped at all, because they'r the
ones that won't get nailed until they come back through those 4
relays with the addresses munched and headers stripped.
> I still worry about bottlenecks in synchronous
>mode, even with a high degree of parallelism and shallow buckets.
From the point of view of Mailman, I doubt it's really an issue. I
think you're still thinking MTA here. Mailman is NOT an MTA. You
don't want to write an MTA. you don't want to think like an MTA
writer. (see this swinging watch? you are getting sleepy, sleepy...
you do not want to write sendmail. you do not want to integrate
sendmail into Mailman. you are not eric allman. sendmail.cf files
give you hives...)
>Thinking out loud: what if the API had two channels, mlm->mta and
>mta->mlm, let's call them outbound and inbound respectively.
I'd do three APIs, actually. DeliverMail, IncomingMail, BounceMail.
they might hand off to each other (forinstance IncomingMail would
recognize a bounce, and forward it ot BounceMail), but they're really
independent operations. I worry that trying to build a single API
would start throwing in compromises or overloading concepts. And iwth
three APIs, they can be developed independently by different people
-- and swapped out independntly. With a single API, that's tougher.
> CVR> If someone wants a rhetoric on how to scale mail list servers
> CVR> infinitely, I'd be happy to explain how, since I've had to
> CVR> develop an architecture to do so.
>
>If you write it up, I'll add it to the documentation. At the very
>least, let's add it to the ZWiki.
Will do, once I get a chance. I've put it on my todo list.
>Have you played at all with the threaded delivery in SMTPDirect?
>Admittedly it's not integrated correctly with the rest of Mailman, but
>I'm still curious if the notion is salvagable.
A little. I really think the fork model needs to be used, because the
thread locks don't seem to allow enough processing independence. The
delivery stuff is going to spend most of its time in I/O wait with
kernel locks, and needs to respond quickly when the I/O is available.
I'm afraid that using threads for this defeats that purpose, because
the block has to be reported to Python, which then has to get around
to activating that thread, and by the time you do, you've lost the
performance edge, especially when you're talking about a number of
these fighting for the single CPU resource.
This is a case where the fork overhead is trivial compared to the job
overhead, and you really want these independent and down in the
kernel, since you're dealing with stuff the kernel is best suited to
resolve.
--
Chuq Von Rospach - Plaidworks Consulting (mailto:chuqui@plaidworks.com)
Apple Mail List Gnome (mailto:chuq@apple.com)
Be just, and fear not.