Type-safe Redis client for Golang
Go to file
Kailash Nadh 6f96bebac7 Add redis.Scan() to scan results from redis maps into structs.
The package uses reflection to decode default types (int, string
etc.) from Redis map results (key-value pair sequences) into
struct fields where the fields are matched to Redis keys by tags.

Similar to how `encoding/json` allows custom decoders using
`UnmarshalJSON()`, the package supports decoding of arbitrary
types into struct fields by defining a `Decode(string) error`
function on types.

The field/type spec of every struct that's passed to Scan() is
cached in the package so that subsequent scans avoid iteration
and reflection of the struct's fields.
2021-01-28 18:04:38 +05:30
.github Merge pull request #1562 from johejo/golangci-lint_v1.32 2020-11-18 17:53:55 +02:00
example/otel Update example module, tidy 2021-01-16 11:20:03 -08:00
extra Update example module, tidy 2021-01-16 11:20:03 -08:00
internal Add redis.Scan() to scan results from redis maps into structs. 2021-01-28 18:04:38 +05:30
testdata Added backoff retry 2017-05-26 14:33:34 +03:00
.gitignore Introduce metrics capture with OpenTelemetry (#1398) 2020-07-15 12:07:07 +03:00
.golangci.yml Update golangci-lint to v1.32 2020-11-17 23:08:15 +09:00
.prettierrc Add sponsors 2020-06-09 17:59:23 +03:00
.travis.yml Update golangci-lint to v1.32 2020-11-17 23:08:15 +09:00
CHANGELOG.md Move changelog to docs 2020-11-06 16:54:46 +02:00
LICENSE Fix license. 2016-09-12 12:00:28 +00:00
Makefile Update extra 2020-11-21 10:18:39 +02:00
README.md Added test setup document in README.md (#1585) 2020-12-21 08:55:13 +02:00
bench_test.go Add Sentinel RouteBy 2020-09-11 16:06:08 +03:00
cluster.go Fix ReadOnly option in ClusterClient 2021-01-22 09:33:09 +02:00
cluster_commands.go Add ctx as first arg 2020-05-19 08:52:38 +03:00
cluster_test.go Fix Tx pipeline hook 2021-01-09 09:57:46 +02:00
command.go Cleanup 2020-09-24 09:06:17 +03:00
command_test.go Fix race 2020-09-17 12:36:10 +03:00
commands.go Add ScanType command to Scan with 'type' option 2021-01-09 09:20:35 -03:00
commands_test.go Add ScanType command to Scan with 'type' option 2021-01-09 09:20:35 -03:00
doc.go doc: fix outdated reference. 2014-10-07 09:27:55 +03:00
error.go Close the conn on context timeout 2020-12-06 11:14:07 +02:00
example_instrumentation_test.go Reduce dependency chain 2020-09-17 14:32:08 +01:00
example_test.go Add ScanType command to Scan with 'type' option 2021-01-09 09:20:35 -03:00
export_test.go Remove ClusterClient failover tests 2020-09-05 12:16:08 +03:00
go.mod Bump otel 2021-01-19 11:49:05 +02:00
go.sum Bump otel 2021-01-19 11:49:05 +02:00
internal_test.go Fix build 2020-05-21 10:03:09 +03:00
iterator.go Prevent index out of bunds error 2020-08-07 08:05:47 +02:00
iterator_test.go gofumports 2020-07-16 09:52:07 +03:00
main_test.go Close the conn on context timeout 2020-12-06 11:14:07 +02:00
options.go add disable/-1 comment to max retries 2020-12-28 14:47:46 -08:00
options_test.go Add redis prefix to errors 2020-09-28 15:29:35 +03:00
pipeline.go Bump major version 2020-05-19 08:52:38 +03:00
pipeline_test.go Fixes #1386; pipeline.Exec() sometimes returns spurious `StatusCmd` 2020-09-17 10:53:55 -04:00
pool_test.go Port pool fixes 2020-08-15 15:45:15 +03:00
pubsub.go Do not use retry backoff in PubSub 2020-09-17 12:54:48 +03:00
pubsub_test.go Support string array in pubsub message payload 2020-08-21 17:29:37 +08:00
race_test.go Export scripter interface 2021-01-26 11:57:16 +02:00
redis.go Wait for the goroutine to finish 2020-12-06 17:09:22 +02:00
redis_test.go Add hooks to Conn. Fixes #1539 2020-10-17 15:21:09 +03:00
renovate.json Add renovate.json 2020-09-09 06:29:38 +00:00
result.go Fix golangci 2020-07-16 10:01:27 +03:00
ring.go Feature/gofumpt (#1545) 2020-10-22 09:40:20 +03:00
ring_test.go Use Rendezvous in Ring. Thanks @rafaeleyng for initial idea and implementation 2020-06-08 13:22:37 +03:00
script.go Export scripter interface 2021-01-26 11:57:16 +02:00
sentinel.go make error message for unreachable sentinels more clear 2020-12-15 19:25:31 +08:00
sentinel_test.go Make build more stable 2020-09-11 16:56:02 +03:00
tx.go Ensure Watch closes the transaction on panic 2021-01-21 19:29:28 +02:00
tx_test.go Port pool fixes 2020-08-15 15:45:15 +03:00
universal.go Add PoolStats() to UniversalClient 2020-09-29 21:38:01 +05:30
universal_test.go use 3 sentinel instances in unit testing 2020-09-03 12:11:56 -07:00

README.md

Redis client for Golang

Build Status PkgGoDev Documentation Chat

❤️ Uptrace.dev - distributed traces, logs, and errors in one place

Ecosystem

Features

Installation

go-redis supports 2 last Go versions and requires a Go version with modules support. So make sure to initialize a Go module:

go mod init github.com/my/repo

And then install go-redis/v8 (note v8 in the import; omitting it is a popular mistake):

go get github.com/go-redis/redis/v8

Quickstart

import (
    "context"
    "github.com/go-redis/redis/v8"
)

var ctx = context.Background()

func ExampleClient() {
    rdb := redis.NewClient(&redis.Options{
        Addr:     "localhost:6379",
        Password: "", // no password set
        DB:       0,  // use default DB
    })

    err := rdb.Set(ctx, "key", "value", 0).Err()
    if err != nil {
        panic(err)
    }

    val, err := rdb.Get(ctx, "key").Result()
    if err != nil {
        panic(err)
    }
    fmt.Println("key", val)

    val2, err := rdb.Get(ctx, "key2").Result()
    if err == redis.Nil {
        fmt.Println("key2 does not exist")
    } else if err != nil {
        panic(err)
    } else {
        fmt.Println("key2", val2)
    }
    // Output: key value
    // key2 does not exist
}

Look and feel

Some corner cases:

// SET key value EX 10 NX
set, err := rdb.SetNX(ctx, "key", "value", 10*time.Second).Result()

// SET key value keepttl NX
set, err := rdb.SetNX(ctx, "key", "value", redis.KeepTTL).Result()

// SORT list LIMIT 0 2 ASC
vals, err := rdb.Sort(ctx, "list", &redis.Sort{Offset: 0, Count: 2, Order: "ASC"}).Result()

// ZRANGEBYSCORE zset -inf +inf WITHSCORES LIMIT 0 2
vals, err := rdb.ZRangeByScoreWithScores(ctx, "zset", &redis.ZRangeBy{
    Min: "-inf",
    Max: "+inf",
    Offset: 0,
    Count: 2,
}).Result()

// ZINTERSTORE out 2 zset1 zset2 WEIGHTS 2 3 AGGREGATE SUM
vals, err := rdb.ZInterStore(ctx, "out", &redis.ZStore{
    Keys: []string{"zset1", "zset2"},
    Weights: []int64{2, 3}
}).Result()

// EVAL "return {KEYS[1],ARGV[1]}" 1 "key" "hello"
vals, err := rdb.Eval(ctx, "return {KEYS[1],ARGV[1]}", []string{"key"}, "hello").Result()

// custom command
res, err := rdb.Do(ctx, "set", "key", "value").Result()

Run the test

go-redis will start a redis-server and run the test cases.

The paths of redis-server bin file and redis config file are definded in main_test.go:

var (
	redisServerBin, _  = filepath.Abs(filepath.Join("testdata", "redis", "src", "redis-server"))
	redisServerConf, _ = filepath.Abs(filepath.Join("testdata", "redis", "redis.conf"))
)

For local testing, you can change the variables to refer to your local files, or create a soft link to the corresponding folder for redis-server and copy the config file to testdata/redis/:

ln -s /usr/bin/redis-server ./go-redis/testdata/redis/src
cp ./go-redis/testdata/redis.conf ./go-redis/testdata/redis/

Lastly, run:

go test

See also