Golang Redis 入门

安装

go-redis 支持最新的两个 Go 版本,并且仅适用于 Go 模块在新窗口中打开。所以首先你需要初始化一个 Go 模块

go mod init github.com/my/repo

要安装 go-redis/v9

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

连接到 Redis 服务器

要连接到 Redis 服务器

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

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

另一种常见的方法是使用连接字符串

opt, err := redis.ParseURL("redis://<user>:<pass>@localhost:6379/<db>")
if err != nil {
	panic(err)
}

rdb := redis.NewClient(opt)

使用 TLS

要启用 TLS/SSL,你需要提供一个空的 tls.Config。如果你使用的是私有证书,你需要 指定在新窗口中打开 它们在 tls.Config 中。

rdb := redis.NewClient(&redis.Options{
	TLSConfig: &tls.Config{
		MinVersion: tls.VersionTLS12,
		//Certificates: []tls.Certificate{cert}
	},
})

如果你收到 x509: cannot validate certificate for xxx.xxx.xxx.xxx because it doesn't contain any IP SANs 错误,尝试设置 ServerName 选项

rdb := redis.NewClient(&redis.Options{
	TLSConfig: &tls.Config{
		MinVersion: tls.VersionTLS12,
		ServerName: "your.domain.com",
	},
})

通过 SSH

要通过 SSH 通道连接

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)
	},
	// Disable timeouts, because SSH does not support deadlines.
	ReadTimeout:  -1,
	WriteTimeout: -1,
})

dial tcp: i/o 超时

当 go-redis 无法连接到 Redis 服务器时,例如,当服务器宕机或端口被防火墙保护时,你会收到 dial tcp: i/o timeout 错误。要检查 Redis 服务器是否在端口上监听,请在运行 go-redis 客户端的主机上运行 telnet 命令

telnet localhost 6379
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused

如果你使用 Docker、Istio 或任何其他服务网格/边车,请确保应用程序在容器完全可用后启动,例如,通过配置 健康检查在新窗口中打开 与 Docker 和 holdApplicationUntilProxyStarts 与 Istio。

上下文

每个 Redis 命令都接受一个上下文,你可以使用它来设置 超时 或传播一些信息,例如,追踪上下文

ctx := context.Background()

执行命令

要执行一个命令

val, err := rdb.Get(ctx, "key").Result()
fmt.Println(val)

或者,你可以保存命令,并在稍后分别访问值和错误

get := rdb.Get(ctx, "key")
fmt.Println(get.Val(), get.Err())

执行不支持的命令

要执行任意/自定义命令

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))

Do 返回一个 Cmd在新窗口中打开,它有一堆助手来处理 interface{}

// Text is a shortcut for get.Val().(string) with proper error handling.
val, err := rdb.Do(ctx, "get", "key").Text()
fmt.Println(val, err)

助手的完整列表

s, err := cmd.Text()
flag, err := cmd.Bool()

num, err := cmd.Int()
num, err := cmd.Int64()
num, err := cmd.Uint64()
num, err := cmd.Float32()
num, err := cmd.Float64()

ss, err := cmd.StringSlice()
ns, err := cmd.Int64Slice()
ns, err := cmd.Uint64Slice()
fs, err := cmd.Float32Slice()
fs, err := cmd.Float64Slice()
bs, err := cmd.BoolSlice()

redis.Nil

go-redis 导出 redis.Nil 错误,并在 Redis 服务器以 (nil) 响应时返回它。你可以使用 redis-cli 来检查 Redis 返回什么响应。

在以下示例中,我们使用 redis.Nil 来区分空字符串回复和空回复(键不存在)

val, err := rdb.Get(ctx, "key").Result()
switch {
case err == redis.Nil:
	fmt.Println("key does not exist")
case err != nil:
	fmt.Println("Get failed", err)
case val == "":
	fmt.Println("value is empty")
}

GET 不是唯一返回空回复的命令,例如,BLPOPZSCORE 也可以返回 redis.Nil

Conn

Conn 代表单个 Redis 连接,而不是连接池。优先从 Client 运行命令,除非有对连续单个 Redis 连接的特定需求。

cn := rdb.Conn(ctx)
defer cn.Close()

if err := cn.ClientSetName(ctx, "myclient").Err(); err != nil {
	panic(err)
}

name, err := cn.ClientGetName(ctx).Result()
if err != nil {
	panic(err)
}
fmt.Println("client name", name)

另请参阅