Hi,

On Thu, Mar 06, 2014 at 01:31:33AM +0100, Lukas Tribus wrote:
> Hi,
> 
> 
> > I understand. Is this something that could be taken up for a
> > future version?
> 
> Not a trivial thing todo. I think an internal resolver implementation
> in haproxy would be needed, as gethostbyname() and friends are blocking
> (nginx has its own resolver for example).

We've been thinking about implementing a simple async resolver in
combination with health checks to at least automatically update server
addresses at EC2 and similar horrible environments where a reboot can
change your server's address. A next step could be to try to use the
same resolver for regular traffic. The thing is that doing this fast
will require a cache otherwise it will be slow and will hammer the DNS
servers quickly.

> I don't think there are use cases other than yours to back an implementation
> (of the resolver and the additional features you would need).
> 
> Like I said, HAproxy is not a real forwarding proxy. Some people still use
> it a such, but its very limited.

I agree. We often see this confusion and each time we try to look closer,
it's obvious that other products like squid for example are much better
suited for the task and are as easy to deploy. That's why I'm not really
tempted to make haproxy bigger and more complex just to handle such
situations at the moment.

> > Also, what maxconn value do you recommend?
> 
> Depends on how much RAM you want HAProxy to use (and what you actually
> need).
> 
> Try start playing with maxconn at 1000, use your "server <name> *:80"
> config use all maxconns and check RAM usage. Finally, adjust maxconn
> to something your box can live with, without swapping.

I have a better approach. This one can be tricky because unless you manage
to really saturate all connections and fill the buffers with real data, it
is hard to know if your RAM is enough or not. I have some memories of
testing our very early ALOHA very hard running 40K concurrent connections
at 1GB and it was fine. But in another test environment, it died so we
decided to double the RAM to match calculations and not observations.

The principle is quite easy :
  - the kernel allocates *at least* 4kB per direction for a socket
  - haproxy uses two sockets per side => 2*2*4 = 16 kB of system buffers
    per forwarded connection.
  - haproxy is built by default with 16kB buffers. You have two buffers
    per forwarded connection => 32kB buffers
  - haproxy uses approximately 1-2kB per forwarded connection depending
    on build options and the architecture. I suggest remaining on the
    pessimistic side and counting 2kB.

So you have :
  -  2 + 2*16 = 34 kB for haproxy (buffers + structures)
  - 16 kB for the kernel
  = 50 kB per forwarded connection.

That means that 20k forwarded connections will need 1 GB of RAM for just
haproxy and the system buffers. You still need some memory to let the
system run normally. Also, a system running with that many connections
will likely need some network tuning so you'll have more skbs etc...
In practice I consider that haproxy+system must not use more than 2/3 of
the total system memory.

To go further, you can shrink the size of haproxy buffers. In the ALOHA,
we use 8kB by default with only 1kB of maxrewrite. It works pretty fine,
since a 8kB request (headers only) is already huge... Also, we don't need
to have a large buffer size for haproxy since it communicates with the
kernel which is not far away. The only gain in using larger buffers is
a lower CPU usage by reducing the number of syscalls at high data rates.

So with that in mind, a forwarded connection consumes 2+2*8=18 kB, plus
16kB for the kernel = 34kB. That's 1.3 GB for 40k connections, which is
fine for a 2 GB machine since it's 2/3 of the whole memory and respects
the principle above.

Thus, we could establish a final formula to know how much RAM you need
on a server for MAXCONN connections depending on BUFSIZE in kB :

  RAM = (2 + 2*BUFSIZE + 16) * MAXCONN * 3/2
      = (BUFSIZE + 9) * MAXCONN * 3

Regards,
Willy


Reply via email to