GoRedis 使用详解
Redis(远程字典服务器)是一种高性能的内存键值型数据库。它可以作为多种应用程序的缓存、数据库、消息代理和排行榜等。而 GoRedis 是 Golang 实现的 Redis 客户端,增加了不少方便易用的特性。本文将从多个方面详细阐述 GoRedis 的使用。
一、连接 Redis 数据库
GoRedis 的最基本用法是连接 Redis 数据库。连接可以使用以下两种方式:
import "github.com/go-redis/redis/v8"
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "",
DB: 0,
})
pong, err := rdb.Ping(ctx).Result()
fmt.Println(pong, err)
}
或者使用连接池:
func main() {
import (
"context"
"fmt"
"time"
"github.com/go-redis/redis/v8"
)
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
DB: 0,
})
defer rdb.Close()
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
pong, err := rdb.Ping(ctx).Result()
fmt.Println(pong, err)
poolSize := 10
maxPoolSize := 30
timeout := 2 * time.Second
rdbPool := &redis.Pool{
MaxIdle: poolSize,
MaxActive: maxPoolSize,
IdleTimeout: timeout,
Dial: func() (redis.Conn, error) {
conn, err := redis.Dial("tcp", "localhost:6379")
if err != nil {
return nil, err
}
return conn, nil
},
}
defer rdbPool.Close()
conn := rdbPool.Get()
defer conn.Close()
pong2, err := redis.String(conn.Do("PING"))
fmt.Println(pong2, err)
}
}
二、设置和获取过期时间
Redis 的值可以设置过期时间,通过 GoRedis 也能轻易应用。使用 TTL
方法获取一个键的剩余过期时间,EXPIRE
和 EXPIREAT
方法设置,DEL
方法删除这个键值即可。
import "github.com/go-redis/redis/v8"
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "",
DB: 0,
})
err := rdb.Set(ctx, "key", "value", time.Hour).Err()
if err != nil {
panic(err)
}
ttl, err := rdb.TTL(ctx, "key").Result()
if err != nil {
panic(err)
}
fmt.Println(ttl)
err = rdb.Expire(ctx, "key", time.Minute).Err()
if err != nil {
panic(err)
}
err = rdb.ExpireAt(ctx, "key", time.Now().Add(24*time.Hour)).Err()
if err != nil {
panic(err)
}
n, err := rdb.Del(ctx, "key").Result()
if err != nil {
panic(err)
}
fmt.Println(n)
}
三、GoRedis 和 Redis 的数据类型匹配
Redis 有多种数据类型,GoRedis 也提供了对应的 Go 语言数据结构相应的 API,相对应的数据类型包括:
字符串 (Strings)
操作字符串可以使用 GET
方法获取整个字符串,SET
方法设置。也可以使用 SETEX
方法设置带有过期时间的键值对,使用 APPEND
方法增加字符串长度。
哈希 (Hashes)
对于哈希,可使用 HSET
方法设置,HMSET
方法设置多组键值对。添加、删除和获取同理,并且通过 HGETALL
方法可以获得哈希表中所有的键值对。
列表 (Lists)
对于列表,使用 LPUSH
方法可以在列表前面添加元素,使用 RPUSH
方法可以在列表尾部添加元素。
import "github.com/go-redis/redis/v8"
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "",
DB: 0,
})
err := rdb.LPush(ctx, "key", "value", "value2").Err()
if err != nil {
panic(err)
}
err = rdb.RPush(ctx, "key", "value", "value2").Err()
if err != nil {
panic(err)
}
val, err := rdb.LPop(ctx, "key").Result()
if err != nil {
panic(err)
}
fmt.Println(val)
vals, err := rdb.LRange(ctx, "key", 0, -1).Result()
if err != nil {
panic(err)
}
for _, val := range vals {
fmt.Println(val)
}
}
集合 (Sets)
对于集合,SET
和 SADD
方法可以添加元素,SPOP
方法可以删除并返回随机一个元素。
有序集合 (Sorted Sets)
对于有序集合,ZADD
方法可以添加有序元素的成员和 score 值,ZRANGE
和 ZREVRANGE
获取对应元素的区间。
import "github.com/go-redis/redis/v8"
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "",
DB: 0,
})
err := rdb.ZAdd(ctx, "key", &redis.Z{Score: 1, Member: "value1"}, &redis.Z{Score: 2, Member: "value2"}).Err()
if err != nil {
panic(err)
}
vals, err := rdb.ZRange(ctx, "key", 0, -1).Result()
if err != nil {
panic(err)
}
fmt.Println(vals)
vals, err = rdb.ZRevRange(ctx, "key", 0, -1).Result()
if err != nil {
panic(err)
}
fmt.Println(vals)
}
四、GoRedis 的一些高级特性
事务 (Transactions)
在 GoRedis 中,MULTI
、EXEC
、WATCH
方法可以实现事务操作。首先使用 WATCH
方法监视某个值,当这个值发生变化时,MULTI
方法之间的代码块才会执行,而 EXEC
方法会执行 MULTI
方法块内的所有操作。
import "github.com/go-redis/redis/v8"
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "",
DB: 0,
})
err := rdb.Watch(ctx, func(tx *redis.Tx) error {
v, err := tx.Get(ctx, "key").Result()
if err != nil {
return err
}
new := v + "bar"
_, err = tx.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
pipe.Set(ctx, "key", new, 0)
return nil
})
if err != nil {
return err
}
return nil
}, "key")
if err != nil {
panic(err)
}
}
发布和订阅 (Pub/Sub)
GoRedis 也支持 Redis 中的发布和订阅功能。通过 Subscrip
和 Subscribe
方法,连接到频道并接收消息。使用 Publish
方法发布数据。
import (
"fmt"
"github.com/go-redis/redis/v8"
"time"
)
func main() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "",
DB: 0,
})
pubsub := rdb.Subscribe(ctx, "channel1")
_, err := pubsub.Receive(ctx)
if err != nil {
panic(err)
}
ch := pubsub.Channel()
go func() {
for msg := range ch {
fmt.Println(msg.Channel, msg.Payload)
}
}()
err = rdb.Publish(ctx, "channel1", "hello").Err()
if err != nil {
panic(err)
}
time.Sleep(time.Second)
_ = pubsub.Close()
_ = rdb.Close()
}
管道 (Pipeline)
GoRedis 的另一个高级功能是管道。使用该功能可将多个 Redis 操作组合成一组命令,可以显著减少网络延迟,并在秒级别执行这些操作。
import "github.com/go-redis/redis/v8"
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "",
DB: 0,
})
pipe := rdb.Pipeline()
incr := pipe.Incr(ctx, "pipeline_counter")
pipe.Expire(ctx, "pipeline_counter", time.Hour)
_, err := pipe.Exec(ctx)
if err != nil {
panic(err)
}
fmt.Println(incr.Val())
}
结论
本文从连接 Redis 数据库、设置和获取过期时间、GoRedis 和 Redis 的数据类型匹配、GoRedis 的一些高级特性等方面详细阐述了 GoRedis 的使用方法。GoRedis 不仅支持 Redis 的基本操作,还提供了一些高级特性,如事务、发布和订阅、管道等。