Physical vs software load balancer? - nginx

I just read this article on the history of load balancers:
https://devcentral.f5.com/s/articles/what-is-load-balancing-24740
going through DNS servers through Cluster IP software based to finally physical devices.
I have also read about HAProxy and nginx in:
https://www.loggly.com/blog/benchmarking-5-popular-load-balancers-nginx-haproxy-envoy-traefik-and-alb/
But HAProxy and nginx are server software application that needs to be installed, configured and run like an apache web server.
So how does this fit with the first article that says load balancing is primarily handled by dedicated hardware?
I assume its a combination of both. E.g. in a network you might setup a physical loadbalancer and behind that one or more webservers running e.g. HAProxy for additional load balancing. But its not clear to me when a loadbalancer should be a physical dedicated device and when you can just install e.g. haproxy on a linux server instead.

I would say that Loggly's benchmarks are completely inaccurate, just to get that out of the way. I read that article and thought to myself, this can't be right. So, I followed their article and tried to reproduce it, but got very different results. I have my code and results here on GitHub: https://github.com/NickMRamirez/Proxy-Benchmarks
So, about software vs hardware load balancers. Traditionally, yes, there were rack mounted hardware devices that were load balancers. F5 was king of these devices. Then, HAProxy and NGINX came out and allowed you to proxy traffic via userland software. You can install them onto your own hardware, a VM, a Docker container...whatever. You control the amount of CPU and RAM, depending on your needs.
Of course, you can also buy servers with the load balancing software pre-installed, such as the HAProxy ALOHA. You may also decide to run the load balancer on a dedicated server if you wish.
Side note: F5 acquired NGINX in order to compete in the software load balancer space.

Related

Load Balancer HA

what happens when a load balancer (HaProxy / Nginx) is down, this single point of failure may cause the whole system to be unavailable, what's the best strategy to recover in this case; how to prevent service to be unavailable.
Do we also need replication for Loadbalancer to prevent data loss?
The common solution is to run one or several servers with one or more VIPs (Virtual IP address) where the keepalived handle the VIP and haproxy the load.
This is one of many examples how to create such a setup Setting Up A High-Availability Load Balancer (With Failover And Session Support) With HAProxy/Keepalived On Debian Lenny
About the "replication" should you answer to you these questions.
what do you want to replicate?
how many replications do you want?
In HAProxy can you use Peers for replication of several things.

What's the mechanism of Inner Load Balancing along with docker swarm v1.12

Docker Swarm mode achieves Inner Load Balancing, and as far as I know, nginx is called hard load balancing, zookeeper is kinda soft load balancing.
So what's the mechanism of the Inner Load Balancing coming along with Docker v1.12?
Does it embed a nginx inside or similar methods like zookeeper?
"Inner" load balancing? Not exactly.
Commit ea4fef2 documents it (docs/swarm/key-concepts.md) as
Swarm uses ingress load balancing to expose the services you want to make available externally to the Swarm.
Swarm can automatically assign the service a PublishedPort or you can configure a PublishedPort for the service in the 30000-32767 range.
External components, such as cloud load balancers, can access the service on the PublishedPort of any node in the cluster, even if the node is not currently running the service.
Swarm has an internal DNS component that automatically assigns each service in the Swarm DNS entry.
Swarm uses internal load balancing to distribute requests among services within the cluster based upon the services' DNS name.
Right now (docker 1.12 August 2016), that inner load balancing does not work consistently: issue 25325
➜ ~ time curl http://10.218.3.5:30000
I'm 272dd0310a95
curl http://10.218.3.5:30000 0.01s user 0.01s system 6% cpu 0.217 total
➜ ~ time curl http://10.218.3.5:30000
curl: (7) Failed to connect to 10.218.3.5 port 30000: Operation timed out
And swarmkit issue 1077 illustrates there is no plan yet to
provide capabilities for session stickiness (cookie-based etc.) in this router mesh.
As awesome as it would be, not all apps are stateless, and we need to route users to the proper container in certain cases
Because:
since we do load balancing at L3/L4 it cannot be bases on things like session cookie.
The best that can be done is to have Source IP based stickiness.
And source IP is not always good enough:
That wouldn't work for our case.
We would have an upstream load balancer (F5) which would make traffic appear to come from a single IP, the "SNAT pool" IP on the F5 since it is a full proxy.
Effectively, Source IP based stickiness would cause all requests to go to one container since all the source IPs would come from the same address.
So the internal load balancer remains quite "basic":
The main issue with adding "session stickyness" is that there are a hundred ways to do it.
It is also an L7 feature, whereas our load balancing operates at L3/4.
There are two high-level paths here:
Monitor events coming from the docker API to modify F5 state to route directly task slots.
Integrate with libnetwork and have the loadbalancer operate as an L7 LB would if it were running directly in the swarm.
The conclusion for now is:
If you want to handle all aspects of load balancing and not use IPVS, you can disable it by running services in DNSRR mode. You can run any load balancer inside of swarm to do load balancing, bypassing the service VIP and populate backends with the DNSRR entries.
That is why the latest release 1.12 has, with PR 827, added support for DNSRR mode and disabling ingress.

Clarification of nginx and load balancing needed

I'm now reading design of Instagram and I found such a description of their load balancing system.
Every request to Instagram servers goes through load balancing machines; we used to run 2 nginx machines and DNS Round-Robin between them. The downside of this approach is the time it takes for DNS to update in case one of the machines needs to get decomissioned. Recently, we moved to using Amazon’s Elastic Load Balancer, with 3 NGINX instances behind it that can be swapped in and out (and are automatically taken out of rotation if they fail a health check). We also terminate our SSL at the ELB level, which lessens the CPU load on nginx. We use Amazon’s Route53 for DNS, which they’ve recently added a pretty good GUI tool for in the AWS console.
The question is. Am I right that for now they have a DNS Server which uses RR to decide on which nginx server to send the request. And each of this nginx servers at their turn resends the request to a cluster?
And the second question is. What the difference between nginx and load balancer. Why cannot we use nginx instead?
For your first question, I believe the answer seems to be that Instagram now uses Route53 to map DNS to an Elastic Load Balancer, which does two things: It routes traffic fairly evenly to three NGINX load balancers, and it provides SSL for all traffic. The NGINX servers then act as load balancers to content/application servers further down the stack. Using an ELB instead of round-robin DNS means they can add/remove/update instances attached to the ELB without ever having to worry about DNS updates or TTL.
As for the second question, you can use NGINX just as easily as HAproxy or other services to do load balancing. I am sure that part of the appeal to Instagram in choosing NGINX is its incredible speed and that it's asynchronous and "event-driven" instead of threaded like Apache2. When set up properly, that can mean less headaches under heavy loads.

nginx behind load balancers

I've found at that Instagram share their technology implementation with other developers trough their blog. They've some great solutions for the problems they run into. One of those solutions they've is an Elastic Load Balancer on Amazon with 3 nginx instances behind it. What is the task of those nginx servers? And what is the task of the Elastic Load balancers, and what is the relation between them?
Disclaimer: I am no expert on this in any way and am in the process of learning about AWS ecosystem myself.
The ELB (Elastic load balancer) has no functionality on its own except receiving the requests and routing it to the right server. The servers can run Nginx, IIS, Apache, lighthttpd, you name it.
I will give you a real use case.
I had one Nginx server running one WordPress blog. This server was, like I said, powered by Nginx serving static content and "upstreaming" .php requests to phpfpm running on the same server. Everything was going fine until one day. This blog was featured on a tv show. I had a ton of users and the server could not keep up with that much traffic.
My first reaction would be to just use the AMI (Amazon machine image) to spin up a copy of my server on a more powerful instance like m1.heavy. The problem was I knew I would have traffic increasing over time over the next couple of days. Soon I would have to spin an even more powerful machine, which would mean more downtime and trouble.
Instead, I launched an ELB (elastic load balancer) and updated my DNS to point website traffic to the ELB instead of directly to the server. The user doesn’t know server IP or anything, he only sees the ELB, everything else goes on inside amazon’s cloud.
The ELB decides to which server the traffic goes. You can have ELB and only one server on at the time (if your traffic is low at the moment), or hundreds. Servers can be created and added to the server array (server group) at any time, or you can configure auto scaling to spawn new servers and add them to the ELB Server group using amazon command line, all automatically.
Amazon cloud watch (another product and important part of the AWS ecosystem) is always watching your server’s health and decides to which server it will route that user. It also knows when all the servers are becoming too loaded and is the agent that gives the order to spawn another server (using your AMI). When the servers are not under heavy load anymore they are automatically destroyed (or stopped, I don’t recall).
This way I was able to serve all users at all times, and when the load was light, I would have ELB and only one Nginx server. When the load was high I would let it decide how many servers I need (according to server load). Minimal downtime. Of course, you can set limits to how many servers you can afford at the same time and stuff like that so you don’t get billed over what you can pay.
You see, Instagram guys said the following - "we used to run 2 Nginx machines and DNS Round-Robin between them". This is inefficient IMO compared to ELB. DNS Round Robin is DNS routing each request to a different server. So first goes to server one, second goes to server two and on and on.
ELB actually watches the servers' HEALTH (CPU usage, network usage) and decides which server traffic goes based on that. Do you see the difference?
And they say: "The downside of this approach is the time it takes for DNS to update in case one of the machines needs to get decommissioned."
DNS Round robin is a form of a load balancer. But if one server goes kaput and you need to update DNS to remove this server from the server group, you will have downtime (DNS takes time to update to the whole world). Some users will get routed to this bad server. With ELB this is automatic - if the server is in bad health it does not receive any more traffic - unless of course the whole group of servers is in bad health and you do not have any kind of auto-scaling setup.
And now the guys at Instagram: "Recently, we moved to using Amazon’s Elastic Load Balancer, with 3 NGINX instances behind it that can be swapped in and out (and are automatically taken out of rotation if they fail a health check).".
The scenario I illustrated is fictional. It is actually more complex than that but nothing that cannot be solved. For instance, if users upload pictures to your application, how can you keep consistency between all the machines on the server group? You would need to store the images on an external service like Amazon s3. On another post on Instagram engineering – “The photos themselves go straight to Amazon S3, which currently stores several terabytes of photo data for us.”. If they have 3 Nginx servers on the load balancer and all servers serve HTML pages on which the links for images point to S3, you will have no problem. If the image is stored locally on the instance – no way to do it.
All servers on the ELB would also need an external database. For that amazon has RDS – All machines can point to the same database and data consistency would be guaranteed.
On the image above, you can see an RDS "Read replica" - that is RDS way of load balancing. I don't know much about that at this time, sorry.
Try and read this: http://awsadvent.tumblr.com/post/38043683444/using-elb-and-auto-scaling
Can you please point the blog entry out?
Load balancers balance load. They monitor the Web servers health (response time etc) and distribute the load between the Web servers. On more complex implementations it is possible to have new servers spawn automatically if there is a traffic spike. Of course you need to make sure there is a consistency between the servers. THEY CAN share the same databases for instance.
So I believe the load balancer gets hit and decides to which server it will route the traffic according to server health.
.
Nginx is a Web server that is extremely good at serving a lot of static content for simultaneous users.
Requests for dynamic pages can be offloaded to a different server using cgi. Or the same servers that run nginx can also run phpfpm.
.
A lot of possibilities. I am on my cell phone right now. tomorrow I can write a little more.
Best regards.
I am aware that I am late to the party, but I think the use of NGINX instances behind ELB in Istagram blogpost is to provide high available load balancer as described here.
NGINX instances do not seem to be used as web servers in the blogpost.
For that role they mention:
Next up comes the application servers that handle our requests. We run Djangoon Amazon High-CPU Extra-Large machines
So ELB is used just as a replacement for their older solution with DNS Round-Robin between NGINX instances that was not providing high availability.

Getting client values of IIS Server Variables in Load Balanced Environment

I have an intranet ASP.NET web application in which I need to get the IP of the client's machine. I do this vis the following code:
HttpContext.Current.Request.ServerVariables.Item("REMOTE_HOST")
It used to work when my ASP.NET site was only hosted on a single server. However once we got the load balancer installed and migrated our apps to a web farm, the code above returns the IP of the Load Balancer device and not of the client anymore.
I am working with the networking folks to determine what can be configured differently with the load balancer, but in the meantime I was wondering if there was another way I could get the client's IP other than using that IIS Server Variable? Or any other suggestions?
Thank you!
Which load balancer are you using? It sounds as if your load balancer is acting as a proxy for the web traffic, hence the reason the source appears to come from the LB. Most hardware load balancers are built on Linux platforms and there is provision for transparency if the kernel supports it:
http://www.mjmwired.net/kernel/Documentation/networking/tproxy.txt
However, this would probably require root access to the unit and some downtime. But it is something that may be worth mentioning to the vendor's support team if they don't have any ideas.
Another (hopefully much easier) option: You may be able to configure the load balancer's proxy to write the client's source IP in the HTTP x-forwarded-for header:
http://en.wikipedia.org/wiki/X-Forwarded-For
And then you'll be able to read this header via ASP.net in a similar way:
Request.ServerVariables("X-Forwarded-For")
This may already work if the proxy is already doing this.
Really your options depend on what your load balancer is capable of, and what is configurable. Note the list of common hardware vendors at the bottom of the wiki page above.

Resources