Go-redis是Go语言的官方Redis客户端库

Redis client for Go

go-redis 是 Go 编程语言的官方 Redis 客户端库。它提供了与 Redis 服务器交互的简单接口。

支持的版本

go-redis 中,我们计划支持 Redis 的最新三个版本。目前,这意味着我们支持:

  • Redis 7.2 - 使用 Redis Stack 7.2 实现模块支持
  • Redis 7.4 - 使用 Redis Stack 7.4 实现模块支持
  • Redis 8.0 - 使用包含模块的 Redis CE 8.0
  • Redis 8.2 - 使用包含模块的 Redis CE 8.2

虽然 go.mod 声明它至少需要 go 1.18 版本,我们的 CI 配置为针对 Redis 的所有三个版本和最新的两个 Go 版本(1.23
1.24) 运行测试。我们观察到,某些模块相关的测试可能无法通过 Redis Stack 7.2 的测试,并且某些命令在 Redis CE 8.0 中有所更改。
如果您遇到任何问题,请参考文档和测试。我们计划在下一个版本中将 go.mod 中的 go 版本更新为 go 1.24

如何使用 Redis?

在 Redis 大学免费学习

使用 Redis Launchpad 更快地构建

试用 Redis Cloud

深入了解开发者教程

加入 Redis 社区

在 Redis 工作

文档

资源

生态系统

此客户端也适用于Kvrocks,一个分布式键值 NoSQL 数据库,使用 RocksDB 作为存储引擎,并兼容 Redis 协议。

功能

安装

go-redis 支持最近两个 Go 版本,并且需要一个支持 模块 的 Go 版本。因此,请确保初始化 Go 模块:

shell 复制代码
go mod init github.com/my/repo

Then install go-redis/v9:

shell 复制代码
go get github.com/redis/go-redis/v9

Quickstart

go 复制代码
import (
    "context"
    "fmt"

    "github.com/redis/go-redis/v9"
)

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
}

身份验证

Redis 客户端支持多种提供身份验证凭据的方式,并具有明确的优先级顺序。以下是可用的选项:

1. 流式凭据提供程序(最高优先级)- 实验性功能

流式凭据提供程序允许在连接生命周期内动态更新凭据。这对于托管身份服务和基于令牌的身份验证尤其有用。

go 复制代码
type StreamingCredentialsProvider interface {
    Subscribe(listener CredentialsListener) (Credentials, UnsubscribeFunc, error)
}

type CredentialsListener interface {
    OnNext(credentials Credentials)  // Called when credentials are updated
    OnError(err error)              // Called when an error occurs
}

type Credentials interface {
    BasicAuth() (username string, password string)
    RawCredentials() string
}

Example usage:

go 复制代码
rdb := redis.NewClient(&redis.Options{
    Addr: "localhost:6379",
    StreamingCredentialsProvider: &MyCredentialsProvider{},
})

**注意:**流式凭据提供程序可与 go-redis-entraid 一起使用,以启用 Entra ID(以前称为 Azure AD)身份验证。这允许与 Azure 的托管身份服务和基于令牌的身份验证无缝集成。

Example with Entra ID:

go 复制代码
import (
    "github.com/redis/go-redis/v9"
    "github.com/redis/go-redis-entraid"
)

// Create an Entra ID credentials provider
provider := entraid.NewDefaultAzureIdentityProvider()

// Configure Redis client with Entra ID authentication
rdb := redis.NewClient(&redis.Options{
    Addr: "your-redis-server.redis.cache.windows.net:6380",
    StreamingCredentialsProvider: provider,
    TLSConfig: &tls.Config{
        MinVersion: tls.VersionTLS12,
    },
})

2. 基于上下文的凭证提供程序

基于上下文的提供程序允许在每次操作时使用上下文确定凭证。

go 复制代码
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
CredentialsProviderContext: func(ctx context.Context) (string, string, error) {
// 返回用户名、密码和任何错误
return "user", "pass", nil
},
})

3. 常规凭证提供程序

一个基于函数的简单提供程序,返回静态凭证。

go 复制代码
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
CredentialsProvider: func() (string, string) {
// 返回用户名和密码
return "user", "pass"
},
})

4. 用户名/密码字段(最低优先级)

提供凭据的最基本方法是通过选项中的 UsernamePassword 字段。

go 复制代码
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Username: "user",
Password: "pass",
})

优先级

客户端将按以下优先级顺序使用凭证:

  1. 流式凭证提供程序(如果已设置)
  2. 基于上下文的凭证提供程序(如果已设置)
  3. 常规凭证提供程序(如果已设置)
  4. 用户名/密码字段(如果已设置)

如果以上均未设置,客户端将尝试在未进行身份验证的情况下进行连接。

协议版本

客户端支持 RESP2 和 RESP3 协议。您可以在选项中指定协议版本:

go 复制代码
rdb := redis.NewClient(&redis.Options{
    Addr:     "localhost:6379",
    Password: "", // no password set
    DB:       0,  // use default DB
    Protocol: 3,  // specify 2 for RESP 2 or 3 for RESP 3
})

通过 redis url 连接

go-redis 还支持通过 redis uri 规范 进行连接。
以下示例演示了如何遵循此规范,使用字符串轻松配置连接。

go 复制代码
import (
    "github.com/redis/go-redis/v9"
)

func ExampleClient() *redis.Client {
    url := "redis://user:password@localhost:6379/0?protocol=3"
    opts, err := redis.ParseURL(url)
    if err != nil {
        panic(err)
    }

    return redis.NewClient(opts)
}

使用 OpenTelemetry 进行测量

go 复制代码
import (
    "github.com/redis/go-redis/v9"
    "github.com/redis/go-redis/extra/redisotel/v9"
    "errors"
)

func main() {
    ...
    rdb := redis.NewClient(&redis.Options{...})

    if err := errors.Join(redisotel.InstrumentTracing(rdb), redisotel.InstrumentMetrics(rdb)); err != nil {
        log.Fatal(err)
    }

缓冲区大小配置

go-redis 默认使用 0.5MiB 的读写缓冲区以获得最佳性能。对于高吞吐量应用程序或大型管道,您可以自定义缓冲区大小:

go 复制代码
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
ReadBufferSize: 1024 * 1024, // 1MiB 读取缓冲区
WriteBufferSize: 1024 * 1024, // 1MiB 写入缓冲区
})

高级配置

go-redis 支持扩展客户端标识阶段,允许项目发送自定义客户端标识。

默认客户端标识

默认情况下,go-redis 会在连接过程中自动发送客户端库名称和版本。此功能在 redis-server 7.2 及更高版本中可用。因此,该命令是“触发后不管”的,这意味着如果 Redis 服务器不支持此功能,它应该会静默失败。

禁用身份验证

当不需要连接身份验证或需要明确禁用连接身份验证时,可以使用“DisableIdentity”配置选项。
最初存在拼写错误,该选项被命名为“DisableIndentity”而不是“DisableIdentity”。拼写错误的选项已被标记为“已弃用”,并将在本库的 V10 版本中移除。
虽然目前这两个选项都可以使用,但正确的选项是“DisableIdentity”。已弃用的选项将在本库的 V10 版本中移除,因此请使用正确的选项名称以避免出现任何问题。

要禁用验证,请在 Redis 客户端选项中将 DisableIdentity 选项设置为 true

go 复制代码
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "",
DB: 0,
DisableIdentity: true, // 连接时禁用 set-info
})

RediSearch 命令的 RESP3 结构不稳定

在使用 RESP3 将 Redis 与应用程序功能集成时,需要注意的是,某些响应结构尚未最终确定。对于搜索和查询结果等更复杂的结构尤其如此。我们建议在使用搜索和查询功能时使用 RESP2,但我们计划在未来的版本中稳定基于 RESP3 的 API。您可以在即将发布的发行说明中找到更多指导。

要启用不稳定的 RESP3,请在客户端配置中设置以下选项:

go 复制代码
redis.NewClient(&redis.Options{
UnstableResp3: true,
})

**注意:**启用 UnstableResp3 模式后,需要使用 RawResult() 和 RawVal() 来检索原始数据。
由于原始响应是不稳定搜索命令的唯一选项,因此 Val() 和 Result() 调用不会对它们产生任何影响:

go 复制代码
res1, err := client.FTSearchWithArgs(ctx, "txt", "foo bar", &redis.FTSearchOptions{}).RawResult()
val1 := client.FTSearchWithArgs(ctx, "txt", "foo bar", &redis.FTSearchOptions{}).RawVal()

在 Redis-Search 模块中,默认方言为 2。如果需要,您可以在查询中使用相应的配置明确指定其他方言。

重要提示:请注意,查询方言可能会影响返回的结果。如果需要,您可以通过在要执行的命令的参数中传递所需的方言来恢复到其他方言版本。
例如:

复制代码
res2, err := rdb.FTSearchWithArgs(ctx,
"idx:bicycle",
"@pickup_zone:[CONTAINS $bike]",
&redis.FTSearchOptions{
Params: map[string]interface{}{
"bike": "POINT(-0.1278 51.5074)",
},
DialectVersion: 3,
},
).Result()

您可以在查询方言文档中找到更多详细信息。

自定义缓冲区大小

在 v9.12 之前,缓冲区大小为 Go 默认的 4096 字节。从 v9.12 开始,
go-redis 默认使用 256KiB 的读写缓冲区以获得最佳性能。
对于高吞吐量应用程序或大型管道,您可以自定义缓冲区大小:

go 复制代码
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
ReadBufferSize: 1024 * 1024, // 1MiB 读取缓冲区
WriteBufferSize: 1024 * 1024, // 1MiB 写入缓冲区
})

重要提示:如果您在使用默认缓冲区大小时遇到任何问题,请尝试将其设置为 Go 默认的 4096 字节。

贡献

我们欢迎您为 go-redis 库做出贡献!如果您有错误修复、功能请求或改进,请在 GitHub 上提交问题或拉取请求。
感谢您帮助我们改进 go-redis,使其更适合所有人。
如果您有兴趣为 go-redis 库做出贡献,请查看我们的贡献指南 (CONTRIBUTING.md),了解更多关于如何开始的信息。

外观和体验

一些特殊情况:

go 复制代码
// 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()

运行测试

go-redis 将启动 redis 服务器并运行测试用例。

redis-server bin 文件和 redis 配置文件的路径在 main_test.go 文件中定义:

go 复制代码
var (
redisServerBin, _ = filepath.Abs(filepath.Join("testdata", "redis", "src", "redis-server"))
redisServerConf, _ = filepath.Abs(filepath.Join("testdata", "redis", "redis.conf"))
)

对于本地测试,您可以更改变量以引用本地文件,或者创建指向 redis-server 相应文件夹的软链接,并将配置文件复制到 testdata/redis/ 目录:

shell 复制代码
ln -s /usr/bin/redis-server ./go-redis/testdata/redis/src
cp ./go-redis/testdata/redis.conf ./go-redis/testdata/redis/

最后,运行:

shell 复制代码
go test

另一种选择是使用已经运行的 redis 运行你的特定测试。以下示例测试了运行在 9999 端口的 redis:

shell 复制代码
REDIS_PORT=9999 go test <你的选项>

另请参阅

关于项目

go-redis 是 Go 编程语言的官方 Redis 客户端库。它提供了与 Redis 服务器交互的简单接口。
BSD-2-Clause
Golang
21,577
2504
258
2012-07-25
2025-10-08

增长趋势 - stars