Go Client Libraries for Redis
Learn about the major Go clients available for Redis.
What is Go?
Go (also referred to as Golang) is a popular programming language known for its performance, simplicity and reliability. Given that they work so well together, it’s not a surprise that there are multiple open-source Go client libraries for Redis! Although that’s a good thing, having multiple choices implies that we need to put in thought when choosing a client to ensure it’s the right fit for our requirements.
Some of the common factors that we might take into consideration when picking a client library include:
Ease of use: Are we looking for a simple, intuitive API with a short learning curve?
Popularly and community support: Are we going to rely on the open-source community and library maintainers to help with queries, accept patches/updates/pull requests, fix issues, and so on?
Performance: If raw performance is what we’re after, then we need to carefully go through existing benchmarks and do testing as well.
With that said, let’s go through a quick overview of some of the Go clients for Redis. All of the libraries chosen for this course have over 500 stars on GitHub. This is not to suggest that number of stars is the only indicator of quality (or popularity), but it gives us a reasonable starting point.
The following Redis clients will be covered in this lesson:
go-redis
redigo
rueidis
The go-redis
client
The go-redis
client is one of the most popular clients with more than 15,500 stars (at the time of writing). In addition to support for all core Redis data types, it has the following:
Great documentation.
Support for instrumentation via OpenTelemetry.
A good ecosystem of features, including Redis-based distributed lock and rate limiter implementations.
Note: The
go-redis
client will be used for the majority of the lessons in this course, unless otherwise noted.
Code sample
Here’s a code snippet to give a general sense of how it works:
client := redis.NewClient(&redis.Options{Addr: "localhost:6379"})ctx := context.Background()err := client.Ping(context.Background()).Err()if err != nil {log.Fatal(err)}defer client.Close()client.Set(ctx, "go-redis", "github.com/go-redis/redis", 0)log.Println("go-redis repo", client.Get(ctx, "go-redis").Val())
Line 1: To get a client handle (
redis.Client
) for a Redis server, use theredis.NewClient
function. Note that this does not actually establish the connection, so it’s a good idea to usePing
(line 4) to ensure you have actually connected successfully.Lines 12–13: Once that’s done, all the operations (
Set
,Get
, etc.) can be invoked from theredis.Client
instance.
The go-redis
API is quite intuitive, the library is stable, active, and has a fairly active community. It’s the recommended library if you’re building Redis applications with Go.
The redigo
client
The redigo
client is a fairly stable and tenured client that supports all the standard Redis data types and features such as transactions, pipelining, etc. It’s also used to implement other Go client libraries like redisearch-go
and the Redis TimeSeries Go client.
Note: The
redigo
client doesn’t support Redis Cluster.
Code sample
Here’s a code snippet to give a general sense of how it works:
c, err := goredis.Dial("tcp", "localhost:6379")if err != nil {log.Fatal(err)}defer c.Close()c.Do("SET", "redigo", "github.com/gomodule/redigo/redis")s, _ := goredis.String(c.Do("GET", "redigo"))log.Println("redigo repo", s)
Line 1: The
Dial
function is used to establish connectivity and returns aredis.Conn
instance.Line 8: After that, we use the
Do
function to create the appropriate commands. In this example, we useSET
andGET
.
With such an API, we lose strong typing; however, it provides flexibility. This flexibility makes it possible to implement features for new Redis versions without having to wait for the client to implement the code (although the implementation efforts depend on the command’s complexity).
The rueidis
client
The rueidis
client is a relatively new and quickly evolving client library. It supports RESP3
protocol, client-side caching, and a variety of Redis modules, such as RedisJSON, RedisBloom, RediSearch, RedisGraph, RedisTimeSeries, RedisAI, and RedisGears. It also has a generic hash or the RedisJSON object mapping capability for OpenTelemetry support of tracing and metrics.
Code sample
Here’s a code snippet to give a general sense of how it works:
c, err := rueidis.NewClient(rueidis.ClientOption{InitAddress: []string{"localhost:6379"},})if err != nil {log.Fatal(err)}ctx := context.Background()c.Do(ctx, c.B().Set().Key("rueids").Value("github.com/rueian/rueidis").Nx().Build()).Error()r, _ := c.Do(ctx, c.B().Get().Key("rueids").Build()).ToString()log.Println("rueidis repo", r)
The rueidis
client adopts an interesting approach.
Line 10: Like the redigo
client, it provides a Do
function, but the way it creates the command is through a Builder function—this retains strong type checking, unlike the redigo
client.
Connecting to Redis with different Go clients
Here’s the complete code for connecting to Redis using all the Go clients mentioned above. Click the “Run” button to execute the code.
package mainimport ("context""log""github.com/go-redis/redis/v8"goredis "github.com/gomodule/redigo/redis""github.com/rueian/rueidis")func main() {goredisClient()redigoClient()rueidsClient()}//example for goredis clientfunc goredisClient() {client := redis.NewClient(&redis.Options{Addr: "localhost:6379"})ctx := context.Background()//ping rediserr := client.Ping(context.Background()).Err()if err != nil {log.Fatal(err)}defer client.Close()log.Println("using go-redis client")//set value for a keyclient.Set(ctx, "go-redis", "github.com/go-redis/redis", 0)log.Println("executed SET")//get value for the keyr := client.Get(ctx, "go-redis").Val()log.Println("executed GET")log.Println("value for go-redis", r)}//example for redigo clientfunc redigoClient() {//establish connection to redisc, err := goredis.Dial("tcp", "localhost:6379")if err != nil {log.Fatal(err)}defer c.Close()log.Println("using redigo client")//set value for a keyc.Do("SET", "redigo", "github.com/gomodule/redigo/redis")log.Println("executed SET")//get value for the keys, _ := goredis.String(c.Do("GET", "redigo"))log.Println("executed GET")log.Println("value for redigo =", s)}//example for rueids clientfunc rueidsClient() {//create new redis client instancec, err := rueidis.NewClient(rueidis.ClientOption{InitAddress: []string{"localhost:6379"},})if err != nil {log.Fatal(err)}defer c.Close()ctx := context.Background()log.Println("using rueidis client")//set value for a keyc.Do(ctx, c.B().Set().Key("rueids").Value("github.com/rueian/rueidis").Nx().Build()).Error()log.Println("executed SET")//get value for the keyr, _ := c.Do(ctx, c.B().Get().Key("rueids").Build()).ToString()log.Println("executed GET")log.Println("value for rueidis =", r)}
The output represents the GET
and SET
operations being executed by different Go clients that we discussed earlier in this lesson. First is the go-redis
client, followed by redigo
, and finally, we have the rueidis
client.