1<p align="center">
2  <a href="https://uptrace.dev/?utm_source=gh-redis&utm_campaign=gh-redis-banner1">
3    <img src="https://raw.githubusercontent.com/uptrace/roadmap/master/banner1.png" alt="All-in-one tool to optimize performance and monitor errors & logs">
4  </a>
5</p>
6
7# Redis client for Golang
8
9![build workflow](https://github.com/go-redis/redis/actions/workflows/build.yml/badge.svg)
10[![PkgGoDev](https://pkg.go.dev/badge/github.com/go-redis/redis/v8)](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc)
11[![Documentation](https://img.shields.io/badge/redis-documentation-informational)](https://redis.uptrace.dev/)
12[![Chat](https://discordapp.com/api/guilds/752070105847955518/widget.png)](https://discord.gg/rWtp5Aj)
13
14- Join [Discord](https://discord.gg/rWtp5Aj) to ask questions.
15- [Documentation](https://redis.uptrace.dev)
16- [Reference](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc)
17- [Examples](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#pkg-examples)
18- [RealWorld example app](https://github.com/uptrace/go-treemux-realworld-example-app)
19
20My other projects:
21
22- [Bun](https://bun.uptrace.dev) - fast and simple SQL client for PostgreSQL, MySQL, and SQLite.
23- [treemux](https://github.com/vmihailenco/treemux) - high-speed, flexible, tree-based HTTP router
24  for Go.
25
26## Ecosystem
27
28- [Redis Mock](https://github.com/go-redis/redismock).
29- [Distributed Locks](https://github.com/bsm/redislock).
30- [Redis Cache](https://github.com/go-redis/cache).
31- [Rate limiting](https://github.com/go-redis/redis_rate).
32
33## Features
34
35- Redis 3 commands except QUIT, MONITOR, and SYNC.
36- Automatic connection pooling with
37  [circuit breaker](https://en.wikipedia.org/wiki/Circuit_breaker_design_pattern) support.
38- [Pub/Sub](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#PubSub).
39- [Transactions](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client-TxPipeline).
40- [Pipeline](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client-Pipeline) and
41  [TxPipeline](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client-TxPipeline).
42- [Scripting](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#Script).
43- [Timeouts](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#Options).
44- [Redis Sentinel](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#NewFailoverClient).
45- [Redis Cluster](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#NewClusterClient).
46- [Cluster of Redis Servers](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-NewClusterClient--ManualSetup)
47  without using cluster mode and Redis Sentinel.
48- [Ring](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#NewRing).
49- [Instrumentation](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#ex-package--Instrumentation).
50
51## Installation
52
53go-redis supports 2 last Go versions and requires a Go version with
54[modules](https://github.com/golang/go/wiki/Modules) support. So make sure to initialize a Go
55module:
56
57```shell
58go mod init github.com/my/repo
59```
60
61And then install go-redis/v8 (note _v8_ in the import; omitting it is a popular mistake):
62
63```shell
64go get github.com/go-redis/redis/v8
65```
66
67## Quickstart
68
69```go
70import (
71    "context"
72    "github.com/go-redis/redis/v8"
73)
74
75var ctx = context.Background()
76
77func ExampleClient() {
78    rdb := redis.NewClient(&redis.Options{
79        Addr:     "localhost:6379",
80        Password: "", // no password set
81        DB:       0,  // use default DB
82    })
83
84    err := rdb.Set(ctx, "key", "value", 0).Err()
85    if err != nil {
86        panic(err)
87    }
88
89    val, err := rdb.Get(ctx, "key").Result()
90    if err != nil {
91        panic(err)
92    }
93    fmt.Println("key", val)
94
95    val2, err := rdb.Get(ctx, "key2").Result()
96    if err == redis.Nil {
97        fmt.Println("key2 does not exist")
98    } else if err != nil {
99        panic(err)
100    } else {
101        fmt.Println("key2", val2)
102    }
103    // Output: key value
104    // key2 does not exist
105}
106```
107
108## Look and feel
109
110Some corner cases:
111
112```go
113// SET key value EX 10 NX
114set, err := rdb.SetNX(ctx, "key", "value", 10*time.Second).Result()
115
116// SET key value keepttl NX
117set, err := rdb.SetNX(ctx, "key", "value", redis.KeepTTL).Result()
118
119// SORT list LIMIT 0 2 ASC
120vals, err := rdb.Sort(ctx, "list", &redis.Sort{Offset: 0, Count: 2, Order: "ASC"}).Result()
121
122// ZRANGEBYSCORE zset -inf +inf WITHSCORES LIMIT 0 2
123vals, err := rdb.ZRangeByScoreWithScores(ctx, "zset", &redis.ZRangeBy{
124    Min: "-inf",
125    Max: "+inf",
126    Offset: 0,
127    Count: 2,
128}).Result()
129
130// ZINTERSTORE out 2 zset1 zset2 WEIGHTS 2 3 AGGREGATE SUM
131vals, err := rdb.ZInterStore(ctx, "out", &redis.ZStore{
132    Keys: []string{"zset1", "zset2"},
133    Weights: []int64{2, 3}
134}).Result()
135
136// EVAL "return {KEYS[1],ARGV[1]}" 1 "key" "hello"
137vals, err := rdb.Eval(ctx, "return {KEYS[1],ARGV[1]}", []string{"key"}, "hello").Result()
138
139// custom command
140res, err := rdb.Do(ctx, "set", "key", "value").Result()
141```
142
143## Run the test
144
145go-redis will start a redis-server and run the test cases.
146
147The paths of redis-server bin file and redis config file are defined in `main_test.go`:
148
149```
150var (
151	redisServerBin, _  = filepath.Abs(filepath.Join("testdata", "redis", "src", "redis-server"))
152	redisServerConf, _ = filepath.Abs(filepath.Join("testdata", "redis", "redis.conf"))
153)
154```
155
156For local testing, you can change the variables to refer to your local files, or create a soft link
157to the corresponding folder for redis-server and copy the config file to `testdata/redis/`:
158
159```
160ln -s /usr/bin/redis-server ./go-redis/testdata/redis/src
161cp ./go-redis/testdata/redis.conf ./go-redis/testdata/redis/
162```
163
164Lastly, run:
165
166```
167go test
168```
169