[erlang-questions] How to handle a massive amount of UDP packets?
Max Lapshin
max.lapshin@REDACTED
Tue Apr 24 08:26:45 CEST 2012
I want to explain a bit about my words on highload, large throughput
and big latency.
Let's first discuss TCP.
I consider, that {active,once} approach is one of the most beautiful
and convenient ways to handle incoming network traffic, I've ever
seen. gen_tcp:recv is not a choice (just like a blocking accept,
which is very popular due its "documented" state, considering with
non-blocking accept). {active,false} is a step back to a
non-responsive C-like program that hangs because of client GPRS lag.
So, again: {active,true} is for brave people. For very brave with very
good monitoring.
{active,false} — I don't know what is it for, but it is really fast right now
{active,once} — this is the best way, because it is flexible and
convenient. But it has one performance problem: messages.
When I want to download 150 MB of data via HTTP into erlang via 1 Gbps
channel, I suppose that it will be downloaded in 1 second. But lets
see what may happen. 150 MB is about 100 000 times of 1500 bytes. If
we use {active,once} than we may receive 100_000 messages in our
process. Erlang VM can hardly handle more messages into one process
than this amount. But this is not the biggest problem: we must handle
this data. And often handling 1500 and 15000 bytes is almost the same
time.
So according to my experience, biggest problem is not an amount of
data, it is amount of messages. Each message is a very expensive thing
if we speak about hundreds of thousands of them.
If we receive these 150MB in 150 messages, each 1 MB, our erlang
system will not even start coolers working. Something about 5% CPU.
But I was wrong about {active, 1024*1024}, because there should be
some timeout. It must be something like {active, 1024*1024, 1000}.
Don't wait more than 1 second and don't accumulate more than 1 MB.
Such hinting will help a lot in terms of copying memory, because it is
possible to preallocate required binary in tcp driver.
Now about UDP: problem is also in amount of messages. I know only one
way to reduce it: to reply with several udp messages in one message,
but perhaps Ulf's approach to combine {active,once} and recv will be
the easiest way to go.
More information about the erlang-questions
mailing list