Namespacing keys in Kredis
posted by Ayush Newatia
6 October, 2021
Kredis is a library that provides an abstraction of higher level data structures for Redis. It’s really useful and will be included in Rails 7.
I like to namespace all my keys in Redis because it prevents clashes between keys from multiple apps in development locally. It also opens the door to sharing a single Redis instance between multiple apps in production. That’s usually not a good idea but for a few side projects, it might be a viable and economical choice.
At first glance it seems like it’s really easy to add a namespace to keys in Kredis. There’s a Kredis.namespace=
method. However it’s primarily meant to prevent clashes in parallel testing. If you look at the implementation, it looks like:
def namespace=(namespace)
Thread.current[:kredis_namespace] = namespace
end
It only sets the namespace on the current thread. That’s fine when using a single threaded process like the Rails Console. But in a multi-threaded process like Sidekiq, you’re going to be in trouble.
One approach to solve this could be setting the namespace on every thread. However that’s pretty messy.
The redis-namespace gem
A clean way to namespacing Kredis is to install the redis-namespace gem. It provides a namespaced proxy to an underlying Redis connection.
To configure Kredis to use this proxy instead of creating its own connection; we need to add the following line in application.rb
:
config.kredis.connector = ->(config) {
Redis::Namespace.new("my_app:kredis", redis: Redis.new(config))
}
Now all keys we set with Kredis will be namespaced with “my_app:kredis”. This also makes it easier to filter keys if you’re using a GUI tool like Medis to view your Redis data.