Sunday, December 21, 2014

Getting ready for the cloud: Preparation for autoscaling

Advent of cloud services has disrupted the way online services are managed. What used to be a gargantuan task of renting, deploying and managing remote servers has been replaced by single click creation and deployment. The process of creating a virtual machine is much easier and programmable than renting servers or working on shared hosting spaces. Cloud service providers create an illusion of infinite space over their own finite resources with managed services like S3 or Dropbox. This takes away any worries about resource limits. The user pays for what he uses and does not have to worry about changing servers in the future when requirement is bound to increase.

Consistency problem with auto-scaling

Considering how easy it is to create and terminate servers on cloud, the application developer tries to minimize its resource consumption. That is where comes auto-scaling. Auto-scaling is a set-up of operating at a minimum resource consumption with provision for automatically increasing resources as soon as the demand comes. Suddenly, there are 10000 users using on an application, the server has created 20 different mirror of the original server to cater to all of them.

The consistency problem

This brings us to the problem of data integrity and consistency. If user A adds a new content, this content should be available to user B accessing the website from different mirror of your server. Your dynamic cloud servers(instances) can not host any dynamic data. Any dynamic data must be consistent across the servers while keeping the resource usage minimum. You need a shared place to manage all your dynamic data.


Solutions for the consistency

Database consistency

Database being the most dynamic is fortunately a different software. You can host it on a different server and make the application servers query this single database server. Database scaling is somewhat limited with most engines not allowing a seamless scaling. e.g. MySQL for example need to stop "write" while changing servers. (You can create multiple read-replicas but there can be a single master server.) A solution is to use managed db services like dynamodb which are virtually scalable. However, the choice of database engine is dictated more by the application requirements than just scalability.

File uploads

The files which are uploaded to the application (e.g. a new user profile picture) needs to be accessible to all logged in user. You can not save this in the application uploads directory. It needs a place which is accessible from different instances behind a load balancer. One easy way out is to create another file hosting server and mount this server in other instance. Every mirror will mount this space on the uploads directory(NFS / Network File System) during boot. This way every time a file is saved in the uploads directory, it will actually be saved on the file hosting server. Alternatively, you can use a managed hosting space such as s3 and place all dynamic files there.

NFS vs managed space : When setting up NFS, you need to check the fraction of write requests that you need to process. Does the NFS server has to bear the burden of load. If every request has to use a file present on the shared space, every request is transferred to the NFS server which defies the primary objective. A managed hosting space like S3 is much better since it is completely scalable. Unless you need to host executables or program code on the shared space, a managed storage works generally. If you are using a reliable service provider, they should have scalable mechanisms for handling usage spikes with low latency. The choice of NFS vs managed space depends on what the application want to do with the content of this shared space.

Application flexibility: The application needs to modify itself to make auto-scaling work. You need to edit database paths, the place to read and write files or even the place to put temporary files. (How temporary are these files?) All these changes are going to be as complicated as the application itself. If the application is based on some preset framework, you might need to wait for a version upgrade or a mod to make your system cloud-compatible.