Redis 6 server-assisted client-side caching with Golang

Ruian
Dev Genius
Published in
3 min readJan 22, 2022

--

Most people use Redis as a remote cache store because it is fast.

Redis 6 can make it even faster, from the users’ point of view, by eliminating unnecessary network roundtrips.

Server-assisted client-side caching

The technique is simple. Redis 6 will keep track of what keys the client requested, and notify the client if the keys’ values are changed.

Therefore, clients can now reuse responses without consulting Redis through the network until receiving the corresponding invalidation notifications. This new feature is called server-assisted client-side caching.

More Detail: https://redis.io/topics/client-side-caching

Although the technique is simple, it requires either upgrading to new RESP3 protocol, or making a trick on the RESP2 Pub/Sub channel to receive the notifications. Both options are not easy for an existing client library to implement.

It has been almost two years since Redis 6 was released in 2020. I found it is still hard to use this powerful new feature with the existing Golang client library. So, I decide to make a new client implementation on my own.

Rueidis: A Fast Golang Redis RESP3 Client

Thanks to the simplicity of RESP3 and auto pipelining technique. The new client library generally has higher throughput than the existing one. Here is the benchmark comparison on my Macbook M1 Pro.

Full Benchmark Source Code: https://github.com/rueian/rueidis-benchmark

The service-assisted client side caching performs very well if cache hit, because there is no network commutation. It takes just about 165ns on average to retrieve a record from the client’s memory cache on my laptop.

Even without client side caching, the new library can achieve 14x throughput over the existing one on local benchmark. See the parallelism(64)-key(16)-value(64)-10 case.

Go get github.com/rueian/rueidis

Here is an example that how to use server-assisted client-side caching with the new client library:

Error handing is omitted

The DoCache() the method uses server-assisted client-side caching under the hood, and it takes 3 parameters:

  1. The context, which supports OpenTelemetry traces.
  2. The Redis command, which should be built from the command builder client.B().
  3. The client-side TTL is used in combination with PTTL to make sure that the TTL on the client-side is not longer than on the Redis side.

In addition, users can use the IsCacheHit() to check if the response came from the client-side memory.

If the OpenTelemetry integration is enabled, there are also two metrics for users to observe the cache hit ratio, which are rueidis_do_cache_hits and rueidis_do_cache_miss.

Rueidis also supports other features, such as Redis Cluster, Pub/Sub, Streams, Lua, Transaction.

Popular Redis Modules are also supported. For example: RedisBloom, RedisJSON, RediSearch, RedisTimeseries.

Rueidis was born just a few months ago, but I will continue to make it better. Feedback, issue reports, PRs, and Stars are all appreciated. Thanks.

--

--