<!--toc--> |
|
## The Basic Rules |
### Cache Is Everything |
|
1. Cache Frequently Used Pages |
2. Cache Database Connections |
3. Cache Prepared Statements |
4. Cache Frequently Used Objects |
5. If you cache more? Do it. |
|
Most of pages displayed by any web site look the |
same for almost all visitors. So why you should |
generate them each time for every new visitor? |
|
The page level cache is the most efficient cache. If most |
of your visitors are not "registered users" then the |
first thing you should do is: |
|
if(!session().is_set("username")) { |
if(cache().fetch_page("/this/page/url")) |
return; |
|
cache().store_page("/this/page/url",300); |
} |
|
|
Cache the page for all non-registered visitors for 5 minute. This is the firs thing you should do. |
|
Of course the next thing is find what pages are visited |
frequently by whom and cache them. |
|
### The Database |
|
The next stage is the data-base. Remember that databases are _fast_ - they are _designed_ to |
be fast. So it may be a very good idea to take |
a look on the data base query and make sure it is optimal. |
|
Make sure that you use connection pooling and prepared |
statements caching. [CppDB](/sql/cppdb) gives you both |
for free - use it. |
|
And the last thing of course it to cache frequently used |
database objects that their retrial may be complex, like |
for example global site settings. |
|
### Profile Your Application |
|
There are many good tools like `valgrind` that would |
help you to find the heavy spots in the program. |
|
Try to figure them out eliminate them, optimize |
them solve them. |
|
This would help you a lot to improve the application |
performance. |
|
### Client Side or Server Side |
|
Think of some stuff you can "outsource" to the client |
side. For example 20% of your visitors are registered |
users and you want to show them some user specific data. |
|
It would not be wise to cache the entire page for the |
user as it may me valid only for a few requests. |
|
So it would be good idea to cache entire page and use |
some Ajax to fetch user specific data. The entire |
page would be cached in compressed when and user specific |
data would be loaded separately and much faster. |
|
You can also modify the page according to user's |
requirements using Java-Script code and some |
session information exposed to cookies. |
|
So think what can be done on client side and what |
have to be done on server side, draw a line and follow |
it. |
|
Remember the client side scales virtually unlimitedly. |
|
## Scaling Up |
|
Even if you have very efficient application you |
will need to be able to scale horizontally at some |
point - add more hardware. |
|
There are several tools that would help you. |
|
### Protocol |
|
Modern fast web servers like nginx and lighttpd |
can communicate with distributed application |
backends using FastCGI or SCGI protocols. |
|
It would be best choice as it would allow to spend |
entire CPU power of a node on the application |
and not on the web server. |
|
### Use Client Side Session Storage |
|
The client side session storage is the most |
scalable type of session storage, it scales linearly |
on the size of the hardware. |
|
Client side storage is suitable for most of cases, but |
you still need to remember about the [replay attack](/wikipp/en/page/secure_programming#Client.side.storage.considerations..Replay.attack.). You can always switch for specific critical points to the server side and then go back |
to the client side once again. |
|
|
### Caching Server |
|
CppCMS provides a `memcached` like sever `cppcms_scale`. |
|
But unlike `memcached`, `cppcms_scale` has following unique features: |
|
1. It supports trigger based cache invalidation |
2. It supports two levels of cache |
3. It provides distributed session support as well. |
|
Let's take a look on each point: |
|
**Triggers:** CppCMS has complicated cache model were keys and triggers may be seen as bipartite graph. Usually |
cache can be used locally, but when you need to scale up |
you need to share it. `cppcms_scale` works as cache |
server and allows to share the cache over the network. |
|
**L1/L2 Cache:** CppCMS allows to have both remote |
and local cache for frequently used items. If some item |
is used very frequently it can be cached on the |
side of the `cppcms_scale` client and instead of fetching |
entire object, it makes it possible to check if it is |
up-to-date. If it is only "confirmation" is sent over the |
network reducing the latency of the cache and the |
amount of work that should be done. |
|
**Session Sharing:** `cppcms_scale` can handle distributed |
session storage as well making it easy to use fast |
server side session storage. |
|
|
So if you need to scale up use `cppcms_scale` for this |
purpose. |
|
<!--toc-->
|
|
## The Basic Rules
|
### Cache Is Everything
|
|
1. Cache Frequently Used Pages
|
2. Cache Database Connections
|
3. Cache Prepared Statements
|
4. Cache Frequently Used Objects
|
5. If you cache more? Do it.
|
|
Most of pages displayed by any web site look the
|
same for almost all visitors. So why you should
|
generate them each time for every new visitor?
|
|
The page level cache is the most efficient cache. If most
|
of your visitors are not "registered users" then the
|
first thing you should do is:
|
|
if(!session().is_set("username")) {
|
if(cache().fetch_page("/this/page/url"))
|
return;
|
|
cache().store_page("/this/page/url",300);
|
}
|
|
|
Cache the page for all non-registered visitors for 5 minute. This is the firs thing you should do.
|
|
Of course the next thing is find what pages are visited
|
frequently by whom and cache them.
|
|
### The Database
|
|
The next stage is the data-base. Remember that databases are _fast_ - they are _designed_ to
|
be fast. So it may be a very good idea to take
|
a look on the data base query and make sure it is optimal.
|
|
Make sure that you use connection pooling and prepared
|
statements caching. [CppDB](/sql/cppdb) gives you both
|
for free - use it.
|
|
And the last thing of course it to cache frequently used
|
database objects that their retrial may be complex, like
|
for example global site settings.
|
|
### Profile Your Application
|
|
There are many good tools like `valgrind` that would
|
help you to find the heavy spots in the program.
|
|
Try to figure them out eliminate them, optimize
|
them solve them.
|
|
This would help you a lot to improve the application
|
performance.
|
|
### Client Side or Server Side
|
|
Think of some stuff you can "outsource" to the client
|
side. For example 20% of your visitors are registered
|
users and you want to show them some user specific data.
|
|
It would not be wise to cache the entire page for the
|
user as it may me valid only for a few requests.
|
|
So it would be good idea to cache entire page and use
|
some Ajax to fetch user specific data. The entire
|
page would be cached in compressed when and user specific
|
data would be loaded separately and much faster.
|
|
You can also modify the page according to user's
|
requirements using Java-Script code and some
|
session information exposed to cookies.
|
|
So think what can be done on client side and what
|
have to be done on server side, draw a line and follow
|
it.
|
|
Remember the client side scales virtually unlimitedly.
|
|
## Scaling Up
|
|
Even if you have very efficient application you
|
will need to be able to scale horizontally at some
|
point - add more hardware.
|
|
There are several tools that would help you.
|
|
### Protocol
|
|
Modern fast web servers like nginx and lighttpd
|
can communicate with distributed application
|
backends using FastCGI or SCGI protocols.
|
|
It would be best choice as it would allow to spend
|
entire CPU power of a node on the application
|
and not on the web server.
|
|
### Use Client Side Session Storage
|
|
The client side session storage is the most
|
scalable type of session storage, it scales linearly
|
on the size of the hardware.
|
|
Client side storage is suitable for most of cases, but
|
you still need to remember about the [replay attack](/wikipp/en/page/secure_programming#Client.side.storage.considerations..Replay.attack.). You can always switch for specific critical points to the server side and then go back
|
to the client side once again.
|
|
|
### Caching Server
|
|
CppCMS provides a `memcached` like sever `cppcms_scale`.
|
|
But unlike `memcached`, `cppcms_scale` has following unique features:
|
|
1. It supports trigger based cache invalidation
|
2. It supports two levels of cache
|
3. It provides distributed session support as well.
|
|
Let's take a look on each point:
|
|
**Triggers:** CppCMS has complicated cache model were keys and triggers may be seen as bipartite graph. Usually
|
cache can be used locally, but when you need to scale up
|
you need to share it. `cppcms_scale` works as cache
|
server and allows to share the cache over the network.
|
|
**L1/L2 Cache:** CppCMS allows to have both remote
|
and local cache for frequently used items. If some item
|
is used very frequently it can be cached on the
|
side of the `cppcms_scale` client and instead of fetching
|
entire object, it makes it possible to check if it is
|
up-to-date. If it is only "confirmation" is sent over the
|
network reducing the latency of the cache and the
|
amount of work that should be done.
|
|
**Session Sharing:** `cppcms_scale` can handle distributed
|
session storage as well making it easy to use fast
|
server side session storage.
|
|
|
So if you need to scale up use `cppcms_scale` for this
|
purpose.
|
|
|