After following the
part one “Scaling webservices- Its easy!!“
you are successful scaled your application server horizontally and
the application is serving thousands of request concurrently. You are
celebrating the initial success of the lucky application. But
somewhere down the line your application get slower and slower and
finally Oops!! Application break down :( .
The culprit is
helpless beast database “MySql”.
Now adding more and
more cloned application server does not helps at all but will cause
the situation even worse. After brainstorming we come to two major
possibilities to tackle it.
#1. Keep the beast
MySql running and make the master slave replication of DB and upgrade
master by adding RAM, and more RAM. In longer run use the tachnique
of database sharding, denormalization of DB and do some fine tuning
of the database in use. But as time goes the optimization become time
consuming and costlier.
#2. Keep your DB bit
less normalized from day1 and include less and less joins in your DB
queries like in case of noSQL DB or you can switch to hogh scalable
NoSql DB like mongoDB. Join is now need to be done in the application
code and the application code is running on couple of servers. The
sooner you take the move lesser the code change and rework need to
done. But this is also have some gotcha. Lets your application do
several joins on dataset. Sooner this database request feels like
getting slower. And this is the time you need to introduce cache.
Cache works with lightning -fast. It holds the data in memory and
serves the data request as fast as technically possible. Eg: Redis
can serve thousands of data request per second when being hosted on
standard server.
Caching can be done
in two ways :
Database query
caching-
Whenever you do a
database query in your application store the result-set in cache. You
can use the hashed version of query string as a key and result-set as
value. But this leads to the problem of cache expiration in case of
complex queries. When one small data changes you need to delete all
the cached data that containing that small data.
Object caching -
This is more
preferable now a days. In this case we set the model object and catch
this model object in memory. This allow us to easily get rid of
unwanted object when something is changed and make overall operation
faster and logical.
This approach make
asynchronous processing possible!! Just feel the situation where a
group of server is setting the attributes of your fatty object by
fetching the data from slow pitty server. The application now just
consume the cached object and never touch the database anymore in
near time.
I am a big fan of
caching and using memcache it scales like a charm. Keep caching and
enjoy the lightning fast performance!!