Crusher Development!

September 27, 2007

More fun with caching and memcached

For the past couple months we’ve been running with our home page and an example page cached. Which gave us a terrfic boost – it was somewhere around 10x more requests/sec on the home page. After running with this for a while we decided to dedicate a week to performance. Specifically trying to speed up event pages, listing directories, users stuff pages, and the contact page. If your mind is ready to sink in to the details, read on! :)

Switching to memcached sessions
Had to go through some effort to make sure during our rolling upgrade our users don’t lose their sessions. I guess we could always schedule downtime, but where’s the fun in that?

Using the model cache portion of intelligent fragment cache
This plug-in intelligently maps models to fragment caches so that when any save or delete occurs on a specific model the correct fragment caches are invalidated. There is one shortcoming that we came across. In our contact page, if a user adds a new contact the cache is not invalidated because that new contact was not associated with the original fragment. So I needed to add code in the after_create method of our contact model to invalidate the proper key.

after_create :invalidate_fragments def invalidate_fragments
return unless ActionController::Base.perform_caching
ActionController::Base.fragment_cache_store.delete(“/account/contacts.body/#{self.owner_id}”)
end

Then I also realized it wasn’t clear to me when a model object was “touched” and therefore associated with a fragment. So there were some instances where I had to do things like this:

@component.touch if ActionController::Base.perform_caching

Aside from that all seemed fine and everything is happily caching now.

Grr to caching content with small custom messaging fragments
Those partial we have where it says something like “Russell, hello!” have made it difficult to effectively apply caching. One more specific area in Crusher with custom messaging is the guest list. When you invite guests to a party and show them on your page we display a list of all those people along with their pictures, responses, etc… Each one of those is a partial and if you’re party is big it takes a bit of time to load. Each anonymous user when they visit the page is given an “add photo” link that overs over their default mug shot. So, what to do? I haven’t spent enough time investigating this yet, but I’m thinking that I can leverage inline CSS outside of the cached partial to make sure the proper display is shown. If not that, there may be some possible Javascript trickery, but I try to avoid that stuff.

Compare different user logins

Excessive calls to the DB with iterating over records
I feel like everyone knows about this one. We did some major clean-ups to ensure that when we iterate over records we weren’t making those single DB calls for every record. This involved using the :include portion of the find methods from active record. The way I debugged this was by watching my console for DB queries, and continually optimizing until the only one left was the big one at the beginning of the request processing. I’m not a mysql guru, so maybe there are things we can do with views or stored procedures to speed things up more, but I haven’t had time to investigate.

2 Comments »

  1. Hi there. What did you do with your memcached sessions to ensure they weren’t squashed?

    Comment by Tim Haines — August 6, 2008 @ 9:51 pm

  2. After investing far too much time in to trying to figure out how to import the sessions in to memcached we decided it was ok to just squash the sessions.

    Comment by Russell — November 11, 2008 @ 7:43 pm


RSS feed for comments on this post. TrackBack URI

Leave a comment

Blog at WordPress.com.