Say you have a user who has many results, in a one to many relationship and can only see the results he/she has permission for. This means every user can potentially have a different result set, hence a different cache value so 1 key per user. We can very easily create a cache key called userid_results where userid is the unique ID of the user making the request. Works well....until you add a new result. If we have 1000 users, how do we invalidate all of those cache keys? The following mechanism solves that issue:
- Create a version cache key named "results_version". This cache key will simply hold the current version of the results table. Whenever we insert a new record we increment the version.
- Create a cache key that uses this version. So in your code you will have to first fetch the version key (memcache->get(results_version)). Then use this value to generate the user cache key like user_results_results_version which would end up something like user_results_1003.
- When a new record is inserted we increment the results_version key. This sets it to 1004 in our example
- The next request for content will try to access user_results_1004, but this cache key does not exist yet so we will force a cache_miss, hit our DB or content source, then cache the result.
Very ingenious! I was thinking about setting an overall timestamp of last revision, but I was missing the importance of adding it to the key!!!
I have extended that idea to support multiple namespace binding to same data and to support immediatelly deletion of obsoleted keys.
You can check it in my blogger, maybe you find it useful too:
Post a Comment