How NGINX Reverse Proxy handle image/video file upload or download - nginx

First off, I'll explain my situation to you. I'm building a server for storing and retrieve data for my phone application. I'm new to NGINX. What I know point of using load balancing/reverse proxy is to improve performance and reliability by distributing the workload across multiple servers. But i'm not understand while it working with image/video file. Let say below is mine NGINX config file
upstream backend {
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
}
}
I have few question here.
First while i upload an image/video file, did i need to upload image into those all backend server or there is other way?
Second if I just save it to a separate server which only store image, while I requesting and download image or video file I proxy it to that specified server then what is the point of load balancing with image/video file since reverse proxy is to improve performance and reliability by distributing the workload across multiple servers?
Third does amazon s3 really better for storing file? Does it cost cheaper?
I'm looking for solution which can be done it by my own server beside using third parties.
Thx for any help!!

You can either use shared storage e.g. NFS, or upload to both servers, or incorporate a strategy to distribute files between servers, storing each file on a single server.
First two options logically are the same and provide fallover, hence improving reliability.
Third option, as you note, does not improve reliability (may be somehow, if one server fails second may still serve some files). It can improve performance, though, if you have many concurrent requests for different files and distribute them evenly between servers. This is not achieved through nginx load balancing but rather by redirecting to different servers based on request (e.g. file name or key).
For shared storage solution, you can use, for example, NFS. There are many resources going into deeper detail, for example https://unix.stackexchange.com/questions/114699/nfs-automatic-fail-over-or-load-balanced-or-clustering
For duplicate upload solution, you can either send file twice from client or do it server side with some code. Server side solution has the benefit of single file traffic from client and sending to second server only on fast network. In simple case this can be achieved, for example, by receiving file in a servlet, storing incoming data to disk and simultaneously upload to another servlet on the second server through http or other protocol.
Note that setting up any of these options correctly can involve quite significant effort, testing and maintanance.
Here comes S3, ready to use distributed/shared storage, with simple API, integrations, clients and reasonable price. For simple solution usually it is not cheaper in terms of $ per storage, but much cheaper in terms of R&D. It also has the option to serve flies and content through http (balanced, reliable and distributed), so you either can download file in client directly from S3 hosts or make permanent or temporary redirects there from your http servers.

Related

What is the difference between HTTP vs FTP?

I'm just learning about it and I have these things in mind but I'm not quite sure about them. Is there any wrong ideas about my findings? Please elaborate it in simple terms.
HTTP:
used to view websites between web servers
web server files to another web server
used to transfer small files (in text form)
used to have access in WWW
FTP
used to access and transfer files between a local machine and a web server
local files to a web server
used to transfer large files (in any form)
used to have access in a remote server
HTTP and FTP (note there is a section on the wikipedia page illustrates the differences between HTTP and FTP) are both application layer protocols.
See also here.
HTTP:
used to make request response communications between a server and a client
this communication can be used to both upload and download text and binary information
state less
faster when transferring many small files
used for web pages with or without authentication required
FTP:
also performs uploading and downloading of information
stateful control connection
faster for single large file transfers
file transfer authentication needed
limited support of pipe-lining
The big difference is that HTTP fixes many of the issues incurred by FTP. One example is that FTP has very little overhead and no metadata while HTTP provides this and there HTTP supports the sending of multiple files. Also HTTP is state less.
Some extra sources I would advise you read for more information on this are:
1. http://www.differencebetween.net/technology/difference-between-ftp-and-http/
2.
https://daniel.haxx.se/docs/ftp-vs-http.html
Also for more information on the different types of FTP, I would advise looking at this Stack Overflow post.

Sticky session load balancer with nginx open source

What the main difference between the sticky session available in nginx plus and hashing cookie in open source version?
According to the docs nginx open source allows session persistence based on hashing different global variables available within nginx, including $cookie_
With the following configuration:
upstream myserver {
hash $cookie_sessionID;
server localhost:8092;
server localhost:8093;
server localhost:8094 weight=3;
}
location / {
proxy_pass http://myserver;
}
Assuming, there will be centralized mechanism across backends for generating unique sessionID cookie for all new requests, so what the main disadvantages of such method compared to the nginx plus sticky session approach?
IP Hash load‑balancing can work as "sticky sessions",
but you have to keep in mind that this load balancing method is working relative bad itself, because a lot of user/devices shared same external IP-Address in modern world.
We experimented with a rather heavily loaded (thousands of parallel users) application and observed tens of percent imbalance between servers when using IP Hash.
Theoretically, the situation should improve with increasing load and number of servers, but for example we did not see any significant difference when using 3 and 5 servers.
So, I would strongly advise against using IP Hash in productive environment.
As open-source based sticky sessions solution, not bad idea to use HAProxy, because HAProxy support it out-of-the-box.
Or HAProxy + Nginx bundle, where HAProxy is responsible for "sticky sessions".
(I know about one extremely loaded system that successfully uses such a bundle for this very purpose, so, this is working idea.)
Your approach will work. According to the official NGINX documentation (Configuring Basic Session Persistence):
"If your application requires basic session persistence (also known as sticky sessions), you can implement it in NGINX Open Source with the IP Hash load‑balancing algorithm."
While NGINX Plus "offers a more sophisticated form of session persistence". For example "Least Time" method – when for each request the server with the lowest average latency and the lowest number of active connections is chosen.

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.

HttpModule to serve file on different server

I would like to create an HttpModule that can serve a file that is on a different server.
Server A is publicly accessible and receives a request for file.txt. This file is on server B and Server A will serve it to the user. Server B is not publicly available.
What would be the highest performance method of accomplishing this with an HttpModule?
I could let Server A download the file from Server B and stream it back to the user. That would require a lot of resources from Server A to do that.
Another option might be that Server A will serve the file directly from an open fileshare to Server B. This would probably require less memory on Server A, but would still need the file to be streamed from Server B to Server A.
I hope there is some way that the request can be redirected to Server B and then the file can be returned directly from Server B to the client, possible facilitated by Server A.
I cannot simply redirect to Server B as it's not directly available to the end user.
I would probably not invest in writing an HttpModule at all but instead I would use ARR (Application Request Routing) module to do the "proxying" for you in a way that is highly performant. You can also use its Caching functionality and that way if some files are "hot" they can be downloaded directly by the "front-end" server without hitting the back-end server. Using its cached will be the fastest option and since it can be pretty smart about caching it will be also one of the pain-less ways.
It is optimized to handle thousands of requests per second and does that in an async way that let it scale to huge numbers. Used in many content-delivery-network-type situations so you can count on it being really fast.

Would implementing a CDN involve moving images and changing path names?

I'm just learning about CDNs, so please forgive if this is a dumb question.
Would implementing a CDN involve moving images and changing paths?
Yes a CDN (Content Delivery Network) is at it basis nothing more that a set of webservers.
If you want to host files on a CDN you must copy your files to the CDN servers and then use the full CDN address that points to those files on those servers on your own webpage.
You can use a CDN on the same server but different URI. For instance, having your page in: www.example.com with cdn: cdn.example.com (with cdn.example.com as a vhost alias) should be faster then getting all data only from www.example.com, i think it's because of the number of http connections related to the address.
Of course it's best if you have it in another server, in this case you have to copy everything.
Not necessarily. You can use a service such as CloudFlare which requires only a modification of some of your DNS settings. In short, the service determines which files being served are static, and caches those in its network, generally reducing overall traffic to your servers. You also get the benefit of any geographical distribution the service provides that your own hosting service might not.

Resources