开发调试
- Tiny RDM:跨平台GUI工具
- windows版本下载 download.csdn.net/download/ch...
编辑
支持多种格式查看:内置高级文本代码编辑器,支持语法高亮/代码折叠/错误提示
便捷搜索过滤:使用正则匹配搜索键后,仍可进行二级过滤,组合筛选数据更方便
调试分析相关支持 :拥有命令行
、慢日志查询
、服务器命令实时监控
、发布/订阅
,极大提高Redis开发调试效率
一、go连接 Redis
在进行操作之前,需要确保已经安装 Redis 并启动 Redis 服务器,同时在 Go 项目中导入 go-redis
库(v9版本需要redis大于7.0.)
如果是7.0以下版本使用v8库 go get github.com/go-redis/redis/v8
go
go get github.com/redis/go-redis/v9
连接配置
go
package main
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
"time"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // No password set
DB: 0, // Use default DB
Protocol: 2, // Connection protocol
})
// 健康检查
if _, err := rdb.Ping(ctx).Result(); err != nil {
panic(fmt.Sprintf("Redis连接失败: %v", err))
}
}
二、核心操作
1. 基础命令
client.Set
方法的原型如下:
func (c *BaseClient) Set(ctx context.Context, key string, value interface{}, expiration time.Duration) *StatusCmd
ctx context.Context
context.Context
是 Go 语言中用于控制请求范围和传递请求元数据的工具。在client.Set
方法中,ctx
主要用于控制该操作的生命周期,例如设置操作的超时时间、传递取消信号等key string
:key
是要设置的键,它是一个字符串类型。在 Redis 中,键是唯一的,通过键可以存储和获取对应的值。value interface{}``value
是要设置的值,它的类型是interface{}
,这意味着可以传入任意类型的值。不过,在存储到 Redis 时,Redis 只能存储字符串类型的数据,所以go-redis
库会尝试将传入的值转换为字符串。expiration time.Duration
表示键值对的过期时间,它的类型是time.Duration
。如果设置为0
,则表示该键值对不会过期,会一直存储在 Redis 中;如果设置为一个正的时间间隔,那么在经过这个时间后,该键值对会自动从 Redis 中删除
go
package main
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
"time"
)
var ctx = context.Background()
type BikeInfo struct {
Model string `redis:"model"`
Brand string `redis:"brand"`
Type string `redis:"type"`
Price int `redis:"price"`
}
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // No password set
DB: 0, // Use default DB
Protocol: 2, // Connection protocol
})
err := rdb.Set(ctx, "name", "John", 0).Err()
if err != nil {
fmt.Println("新增数据失败:", err)
return
}
fmt.Println("新增数据成功")
val, err := client.Get(ctx, "name").Result()
if err != nil {
panic(err)
}
fmt.Println("name", val)
hashFields := []string{
"model", "Deimos",
"brand", "Ergonom",
"type", "Enduro bikes",
"price", "4972",
}
res1, err := client.HSet(ctx, "bike:1", hashFields).Result()
if err != nil {
panic(err)
}
fmt.Println(res1) // >>> 4
res2, err := client.HGet(ctx, "bike:1", "model").Result()
if err != nil {
panic(err)
}
fmt.Println(res2) // >>> Deimos
res3, err := client.HGet(ctx, "bike:1", "price").Result()
if err != nil {
panic(err)
}
fmt.Println(res3) // >>> 4972
res4, err := client.HGetAll(ctx, "bike:1").Result()
if err != nil {
panic(err)
}
fmt.Println(res4)
err = rdb.Del(ctx, "name").Err()
if err != nil {
fmt.Println("删除数据失败:", err)
return
}
fmt.Println("删除数据成功")
err = rdb.HDel(ctx, "bike:1", "model").Err()
if err != nil {
fmt.Println("删除哈希数据失败:", err)
return
}
fmt.Println("删除哈希数据成功")
var res4a BikeInfo
err = client.HGetAll(ctx, "bike:1").Scan(&res4a)
if err != nil {
panic(err)
}
fmt.Printf("Model: %v, Brand: %v, Type: %v, Price: $%v\n",
res4a.Model, res4a.Brand, res4a.Type, res4a.Price)
}
scss
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{Addr: "localhost:6379"})
// 方式1:通过 Set 方法直接设置过期时间(推荐)
err := rdb.Set(ctx, "captcha", "123456", 300*time.Second).Err() // 5分钟后过期
if err != nil {
panic(err)
}
// 方式2:使用 Expire 命令
err = rdb.Expire(ctx, "session", 2*time.Hour).Err() // 2小时后过期
if err != nil {
panic(err)
}
// 验证剩余时间
ttl, err := rdb.TTL(ctx, "session").Result()
if err != nil {
panic(err)
}
fmt.Printf("剩余生存时间: %v\n", ttl) // 输出: 1h59m59s(剩余时间)
// 取消键的过期时间 使用 PERSIST 命令移除过期时间
persisted, err := rdb.Persist(ctx, "session").Result()
if err != nil {
panic(err)
}
fmt.Printf("取消过期成功,剩余生存时间: %d 秒\n", persisted) // 输出: -1(永久存在)
三、高级功能
1. 管道技术(性能优化)
go
pipe := rdb.Pipeline()
for i := 0; i < 5; i++ {
pipe.Set(ctx, fmt.Sprintf("seat:%v", i), fmt.Sprintf("#%v", i), 0)
}
cmds, err := pipe.Exec(ctx)
if err != nil {
panic(err)
}
for _, c := range cmds {
fmt.Printf("%v;", c.(*redis.StatusCmd).Val())
}
fmt.Println("")
// >>> OK;OK;OK;OK;OK;
pipe = rdb.Pipeline()
get0Result := pipe.Get(ctx, "seat:0")
get3Result := pipe.Get(ctx, "seat:3")
get4Result := pipe.Get(ctx, "seat:4")
cmds, err = pipe.Exec(ctx)
// The results are available only after the pipeline
// has finished executing.
fmt.Println(get0Result.Val()) // >>> #0
fmt.Println(get3Result.Val()) // >>> #3
fmt.Println(get4Result.Val()) // >>> #4
性能对比:管道技术可减少90%网络开销
2. 事务处理
scss
trans := rdb.TxPipeline()
trans.IncrBy(ctx, "counter:1", 1)
trans.IncrBy(ctx, "counter:2", 2)
trans.IncrBy(ctx, "counter:3", 3)
cmds, err = trans.Exec(ctx)
for _, c := range cmds {
fmt.Println(c.(*redis.IntCmd).Val())
}
3. 集群支持
php
client := redis.NewClusterClient(&redis.ClusterOptions{
Addrs: []string{":16379", ":16380", ":16381", ":16382", ":16383", ":16384"},
// To route commands by latency or randomly, enable one of the following.
//RouteByLatency: true,
//RouteRandomly: true,
})
4. Pub/Sub 模式
go
ctx := context.Background()
// 创建订阅对象
pubsub := rdb.Subscribe(ctx, "news")
// 在独立 Goroutine 中接收消息
go func() {
for {
msg, err := pubsub.ReceiveMessage(ctx)
if err != nil {
log.Println("订阅中断:", err)
return
}
fmt.Printf("收到消息 - 频道: %s, 内容: %s\n", msg.Channel, msg.Payload)
}
}()
// 发布消息到指定频道
_, err = rdb.Publish(ctx, "news", "突发新闻:Redis 7.4 发布!").Result()
if err != nil {
panic(err)
}
// 取消订阅单个频道
err = pubsub.Unsubscribe(ctx, "news").Err()
if err != nil {
panic(err)
}
四、性能优化
- 连接池配置
c
rdb := redis.NewClient(&redis.Options{
PoolSize: 50, // 最大连接数
MinIdleConns: 10, // 最小空闲连接
MaxConnAge: 30 * time.Minute, // 连接最大存活时间
IdleTimeout: 5 * time.Minute, // 空闲超时
Logger: log.Default(), // 集成标准日志
})
五、缓存策略
scss
// 缓存穿透保护
val, err := rdb.Get(ctx, "hot_key").Result()
if err == redis.Nil {
val = fetchFromDB() // 从数据库获取
rdb.Set(ctx, "hot_key", val, 5*time.Minute)
}