Redis assisted client side caching
|It has almost become a standard practice to cache frequently used data in a distributed cache such as redis. Once a distributed cache is introduced into architecture if further performance improvements are required, then the next logical step would be to introduce client side caching. Here the client side caching means caching the data in the application server itself. If there are several instances of applications running, then all these instances should know when the cached entry became stale, Otherwise they will continue to use stale data. Having TTL will provide an upper bound, but if you are looking for immediate notification when a cache entry is updated, then you can checkout redis client tracking. In this post, I will describe how redis client tracking with broadcast mode can be used to implement a client side cache invalidation logic. Even with the client tracking in place, it is still a good idea to have TTL and an upper bound on number entries that can be cached in application.
Redis client tracking in broadcasting mode
In the broadcast mode, Client registers a list of key patterns for which notifications are required. Clients also need to tell on which connection these notifications need to be delivered, this is done by providing the client id of the connection. Every application instance might need to have a dedicated connection to listen for the notifications. Whenever a key that is matching the registered patterns changes, redis will send a notification to the client. Clients can listen for these notifications using standard pubsub clients (for RESP3, pubsub is not required, but it will work).
Here is one possible sequence
- Open a connection
- Get client id
- Enable client tracking
- Subscribe to the channel – __redis__:invalidate
This can be verified used the redis-cli, start two redis-cli instance, the first one will be used for listening the notifications and the second will be used to mutate the keys.
Connection 1 session
127.0.0.1:6379> CLIENT ID
(integer) 49
127.0.0.1:6379> CLIENT TRACKING ON REDIRECT 49 BCAST PREFIX barKey:
OK
127.0.0.1:6379> SUBSCRIBE __redis__:invalidate
1) "subscribe"
2) "__redis__:invalidate"
3) (integer) 1
1) "message"
2) "__redis__:invalidate"
3) 1) "barKey:bar1"
1) "message"
2) "__redis__:invalidate"
3) 1) "barKey:bar2"
Connection 2 session
127.0.0.1:6379> set barKey:bar1 bar1Value
OK
127.0.0.1:6379> set barKey:bar2 bar2Value
OK
127.0.0.1:6379>