“There are only two hard things in Computer Science: cache invalidation and naming things.” — Phil Karlton
Mr. Karlton was not wrong. In my day-to-day job, cache invalidation is something that can easily disrupt releases – the fact that the result from an API is cached can be easily forgotten, for example. It has often caused us to pause and re-evaluate exactly what our applications are doing. Some of our APIs are quite static in nature and are cached appropriately (general rule of thumb is that more static data is cached for longer periods of time). When it comes to update these APIs, there are often many layers of cache to bust through in order to prune stale data. If we forget to clear one cache, the stale data can again propagate to all the other caches in the stash. Not cool.
Not unlike an onion, this can definitely cause tears.
Memcache & Redis
Invalidating keys in redis is relatively simple via redis-cli:
redis-cli KEYS "session:*" | xargs redis-cli DEL
memcached on the other hand does not support namespaced deletes, nor does it have a tool to interact with the server. The only real way to interact with the server is via telnet or similar tool via TCP/IP (such as nc). This caused a desire to write a tool to invalidate cache quickly so that I could test these problem APIs more effectively. Below is the source code (a bash script) – it requires netcat to be installed and within your path.
To use this script, make sure it is executable and pass a regular expression in as the first argument. As an example, let’s invalidate all keys that start with session:
chmod a+x memcache_invalidator ./memcache_invalidator ^session
Here is some sample output, showing that we have deleted two keys (that I added for testing purposes) from local memcache:
jonnu@onion:$ ./memcache_invalidator ^session Invalidating keys on: 127.0.0.1:11211 Searching for : ^session DELETING: session_9fc9575c7eb47fbcdb39c2a872ea74d8 DELETING: session_2bdace452a1904970c457f7ddfd6a132 DONE
Suggestions on how to improve this tool are welcome – either comment here or just fork & send me a merge request on github.