Setting up Johnny Cache with Redis on Heroku.

Hooking up Johnny Cache and seeing your SQL query count drop down to next to nothing is a really satisfying feeling. Recently we've taken on a client running on Heroku, which enforces certain constraints meaning we had to do a few additional things to get Johnny running.

Heroku's memcache add-on requires SASL authentication, which isn't currently supported by the Django provided pylibmc cache backend. There's a django-pylibmc-sasl module, which is a drop in solution for using memcache as Django's cache directly, but this isn't supported by Johnny out of the box, so the the best solution seems to be to use Redis instead.

~~Redis isn't currently supported in the stable release of JC, but there's a Redis backend (contributed by Jannis Leidel) here. (This has since been merged into the development tip of johnny-cache, which looks like it will be included in the upcoming 1.4 release).~~

~~~So we need to install the dev version of Johnny, along with the redis and django-redis-cache packages:~~~

The stable release of johnny-cache now supports Redis, so we can install it from PyPI along with redis and django-redis-cache.

    pip install johnny-cache redis django-redis-cache

If you're doing this on Heroku, then we need to add the Redis To Go add on. The smallest option with persistent connections is the $5/month "mini" (I haven't tried this with the free "nano" option).

    heroku addons:add redistogo:mini

So we're nearly there, but following the Heroku instructions for setting up Redis To Go as a cache gave me an error:

    NameError: global name 'hiredis' is not defined
    RedisError: Hiredis is not installed

Turns out that's down to this issue in redis-py which hasn't made it onto PyPi yet, so we just need to leave out the PARSER_CLASS HiredisParser setting.

So in total the Django CACHES setting to use Johnny on our Heroku site looks like this:

    from urlparse import urlparse

    redis_url = urlparse(os.environ.get('REDISTOGO_URL', 'http://localhost:6379'))

    CACHES = {
        'default': {
            'BACKEND': 'johnny.backends.redis.RedisCache',
            'LOCATION': '%s:%s' % (redis_url.hostname, redis_url.port),
            'JOHNNY_CACHE': True,
            'OPTIONS': {
                'DB': 0,
                'PASSWORD': redis_url.password,
            }
        }
    }

Cue happy feeling.

Rolo.

comments powered by Disqus

Pingbacks

Pingbacks are open.