Magento for Big Kids: Use a Consistent Cache Key Prefix

This is the first in what I hope to be a multi-part series on using Magento.  I’ve been working with it since June to run one of our core sites at Half Off Depot.

During these six months, we have:

  • Built an incredible team
  • Had our application servers swap to disk and otherwise go belly up, on numerous occasions
  • Moved from FastCGI back to mod_php
  • Tuned Apache a bit to squeeze more out of our application servers
  • Moved from a single front end webserver to multiple
  • Introduced MySQL master-slave replication, when the slave actually in use — it’s not just a hot backup
  • Crafted a respectable Magento application deployment process using Capistrano
  • Cranked out some basic Magento extensions
  • Run countless sales, built mobile apps, launched new web applications and a private API

I don’t claim to be a Magento expert after only six months (far from it), but I / we have learned a lot during this time.

In this first post, I’m going to unveil a handy tip:

Always use a consistent Magento cache key prefix.

This can be done in your app/etc/local.xml file like so:

<cache>
    ...
    <prefix>foo_</prefix>
    ...
</cache>

Magento performs poorly out of the box.  The crux of this is that its database is based on an Entity-Attribute-Value (EAV) data model.  Using APC is basically a requirement if you do any reasonable amount of traffic, too.  Big red flags, right? Anyways…

It also uses an aggressive caching model for things like:

  • Front end layout
  • Blocks of HTML used to render pages
  • Magento configuration data (because many core application config options are stored in the database)
  • Translation data
  • Full page cache
  • EAV types and attributes

Because we run on multiple front end web servers, we have to have a centralized cache.  We use Memcached for this. For example, if someone alters a product in our admin tool, which purges the cache item, the refreshed cache item needs to be available to all front end web servers at the same time. An inconsistency between our front end servers is not acceptable. Hence, the centralized cache.

When using Memcached, Magento uses Zend_Cache_Backend_TwoLevels under the hood because it has to maintain a mapping of cache type to the cache keys that make up the data for that type of cache. For example, you should be able to purge the layout or block cache without purging the entire set of cached data.  There’s no sort of partial cache purge out of the box possible with Memcached.  You either mark all items invalidated, or delete what you want to, one key at a time. In our case, the mapping of cache type to its keys is stored in our MySQL database. That’s not ideal, but…it is what it is for now.

But, here’s the catch: Magento / Zend_Cache prefixes all cache keys.  If you don’t define a cache key, Magento uses one that is formed with:

  1. Absolute path to your app/etc/ directory
  2. MD5 of this path string
  3. First three characters of the MD5 hash value

This makes all the sense in the world, right?  Maybe it does for some, but it doesn’t for us.  We run one web site driven by this single Magento instance.

But, we also have a deployment process centered around Capistrano.  What does this boil down to?

  1. Code releases are kept at /foo/bar/site/releases/[YYYYMMDDHHIISS] of when the code was deployed
  2. /foo/bar/site/current is a symlink to /foo/bar/site/releases/[YYYYMMDDHHIISS] of the most recent release

So, as we deploy code, the absolute path to the app/etc/ directory on disk changes!

Thus, when we deploy a new release, we get extremely high cache churn — the absolute path to the app/etc/ directory has changed because we move that current symlink!  We basically were rewriting all of our cache with every release, clobbering our Memcached instances and database.

We had to take the site down for a minute or two and refresh the cache in a controlled environment without many concurrent requests taking place. Once the cache had been warmed by a single user, all worked well once again.

Why not, say, throw an exception and barf all over the developer? Or provide a reasonable, consistent default value? Don’t change it as filesystem changes occur. That’s not intuitive at all. If you’re running multiple sites and need a separate cache prefix, you’re probably advanced enough that you’ve considered the implications of your approach already anyway.

So, what’s the lesson here?  Define your own Magento cache prefix to ensure that it never changes.

Hope you find this helpful! Here are a few more topics that will be coming soon:

  • Deploying Magento to multiple web servers with Capistrano
  • Centralizing your /media directory
  • Don’t touch Core!
  • Abstraction is for wimps: query the database yourself

Making a move to Half Off Depot

I’m happy to announce that I’ll be joining Half Off Depot, LLC as Lead Software Architect on June 27th.

Half Off Depot is a growing, promising startup here in Atlanta. As you might gather from the name, they’re in the daily deals space, sort of along the lines of Groupon and LivingSocial. As of this writing, they have been focusing on the Atlanta, Georgia and Knoxville, Tennessee markets.

I’ll be focusing on a number of areas, both server-side and in the mobile app arena, in addition to helping build the technology team.

This was not an simple decision. I’ve been in a Senior Software Development Engineer role at Yahoo! since April 2010. During the first decade of my career, I spent over four years at both Community Connect Inc. (now Interactive One) and Schematic, Inc. (now Possible Worldwide), both in senior-level roles. It’s not my style to leave a position after just over a year; I’m much more of a long-term kind of guy. However, as I got deeper into Schematic, I took on much more technical leadership where I was leading projects and directly managing developers, but haven’t done a lot of that at Yahoo! yet. I’ll be able to tap back into that wider range of my skills at Half Off Depot.

My transition to Yahoo! was really about focusing on my passion: architecture and development. Yahoo! has afforded me some incredible opportunities, especially when it came to exposing me to more technologies outside of the PHP and open source tools I’ve worked with over the past decade.

Specifically, I’ve spent a lot of time with Objective-C, Apple frameworks such as UIKit and AppKit, Hadoop, some Microsoft Mediaroom, and even client-side technologies. Yahoo! has really helped me expand my skill set and grow as a developer. I’ve worked with some incredibly talented, experienced developers. It’s been an amazing ride. I’m going to miss it!

But, startup life came calling, and it was time to answer. I could not be more excited to join the Half Off Depot team, and I wish my Yahoo! colleagues the best of luck. If you ever get the chance to work at Yahoo!, take it!

This is going to be an incredible journey — I can’t wait to get started. Stay tuned! You’ll be hearing more from me in the weeks and months ahead, especially as I begin to focus more on PHP, the web, and native mobile application development.

Technical New Year’s Resolutions: 2011

Better late than never, right? I should’ve done this in December, but at least it’s only two weeks into the New Year.

Last year was a great year. Looking back at my 2010 resolutions, here’s what I accomplished:

  • Learn a new language — really dove head first into learning Objective-C, along with the Cocoa and UIKit frameworks
  • Built and released my first iOS app, FloodWatch

My 2010 resolutions aside, I also managed to make a move to Yahoo!, start to hone my front end developer skills, do some Java work, learn some Hadoop and Pig scripting, learn some Lua, and speak at BarCamp Charleston. It’s been a busy year!

I’ve been absolutely horrible at blogging over the past year, though. Two posts in 2010 is just pitiful and sad. Shame on me.

So, given the look back and the year ahead, here’s what I’m challenging myself with:

  • Blog more: This is the biggest resolution of them all. I really need to write a few blog posts a month on whatever it is that I’m working on, when I might have something that can and should be shared with a larger potential audience. More often than not, I complete my tasks at hand and charge ahead to the next ones. I need to take more time to stop, reflect, and share.
  • Speak at more user groups and conferences: …this is already in the works, too, with my first 2011 talk at Atlanta PHP on February 3, 2011. I’ll be talking on the Yahoo! Query Language.
  • Write another article: …already in the works! Look for it later in the year.
  • Continue to sharpen my development and architecture skills: I’ve learned an amazing amount of new things during my time at Yahoo! I work with some ridiculously smart people, and am constantly learning from them and becoming a better developer because the people in my environment. I’m loving every single day in the office where I get to focus on code and architecture. This one should be a breeze.
  • Read some of the classic programming books again: Classic books like The Pragmatic Programmer and Code Complete are great to read every few years to keep yourself grounded and humble. This should be one of those years for me.
  • Build another app of some sort, iOS, Mac or otherwise: …have some ideas here, should be totally doable.
  • Spend some more time with PHP: I haven’t written much PHP since mid-2010, so it’d be nice to get back to it. I should contribute to Zend Framework, etc. — that’d be a great way to achieve this goal, while contributing to the community at the same time.
  • Get back on the conference circuit: I didn’t do so well with this in 2010, mostly due to my job change. I’d like to get to at least one PHP, OSS, or development conference in 2011.

So, that’s what I’ll be doing in 2011. Hopefully I’ll be here about 50 weeks from now, recounting how I knocked out every single one of these.

What are you doing in 2011?

Speaking at BarCamp Charleston 2010

UPDATE: slides are now available at Slideshare; also see my recap of the event at the Yahoo! Developer Network

I’ll be speaking at BarCamp Charleston in Charleston, SC on November 13, 2010. I’ll be giving an introduction to Yahoo! Query Language, Yahoo!’s SQL-like language allowing users to query data across web services. I’ve spent a bit of time with it over the past few months, so it’s sure to be packed full of interesting demos.

This will be my first official speaking event where I’ll be representing Yahoo!, my employer. I’ve been at Yahoo! for just over six months now and am loving every minute of it! I’m honored to join the ranks of my fellow Yahoo! Developer Network colleagues, such as Derek Gathright and Jonathan LeBlanc.

If you’re an Atlanta-based reader, I know that a number of members of Atlanta PHP will be attending. Let’s show Charleston how committed Atlanta is to technology here in the Southeast! See you all there.

Goodbye Schematic, hello Yahoo!

After four and a half years, I will be leaving Schematic for Yahoo!. My first day with Yahoo! will be April 5th, where I’ll be working from their Atlanta office. I’m not at liberty to tell you what I’ll actually be working on, though…sorry!

I look forward to joining the ranks of former Schemers Robert Swarthout and Paul Amsbary, and fellow PHP community members such as Derek Gathright and Sara Golemon.

I’m sad to make this move as I’ve seen Schematic grow from ~120 people up to near 400. We’ve added offices around the globe and entire business units. I’ve had the opportunity to work with some incredibly talented developers, technology leaders, project managers, and account managers. I’ve worked on some amazing projects with some of the most appreciative, cutting-edge clients you could ever ask for.

Before joining Schematic, I worked for Community Connect Inc. (now Interactive One) for almost five years, building and maintaining functionality across various social networking sites, such as BlackPlanet.com, AsianAve.com, and MiGente.com. I enjoyed this product-centric environment where any developer could take ownership of a product, then watch it grow and flourish over time. These opportunities are a bit more rare in the agency world, where you’re generally building, delivering, then moving on to the next big effort.

I’m very excited to get back into a product-focused environment. I’ll have the opportunity to sharpen my skills with client-side technologies, along with other languages and platforms. I’m very much looking forward to focusing 100% of my time on architecture and development as I might have gotten a little rusty over the past year or two.

So, thanks, Schematic! It’s been fun, but it’s time for me to perfect my Yahoo! yodel. Best of luck to you!