Go Redis专题精讲

Go Redis专题精讲

一、介绍

https://github.com/redis/go-redis

1.1、客户端列表

  go-redis提供各种类型的客户端:

    • Redis 单节点客户端
    • Redis 集群客户端
    • Redis 哨兵客户端
    • Redis 分片客户端
    • Redis 通用客户端

  go-redis 也可以用于 kvrocks, kvrocks 是分布式键值 NoSQL 数据库,使用 RocksDB 作为存储引擎,兼容 redis 协议。

二、入门

2.1、Installation

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

1
go mod init github.com/my/repo

Then install go-redis/v9:

1
go get github.com/redis/go-redis/v9 

2.2、QuickStart

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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
}

通过在 Options 结构中添加 protocol 选项,可以修改以上内容来指定 RESP 协议的版本:

1
2
3
4
5
6
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
})

2.3、Connecting via a redis url

Go-redis 还支持通过 redis uri 规范进行连接。下面的示例演示如何使用字符串轻松地配置连接,并遵循此规范:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import (
    "context"
    "fmt"
 
    "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)
}

2.4、使用 TLS

  需要手动设置 tls.conf:

1
2
3
4
5
6
7
rdb := redis.NewClient(&redis.Options{
    TLSConfig: &tls.Config{
        MinVersion: tls.VersionTLS12,
        ServerName: "you domain",
        //Certificates: []tls.Certificate{cert}
    },
})

如果你使用的是域名连接,且遇到了类似 x509: cannot validate certificate for xxx.xxx.xxx.xxx because it doesn't contain any IP SANs的错误,应该在 ServerName 中指定你的域名:

1
2
3
4
5
6
rdb := redis.NewClient(&redis.Options{
    TLSConfig: &tls.Config{
        MinVersion: tls.VersionTLS12,
        ServerName: "你的域名",
    },
})

2.5、SSH 方式

使用 SSH 协议连接:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
sshConfig := &ssh.ClientConfig{
    User:            "root",
    Auth:            []ssh.AuthMethod{ssh.Password("password")},
    HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    Timeout:         15 * time.Second,
}
 
sshClient, err := ssh.Dial("tcp", "remoteIP:22", sshConfig)
if err != nil {
    panic(err)
}
 
rdb := redis.NewClient(&redis.Options{
    Addr: net.JoinHostPort("127.0.0.1", "6379"),
    Dialer: func(ctx context.Context, network, addr string) (net.Conn, error) {
        return sshClient.Dial(network, addr)
    },
    // SSH不支持超时设置,在这里禁用
    ReadTimeout:  -1,
    WriteTimeout: -1,
})
 
   
  

2.6、Context 上下文

go-redis 支持 Context,你可以使用它控制超时或者传递一些数据, 也可以监控 go-redis 性能。

1
ctx := context.Background()

2.7、执行 Redis 命令

1
2
val, err := rdb.Get(ctx, "key").Result()
fmt.Println(val)
你也可以分别访问值和错误:
1
2
3
4
get := rdb.Get(ctx, "key")
fmt.Println(get.Val(), get.Err())
 
  

2.8、执行尚不支持的命令 

可以使用 Do() 方法执行尚不支持或者任意命令:

1
2
3
4
5
6
7
8
9
val, err := rdb.Do(ctx, "get", "key").Result()
if err != nil {
    if err == redis.Nil {
        fmt.Println("key does not exists")
        return
    }
    panic(err)
}
fmt.Println(val.(string))  

三、Redis集群

go-redis 支持 Redis Cluster 客户端,如下面示例,redis.ClusterClient 表示集群对象,对集群内每个 redis 节点使用 redis.Client 对象进行通信,每个 redis.Client 会拥有单独的连接池。
连接到 redis 集群示例,更多配置参数,请参照:https://redis.uptrace.dev/zh/guide/go-redis-option.html#redis-client
1
2
3
4
5
import "github.com/redis/go-redis/v9"
 
rdb := redis.NewClusterClient(&redis.ClusterOptions{
    Addrs: []string{":7000", ":7001", ":7002", ":7003", ":7004", ":7005"},
})
遍历每个节点:
1
2
3
4
5
6
err := rdb.ForEachShard(ctx, func(ctx context.Context, shard *redis.Client) error {
    return shard.Ping(ctx).Err()
})
if err != nil {
    panic(err)
}

只遍历主节点请使用: ForEachMaster, 只遍历从节点请使用: ForEachSlave

你也可以自定义的设置每个节点的初始化:

1
2
3
4
5
6
7
8
9
rdb := redis.NewClusterClient(&redis.ClusterOptions{
    NewClient: func(opt *redis.Options) *redis.NewClient {
        user, pass := userPassForAddr(opt.Addr)
        opt.Username = user
        opt.Password = pass
 
        return redis.NewClient(opt)
    },
})
posted @   左扬  阅读(70)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
levels of contents
点击右上角即可分享
微信分享提示