Fast and feature-rich Golang Redis RESP3 client


A Fast Golang Redis RESP3 client does auto pipelining and supports client-side caching.

Features

  • Auto pipeline for non-blocking Redis commands
  • Connection pooling for blocking Redis commands
  • Redis Cluster, Sentinel, Pub/Sub, Redis 7 Sharded Pub/Sub, Streams, TLS, RedisJSON, RedisBloom, RediSearch, RedisGraph, RedisTimeseries, RedisAI, RedisGears
  • IDE-friendly Redis command builder
  • Opt-in client-side caching
  • Generic Hash/RedisJSON Object Mapping with client-side caching and optimistic locking
  • OpenTelemetry tracing and metrics

Requirement

  • Currently, it only supports Redis >= 6.x

Getting Started

package main

import (
	"context"
	"github.com/rueian/rueidis"
)

func main() {
	c, err := rueidis.NewClient(rueidis.ClientOption{
		InitAddress: []string{"127.0.0.1:6379"},
	})
	if err != nil {
		panic(err)
	}
	defer c.Close()

	ctx := context.Background()

	// SET key val NX
	c.Do(ctx, c.B().Set().Key("key").Value("val").Nx().Build()).Error()
	// GET key
	c.Do(ctx, c.B().Get().Key("key").Build()).ToString()
}

Auto Pipeline implemented with Golang

All non-blocking commands sending to a single Redis node are automatically pipelined through one tcp connection, which reduces the overall round trips and system calls, and gives higher throughput.

Benchmark comparison with go-redis v8.11.4

Rueidis has higher throughput than go-redis v8.11.4 across 1, 8, and 64 parallelism settings.

It can achieve ~14x throughput over go-redis in a local benchmark. (see parallelism(64)-key(16)-value(64)-10)

Single Client

client_test_set

Cluster Client

cluster_test_set

Benchmark source code: https://github.com/rueian/rueidis-benchmark

Redis Golang Client Side Caching

The Opt-In mode of server-assisted client-side caching is enabled by default and can be used by calling DoCache() or DoMultiCache() with an explicit client-side TTL.

c.DoCache(ctx, c.B().Hmget().Key("myhash").Field("1", "2").Cache(), time.Minute).ToArray()
c.DoMultiCache(ctx,
    rueidis.CT(c.B().Get().Key("k1").Cache(), 1*time.Minute),
    rueidis.CT(c.B().Get().Key("k2").Cache(), 2*time.Minute))

An explicit client-side TTL is required because Redis server may not send an invalidation message in time when a key is expired on the server. Please follow #6833 and #6867

Although an explicit client-side TTL is required, the DoCache() and DoMultiCache() still sends a PTTL command to the server and ensure that the client-side TTL is not longer than the TTL on the server side.

Users can use IsCacheHit() to verify if the response came from the client side memory.

c.DoCache(ctx, c.B().Get().Key("k1").Cache(), time.Minute).IsCacheHit() == true

If the OpenTelemetry is enabled by the rueidisotel.WithClient(client), then there are also two metrics instrumented:

  • rueidis_do_cache_miss
  • rueidis_do_cache_hits

Benchmark

client_test_get

Benchmark source code: https://github.com/rueian/rueidis-benchmark

Supported Commands by Client Side Caching