golang实现Redis客户端操作的高效插件库godis的使用
golang实现Redis客户端操作的高效插件库godis的使用
godis简介
godis是一个用Golang实现的Redis客户端库,参考了Jedis的设计。这个库实现了大多数Redis命令,包括普通Redis命令、集群命令、哨兵命令、管道命令和事务命令。
如果你曾经使用过Jedis,那么你可以轻松使用godis,因为godis的方法几乎与Jedis相同。特别值得一提的是,godis实现了单机模式和集群模式下的分布式锁,性能比Redisson更好。
特性
- 集群支持
- 管道操作
- 事务支持
- 分布式锁
- 其他功能正在开发中
安装
使用go get安装:
go get -u github.com/piaohao/godis
或者使用go.mod:
require github.com/piaohao/godis latest
快速开始
1. 基础示例
package main
import (
"github.com/piaohao/godis"
)
func main() {
// 创建Redis客户端连接
redis := godis.NewRedis(&godis.Option{
Host: "localhost",
Port: 6379,
Db: 0,
})
defer redis.Close()
// 设置键值
redis.Set("godis", "1")
// 获取键值
arr, _ := redis.Get("godis")
println(arr)
}
2. 使用连接池
package main
import (
"github.com/piaohao/godis"
)
func main() {
option := &godis.Option{
Host: "localhost",
Port: 6379,
Db: 0,
}
// 创建连接池
pool := godis.NewPool(&godis.PoolConfig{}, option)
// 从连接池获取连接
redis, _ := pool.GetResource()
defer redis.Close()
redis.Set("godis", "1")
arr, _ := redis.Get("godis")
println(arr)
}
3. 发布订阅
package main
import (
"github.com/piaohao/godis"
"time"
)
func main() {
option := &godis.Option{
Host: "localhost",
Port: 6379,
Db: 0,
}
pool := godis.NewPool(&godis.PoolConfig{}, option)
// 启动订阅协程
go func() {
redis, _ := pool.GetResource()
defer redis.Close()
pubsub := &godis.RedisPubSub{
OnMessage: func(channel, message string) {
println(channel, message)
},
OnSubscribe: func(channel string, subscribedChannels int) {
println(channel, subscribedChannels)
},
OnPong: func(channel string) {
println("recieve pong")
},
}
redis.Subscribe(pubsub, "godis")
}()
time.Sleep(1 * time.Second)
{
// 发布消息
redis, _ := pool.GetResource()
defer redis.Close()
redis.Publish("godis", "godis pubsub")
redis.Close()
}
time.Sleep(1 * time.Second)
}
4. 集群操作
package main
import (
"github.com/piaohao/godis"
"time"
)
func main() {
// 创建Redis集群客户端
cluster := godis.NewRedisCluster(&godis.ClusterOption{
Nodes: []string{"localhost:7000", "localhost:7001", "localhost:7002", "localhost:7003", "localhost:7004", "localhost:7005"},
ConnectionTimeout: 0,
SoTimeout: 0,
MaxAttempts: 0,
Password: "",
PoolConfig: &godis.PoolConfig{},
})
cluster.Set("cluster", "godis cluster")
reply, _ := cluster.Get("cluster")
println(reply)
}
5. 管道操作
package main
import (
"github.com/piaohao/godis"
"time"
)
func main() {
option := &godis.Option{
Host: "localhost",
Port: 6379,
Db: 0,
}
pool := godis.NewPool(&godis.PoolConfig{}, option)
redis, _ := pool.GetResource()
defer redis.Close()
// 创建管道
p := redis.Pipelined()
// 添加命令到管道
infoResp, _ := p.Info()
timeResp, _ := p.Time()
// 执行管道中的所有命令
p.Sync()
// 获取结果
timeList, _ := timeResp.Get()
println(timeList)
info, _ := infoResp.Get()
println(info)
}
6. 事务操作
package main
import (
"github.com/piaohao/godis"
"time"
)
func main() {
option := &godis.Option{
Host: "localhost",
Port: 6379,
Db: 0,
}
pool := godis.NewPool(nil, option)
redis, _ := pool.GetResource()
defer redis.Close()
// 开启事务
p, _ := redis.Multi()
// 添加命令到事务
infoResp, _ := p.Info()
timeResp, _ := p.Time()
// 执行事务
p.Exec()
// 获取结果
timeList, _ := timeResp.Get()
println(timeList)
info, _ := infoResp.Get()
println(info)
}
7. 分布式锁
单机Redis锁
package main
import (
"github.com/piaohao/godis"
"time"
)
func main() {
// 创建锁管理器
locker := godis.NewLocker(&godis.Option{
Host: "localhost",
Port: 6379,
Db: 0,
}, &godis.LockOption{
Timeout: 5*time.Second,
})
// 尝试获取锁
lock, err := locker.TryLock("lock")
if err == nil && lock!=nil {
// 执行业务代码
// ...
// 释放锁
locker.UnLock(lock)
}
}
Redis集群锁
package main
import (
"github.com/piaohao/godis"
"time"
)
func main() {
// 创建集群锁管理器
locker := godis.NewClusterLocker(&godis.ClusterOption{
Nodes: []string{"localhost:7000", "localhost:7001", "localhost:7002", "localhost:7003", "localhost:7004", "localhost:7005"},
ConnectionTimeout: 0,
SoTimeout: 0,
MaxAttempts: 0,
Password: "",
PoolConfig: &godis.PoolConfig{},
}, &godis.LockOption{
Timeout: 5*time.Second,
})
// 尝试获取锁
lock, err := locker.TryLock("lock")
if err == nil && lock!=nil {
// 执行业务代码
// ...
// 释放锁
locker.UnLock(lock)
}
}
许可证
godis
采用MIT许可证,100%免费且开源。
感谢
- [jedis] - Java实现的流行Redis客户端
- [gf] - Golang实现的优秀Web框架
- [go-commons-pool] - 参考了Apache Common Pool
联系方式
更多关于golang实现Redis客户端操作的高效插件库godis的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang实现Redis客户端操作的高效插件库godis的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用godis实现高效Redis客户端操作
godis是一个高性能的Go语言Redis客户端库,它提供了简洁易用的API来操作Redis数据库。下面我将详细介绍如何使用godis库进行高效的Redis操作。
安装godis
首先需要安装godis库:
go get github.com/redis/go-redis/v9
基本使用
1. 连接Redis
package main
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
)
func main() {
// 创建Redis客户端
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379", // Redis地址
Password: "", // 密码
DB: 0, // 数据库编号
})
// 测试连接
ctx := context.Background()
pong, err := rdb.Ping(ctx).Result()
if err != nil {
panic(err)
}
fmt.Println(pong) // 输出: PONG
}
2. 基本操作示例
// 设置键值
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)
// 设置带过期时间的键
err = rdb.Set(ctx, "key2", "value", 10*time.Second).Err()
if err != nil {
panic(err)
}
// 删除键
rdb.Del(ctx, "key")
// 检查键是否存在
exists, err := rdb.Exists(ctx, "key").Result()
if err != nil {
panic(err)
}
fmt.Println(exists) // 0表示不存在
高级功能
1. 管道(Pipeline)操作
管道可以一次性发送多个命令到Redis服务器,减少网络往返时间:
pipe := rdb.Pipeline()
// 添加多个命令到管道
pipe.Set(ctx, "key1", "value1", 0)
pipe.Set(ctx, "key2", "value2", 0)
pipe.Incr(ctx, "counter")
// 执行管道中的所有命令
_, err := pipe.Exec(ctx)
if err != nil {
panic(err)
}
2. 事务(Multi/Exec)
// 使用Watch实现乐观锁
err := rdb.Watch(ctx, func(tx *redis.Tx) error {
// 获取当前值
n, err := tx.Get(ctx, "counter").Int()
if err != nil && err != redis.Nil {
return err
}
// 在Watch期间如果counter被修改,事务会失败
_, err = tx.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
pipe.Set(ctx, "counter", n+1, 0)
return nil
})
return err
}, "counter")
if err != nil {
panic(err)
}
3. 发布/订阅
// 订阅
pubsub := rdb.Subscribe(ctx, "mychannel")
defer pubsub.Close()
// 接收消息
ch := pubsub.Channel()
for msg := range ch {
fmt.Println(msg.Channel, msg.Payload)
}
// 发布
err := rdb.Publish(ctx, "mychannel", "hello").Err()
if err != nil {
panic(err)
}
4. 连接池配置
godis内置连接池,可以这样配置:
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "",
DB: 0,
// 连接池配置
PoolSize: 100, // 最大连接数
MinIdleConns: 10, // 最小空闲连接数
MaxConnAge: time.Hour, // 连接最大存活时间
})
性能优化建议
- 使用Pipeline:批量操作时使用Pipeline可以减少网络往返时间
- 合理配置连接池:根据业务负载调整PoolSize和MinIdleConns
- 避免大键:单个键的值不宜过大,会影响性能
- 使用合适的数据结构:根据场景选择合适的数据结构(如Hash、Set等)
- 复用Context:避免频繁创建新的Context对象
完整示例
package main
import (
"context"
"fmt"
"time"
"github.com/redis/go-redis/v9"
)
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "",
DB: 0,
PoolSize: 100,
})
ctx := context.Background()
// 基本操作
rdb.Set(ctx, "name", "Alice", 0)
name, _ := rdb.Get(ctx, "name").Result()
fmt.Println("name:", name)
// Hash操作
rdb.HSet(ctx, "user:1", "name", "Bob", "age", 30)
user, _ := rdb.HGetAll(ctx, "user:1").Result()
fmt.Println("user:", user)
// 列表操作
rdb.LPush(ctx, "tasks", "task1", "task2")
tasks, _ := rdb.LRange(ctx, "tasks", 0, -1).Result()
fmt.Println("tasks:", tasks)
// 设置操作
rdb.SAdd(ctx, "tags", "golang", "redis", "database")
tags, _ := rdb.SMembers(ctx, "tags").Result()
fmt.Println("tags:", tags)
// 有序集合
rdb.ZAdd(ctx, "leaderboard", redis.Z{Score: 100, Member: "player1"})
leaders, _ := rdb.ZRevRangeWithScores(ctx, "leaderboard", 0, 2).Result()
fmt.Println("leaders:", leaders)
// 带过期时间的键
rdb.Set(ctx, "temp", "value", 10*time.Second)
ttl, _ := rdb.TTL(ctx, "temp").Result()
fmt.Println("ttl:", ttl)
}
godis提供了丰富的方法来操作Redis的各种数据结构,通过合理使用可以构建高效的Redis客户端应用。