前言
本文主要是针对go-redis框架从安装到使用入门, 在实际使用中一定要多参考官方API。
官方API地址:pkg.go.dev/github.com/...
Redis环境部署
在docker中运行如下命令:
Go
docker run --name redis -p 6379:6379 -v your_path/Data/redis/data:/data -d --restart=always redis:latest redis-server --appendonly yes --requirepass "your_password"
执行完后将会得到一个docker容器。
安装go-redis库
Bash
go get github.com/go-redis/redis/v8
redis连接方式
- 普通连接模式
Go
//1. go-redis库使用redis.NewClient函数连接redis服务器
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // 密码
DB: 0, // 数据库
PoolSize: 20, // 连接池大小
})
//2. redis.ParseURL 函数从表示数据源的字符串中解析得到 Redis 服务器的配置信息。
opt, err := redis.ParseURL("redis://<user>:<pass>@localhost:6379/<db>")
if err != nil {panic(err)
}
rdb := redis.NewClient(opt)
- TLS连接模式
如果使用的是 TLS 连接方式,则需要使用 tls.Config 配置。
Go
rdb := redis.NewClient(&redis.Options{
TLSConfig: &tls.Config{
MinVersion: tls.VersionTLS12,
// Certificates: []tls.Certificate{cert},
// ServerName: "your.domain.com",
},
})
- Redis Sentinel模式
Sentinel是Redis在主从复制基础上构建的一套高可用解决方案。 不断监听下游服务是不是可用,在主从之间切换模式。
使用下面的命令连接到由 Redis Sentinel 管理的 Redis 服务器。
Go
rdb := redis.NewFailoverClient(&redis.FailoverOptions{
MasterName: "master-name",
SentinelAddrs: []string{":9126", ":9127", ":9128"},
})
- Redis Cluster模式
集群模式是对redis进行分片冗余存储模式,进而保证服务可用性。
使用下面的命令连接到 Redis Cluster,go-redis 支持按延迟或随机路由命令。
Go
rdb := redis.NewClusterClient(&redis.ClusterOptions{
Addrs: []string{":7000", ":7001", ":7002", ":7003", ":7004", ":7005"},// 若要根据延迟或随机路由命令,请启用以下命令之一// RouteByLatency: true,// RouteRandomly: true,
})
基本使用
基础使用
Go
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
"time"
)
// doCommand go-redis基本使用示例
func doCommand(rdb *redis.Client) {
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
defer cancel()
// 执行命令获取结果
val, err := rdb.Get(ctx, "key").Result()
fmt.Println(val, err)
// 先获取到命令对象
cmder := rdb.Get(ctx, "key")
fmt.Println(cmder.Val()) // 获取值
fmt.Println(cmder.Err()) // 获取错误
// 直接执行命令获取错误
err = rdb.Set(ctx, "key", 10, time.Hour).Err()
// 直接执行命令获取值
value := rdb.Get(ctx, "key").Val()
fmt.Println(value)
}
func main() {
fmt.Printf("项目测试")
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // 密码
DB: 0, // 数据库
PoolSize: 20, // 连接池大小
})
doCommand(rdb)
}
需要格外注意的是 :redis
库的引入加上了,版本号v8. 这样就可以使用带有context
的api
命令。在v6版本中是不带ctx的。使用时会提示错。
执行任意命令
go-redis
还提供了一个执行任意命令或自定义命令的 Do
方法,特别是一些 go-redis
库暂时不支持的命令都可以使用该方法执行。具体使用方法如下。
Go
// 直接执行命令获取错误
err := rdb.Do(ctx, "set", "key", 10, "EX", 3600).Err()
// 执行命令获取结果
val, err := rdb.Do(ctx, "get", "key").Result()
redis.Nil
go-redis
库提供了一个 redis.Nil
错误来表示 Key 不存在的错误。
因此在使用 go-redis
时需要注意对返回错误的判断。在某些场景下我们应该区别处理 redis.Nil
和其他不为 nil 的错误。
Go
// getValueFromRedis redis.Nil判断
func getValueFromRedis(key, defaultValue string) (string, error) {
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
defer cancel()
val, err := rdb.Get(ctx, key).Result()
if err != nil {// 如果返回的错误是key不存在
if errors.Is(err, redis.Nil) {
return defaultValue, nil
}
// 出其他错了
return "", err
}
return val, nil
}
其他场景
-
Zset
: 有序集合和集合一样也是string
类型元素的集合,且不允许重复的成员。 -
Key
: 扫描或遍历所有key
。 你可以使用KEYS prefix:\*
命令按前缀获取所有key
。 如果在生产环境中尽量不要这么使用,因为他会造成数据库的阻塞。scan
命令是一个基于游标的迭代器。 这意味着命令每次被调用都需要使用上一次这个调用返回的游标作为该次调用的游标参数,以此来延续之前的迭代过程。
Go
vals, err := rdb.Keys(ctx, "prefix*").Result()
-
pipline
-
事务
-
发布订阅消息
Go
// 发布消息
err := rdb.Publish(ctx, "mychannel1", "payload").Err()
if err != nil {
panic(err)
}
// 订阅消息
// There is no error because go-redis automatically reconnects on error.
pubsub := rdb.Subscribe(ctx, "mychannel1")
// Close the subscription when we are done.
defer pubsub.Close()
//接收消息
for {
msg, err := pubsub.ReceiveMessage(ctx)
if err != nil {
panic(err)
}
fmt.Println(msg.Channel, msg.Payload)
}
//发布消息
ch := pubsub.Channel()
for msg := range ch {
fmt.Println(msg.Channel, msg.Payload)
}
参考链接: