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-redisredigorueidis
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-redisclient 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.NewClientfunction. 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.Clientinstance.
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
redigoclient 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
Dialfunction is used to establish connectivity and returns aredis.Conninstance.Line 8: After that, we use the
Dofunction to create the appropriate commands. In this example, we useSETandGET.
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.