Response Caching with memcached

Wow, this screams!

Today I played around with memcached as a response cache for this application. The goal was to boost the number of requests per second this application can handle when there is not so much content change but a huge load of read requests - e.g. from being "slashdotted", meaning, linked from a high profile site and getting a huge number of requests in a short time.

Initial testing on my MacBook Pro showed, that without response caching, a single instance can sustain about 12 requests per second to the main page. This is not too good, but does a lot of database traffic and has pretty much no optimization. Here are the results:

Document Path:          /-51111/wa/Web/page?pageId=2
Document Length:        22973 bytes

Concurrency Level:      20
Time taken for tests:   79.914 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      23180000 bytes
HTML transferred:       22973000 bytes
Requests per second:    12.51 [#/sec] (mean)
Time per request:       1598.283 [ms] (mean)
Time per request:       79.914 [ms] (mean, across all concurrent requests)
Transfer rate:          283.26 [Kbytes/sec] received

Tests I did a while ago showed that the Mac Mini with two instances configured can handle around 30 requests per second with this test. Not perfect but a reasonable number for this machine.

To improve this, I compiled memcached and used it as a cache for responses. It runs on the same machine, uses a max. of 64MB cache and caches a full response for a given URI. The cache gets flushed whenever a change is made on the admin side. Everything is pretty simple, straightforward, and without much sophistication.

Here are the results with memcached usage:

Document Path:          /-51111/wa/Web/page?pageId=2
Document Length:        22973 bytes

Concurrency Level:      20
Time taken for tests:   3.936 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      23165000 bytes
HTML transferred:       22973000 bytes
Requests per second:    254.05 [#/sec] (mean)
Time per request:       78.725 [ms] (mean)
Time per request:       3.936 [ms] (mean, across all concurrent requests)
Transfer rate:          5747.13 [Kbytes/sec] received

254 requests per second. This is very impressive - given that this is a single instance of a WebObjects application running inside Eclipse 3.5 on a laptop with Snow Leopard. I'll work out the kinks with caching / cache flushing and will deploy that sooner or later to the life site on the Mac Mini and this site should get noticeably faster.

That is, if the my upstream connection is fast enough to deliver ...

created by: Guido  |  Comments: 2

Comments

03.12.2009 14:38
Fredrik Lindgren said:

Interesting! How did you do the integration? Is memcached caching the database tables? I am looking for a way to cashe hole pages such as Varnish. But this might be an alternative?!
03.12.2009 14:50
Guido said:

So, some background:

I use my own WebObjects Application to host this blog. It's all home grown, my own code base, so I can hook in wherever I like. The memcached integration was done fairly easily. I use a unique identifier for a blog entry to cache the full HTML response in memcached whenever the page is hit the first time. Whenever I change the blog entry, I remove the entry from memcached and it gets cached automatically whenever the page is hit again.

Right now, the entries do not expire as I remove them whenever the blog entry or the list changes. Currently this is not in the production app, as I'm still working out some small kinks, but overall, it is a fairly easy concept and makes responses incredibly fast (compared to a normal dynamic page).

Leave a comment

Comment Note

Name

Email (required, will not be published)

Website

Comment

Notify me when more comments arrive