Free version available
Magnifying Glass

The PocketSmith Blog

Syndicated Posts

FaceBook

Twitter

  • #financialconfession of the day: "I get really annoyed when my friends spend frivolously and then complain about... http://fb.me/I1qhJW4p 4 days ago
  • "Bye Bye Quicken Online, Hello Mint!" by Jay Monee on Budgets Are Sexy - "PocketSmith: This big pull with these... http://fb.me/EuooR2LH 1 week ago
  • "Too many people spend money they haven't earned, to buy things they don't want, to impress people they don't like." Will Smith #quote 1 week ago
  • More updates...

Sessions with memcached for Rails on Leopard

Wednesday, September 3rd, 2008 by Jason
Geek time. James has been getting our new beta environment up and running on Slicehost, making some impressive strides in the right direction. In the last 12 hours, we’ve noticed a significant increase in speed from a single Mongrel instance, to a combination of Thin and Nginx. James will write more as he forges on, in the meantime I’m working on performance from a session-management perspective, and will post a step-by-step that I emailed the team this morning.

PocketSmith’s current architecture loads most of its forecasting data into sessions by utilising non-database backed models. When the user logs in, the application generates the user’s cashflow forecast from a list of stored events and matches it to a series of uploaded bank transaction data, amongst other things. Subsequent modifications to the user’s account require a complete update from point x forward as the information is refactored (cash forecasts, vs actuals, cashflow information, date and time-related events, goals etc).

Given we’re currently generating forecasts for 365 days (and soon to be more), there’s a lot of data shuffling around every time the user makes a change, and the initial assumption from this Rails newbie is that multiple read/writes of volatile data to a database is inefficient. Hence, forecast data is stored in the air. Or in less romantic terms, in a chunky-ass session that’s also not particularly efficient, as we’ve discovered in deploying PocketSmith to the new hosting environment. Sessions themselves have to be stored somewhere in order to persist.

I’ve also come to realise that rapid writes of multiple rows to the database don’t have to be slow, as evidenced by how quickly we’re importing bank transactions via CSV upload using ar-extensions. For the beta, we’ll stay this course and refactor to suit in the near future, if necessary.

Anyway, the size of these sessions has been impeding the application’s performance in terms of speed; furthermore they’ve been causing frequent 500 server errors as MySQL occasionally fails in its attempts to write the session to the database.

Having not given much thought to session handling since the first lines of the forecasting system were written a couple of months back, some quick research yielded a number of alternatives to what we were using (ActiveRecordStore). Seeing how we’ve heard very good things about memcached (mem-cache-dee), in particular how well it plays with Nginx (engine-exxx), I thought I’d give it a shot.

Memcached is a distributed memory caching system that yields a significant increase in performance mainly because it avoids reading and writing to disk; in addition to this it should scale well as we load-balance and proxy through Nginx.

Email below – we’ll post the results of the migration in due course :-)



Righto – there’ll be a few tweaks here and there as we go forward, but here’re some quick steps to getting memcached running on Leopard. The attached shell script should also work for installing memcached on Ubuntu.

1. Install memcached by running the attached shell script, save it to a separate folder first for neatness:
chmod u+x install-memcached.sh
bash -x install-memcached.sh
2. As per the echo, add this line to your ~/.bash_profile
EVENTNOKQUEUE=1
3. Pull the configuration into your current environment
source ~/.bash_profile
4. Install the memcache client
sudo gem install memcache-client
-
FYI this is what I’ve added to environment.rb

5. New requirement and constant

require 'memcache'
CACHE = MemCache.new :namespace => "pocketsmith",
:cthreshold => 10000, :compression => true, :debug => false,
:readonly => false, :urlencode => false
CACHE.servers = '127.0.0.1:11211'  

6. Flicked the switch
from :active_record_store to :mem_cache_store

config.action_controller.session_store = :mem_cache_store

7. Added cache and expires values to the session config

config.action_controller.session = {
:session_key => '_pocketsmith_session',
:secret      => '_secret_squirrels_code_here_',
:cache       => CACHE,
:expires     => 900
}

I haven’t pushed this yet as it will break everything. Actually, doing this will most likely make it not run on Heroku as I don’t think they support memcached yet (or even SQLSessions, if they’re running on postgresql?) When you have installed memcached and the updated copy of PocketSmith, you’ll need to have it running in order for the application to work.

8. Start memcache in verbose mode

memcached -vv
Note: if you quit memcached PocketSmith will crash, and you’ll need to restart the webserver in order to reconnect :-T

9. Optionally, get memcached to run every time you login to the console by adding this to your .bash_profile:

memcached -d -m 24 -p 11211
echo "memcached started. also, francois wears lacy panties."
Multiple terminal windows will not spawn multiple instances of memcached as it can only serve up at one address and port at a time.

10. To nuke the running instances of memcached:

killall memcached
…and that should be it :-) Keen to see how speedy Nginx is with memcached in tow!

p/s These references were valuable:

Tags: , , , ,

Leave a Reply