golang类型安全可定制化的Redis客户端插件库xredis的使用
golang类型安全可定制化的Redis客户端插件库xredis的使用
xredis是一个基于github.com/garyburd/redigo构建的Redis客户端库,旨在简化Redis客户端的创建,提供类型安全的调用,并封装底层细节以便轻松集成Redis。
特性
- 类型安全客户端
- 易于设置:
- 使用默认客户端
- 通过设置选项自定义客户端
- 使用redigo的redis.Pool
- 自动提供连接池
- 支持Redis哨兵:
- 写入操作发送到主节点
- 读取操作发送到从节点,如果没有可用从节点则回退到主节点
- 支持多种Redis命令(ECHO、INFO、PING、SET、GET、HSET、HGET等)
- 完全访问Redigo的API
依赖
- redigo (github.com/garyburd/redigo)
- go-sentinel (github.com/FZambia/go-sentinel)
示例
示例1:使用DefaultClient创建默认Redis客户端
package main
import (
"fmt"
"github.com/shomali11/xredis"
)
func main() {
client := xredis.DefaultClient()
defer client.Close()
fmt.Println(client.Ping()) // PONG <nil>
}
默认选项:
defaultHost = "localhost"
defaultPort = 6379
defaultPassword = ""
defaultDatabase = 0
defaultNetwork = "tcp"
defaultConnectTimeout = time.Second
defaultWriteTimeout = time.Second
defaultReadTimeout = time.Second
defaultConnectionIdleTimeout = 240 * time.Second
defaultConnectionMaxIdle = 100
defaultConnectionMaxActive = 10000
defaultConnectionWait = false
defaultTlsConfig = nil
defaultTlsSkipVerify = false
defaultTestOnBorrowTimeout = time.Minute
示例2:使用SetupClient创建自定义Redis客户端
package main
import (
"fmt"
"github.com/shomali11/xredis"
)
func main() {
options := &xredis.Options{
Host: "localhost",
Port: 6379,
}
client := xredis.SetupClient(options)
defer client.Close()
fmt.Println(client.Ping()) // PONG <nil>
}
可用选项:
type Options struct {
Host string
Port int
Password string
Database int
Network string
ConnectTimeout time.Duration
WriteTimeout time.Duration
ReadTimeout time.Duration
ConnectionIdleTimeout time.Duration
ConnectionMaxIdle int
ConnectionMaxActive int
ConnectionWait bool
TlsConfig *tls.Config
TlsSkipVerify bool
TestOnBorrowPeriod time.Duration
}
示例3:使用SetupSentinelClient创建Redis哨兵客户端
package main
import (
"fmt"
"github.com/shomali11/xredis"
)
func main() {
options := &xredis.SentinelOptions{
Addresses: []string{"localhost:26379"},
MasterName: "master",
}
client := xredis.SetupSentinelClient(options)
defer client.Close()
fmt.Println(client.Ping()) // PONG <nil>
}
示例4:使用NewClient通过redis.Pool创建Redis客户端
package main
import (
"fmt"
"github.com/garyburd/redigo/redis"
"github.com/shomali11/xredis"
)
func main() {
pool := &redis.Pool{
Dial: func() (redis.Conn, error) {
return redis.Dial("tcp", "localhost:6379")
},
}
client := xredis.NewClient(pool)
defer client.Close()
fmt.Println(client.Ping()) // PONG <nil>
}
示例5:使用Ping、Echo和Info命令
package main
import (
"fmt"
"github.com/shomali11/xredis"
)
func main() {
client := xredis.DefaultClient()
defer client.Close()
fmt.Println(client.Ping()) // PONG <nil>
fmt.Println(client.Echo("Hello")) // Hello <nil>
fmt.Println(client.FlushDb()) // <nil>
fmt.Println(client.FlushAll()) // <nil>
fmt.Println(client.Info())
}
示例6:使用SET、GET、DEL等命令
package main
import (
"fmt"
"github.com/shomali11/xredis"
)
func main() {
client := xredis.DefaultClient()
defer client.Close()
fmt.Println(client.Set("name", "Raed Shomali")) // true <nil>
fmt.Println(client.SetNx("name", "Hello")) // false <nil>
fmt.Println(client.SetEx("id", "10", 1)) // true <nil>
fmt.Println(client.Expire("name", 1)) // true <nil>
fmt.Println(client.Expire("unknown", 1)) // false <nil>
fmt.Println(client.Keys("*")) // [id name] <nil>
fmt.Println(client.Get("name")) // "Raed Shomali" true <nil>
fmt.Println(client.Exists("name")) // true <nil>
fmt.Println(client.Del("name")) // 1 <nil>
fmt.Println(client.Exists("name")) // false <nil>
fmt.Println(client.Get("name")) // "" false <nil>
fmt.Println(client.Del("name")) // 0 <nil>
fmt.Println(client.Append("name", "a")) // 1 <nil>
fmt.Println(client.Append("name", "b")) // 2 <nil>
fmt.Println(client.Append("name", "c")) // 3 <nil>
fmt.Println(client.Get("name")) // "abc" true <nil>
fmt.Println(client.GetRange("name", 0 , 1)) // "ab" <nil>
fmt.Println(client.SetRange("name", 2, "xyz")) // 5 <nil>
fmt.Println(client.Get("name")) // "abxyz" <nil>
fmt.Println(client.Scan(0, "*")) // 0 [name id] <nil>
fmt.Println(client.Del("id", "name")) // 2 <nil>
}
示例7:使用INCR、DECR等命令
package main
import (
"fmt"
"github.com/shomali11/xredis"
)
func main() {
client := xredis.DefaultClient()
defer client.Close()
fmt.Println(client.Set("integer", "10")) // true <nil>
fmt.Println(client.Set("float", "5.5")) // true <nil>
fmt.Println(client.Get("integer")) // 10 true <nil>
fmt.Println(client.Get("float")) // 5.5 true <nil>
fmt.Println(client.Incr("integer")) // 11 <nil>
fmt.Println(client.IncrBy("integer", 10)) // 21 <nil>
fmt.Println(client.DecrBy("integer", 5)) // 16 <nil>
fmt.Println(client.Decr("integer")) // 15 <nil>
fmt.Println(client.IncrByFloat("float", 3.3)) // 8.8 <nil>
fmt.Println(client.DecrByFloat("float", 1.1)) // 7.7 <nil>
fmt.Println(client.Get("integer")) // 15 true <nil>
fmt.Println(client.Get("float")) // 7.7 true <nil>
fmt.Println(client.Del("integer", "float")) // 2 <nil>
}
示例8:使用HSET、HGET等哈希命令
package main
import (
"fmt"
"github.com/shomali11/xredis"
)
func main() {
client := xredis.DefaultClient()
defer client.Close()
fmt.Println(client.HSet("hash", "name", "Raed Shomali")) // true <nil>
fmt.Println(client.HSet("hash", "sport", "Football")) // true <nil>
fmt.Println(client.HKeys("hash")) // [name sport] <nil>
fmt.Println(client.HScan("hash", 0, "*")) // 0 [name Raed Shomali sport Football] <nil>
fmt.Println(client.HGet("hash", "name")) // "Raed Shomali" true <nil>
fmt.Println(client.HGetAll("hash")) // map[name:Raed Shomali sport:Football] <nil>
fmt.Println(client.HExists("hash", "name")) // true <nil>
fmt.Println(client.HDel("hash", "name", "sport")) // 2 <nil>
fmt.Println(client.HGet("hash", "name")) // "" false <nil>
fmt.Println(client.HExists("hash", "name")) // false <nil>
fmt.Println(client.HGetAll("hash")) // map[] nil
fmt.Println(client.HDel("hash", "name")) // 0 <nil>
fmt.Println(client.HKeys("hash")) // [] <nil>
}
示例9:使用HINCR、HDECR等哈希命令
package main
import (
"fmt"
"github.com/shomali11/xredis"
)
func main() {
client := xredis.DefaultClient()
defer client.Close()
fmt.Println(client.HSet("hash", "integer", "10")) // true <nil>
fmt.Println(client.HSet("hash", "float", "5.5")) // true <nil>
fmt.Println(client.HIncr("hash", "integer")) // 11 <nil>
fmt.Println(client.HIncrBy("hash", "integer", 10)) // 21 <nil>
fmt.Println(client.HDecrBy("hash", "integer", 5)) // 16 <nil>
fmt.Println(client.HDecr("hash", "integer")) // 15 <nil>
fmt.Println(client.HIncrByFloat("hash", "float", 3.3)) // 8.8 <nil>
fmt.Println(client.HDecrByFloat("hash", "float", 1.1)) // 7.7 <nil>
fmt.Println(client.HDel("hash", "integer", "float")) // 2 <nil>
}
示例10:直接访问Redigo API
package main
import (
"fmt"
"github.com/garyburd/redigo/redis"
"github.com/shomali11/xredis"
)
func main() {
client := xredis.DefaultClient()
defer client.Close()
connection := client.GetConnection()
defer connection.Close()
fmt.Println(redis.String(connection.Do("INFO")))
}
更多关于golang类型安全可定制化的Redis客户端插件库xredis的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang类型安全可定制化的Redis客户端插件库xredis的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
xredis - Golang类型安全可定制化的Redis客户端插件库
xredis是一个为Golang设计的类型安全且高度可定制的Redis客户端库,它在标准Redis客户端基础上提供了更严格的类型检查和灵活的扩展能力。
主要特性
- 类型安全:所有Redis操作都带有类型检查
- 可定制化:可以轻松扩展和修改命令行为
- 链式调用:提供流畅的API设计
- 上下文支持:支持context.Context传递
- 连接池管理:内置高效的连接池
安装
go get github.com/xxx/xredis
基本使用示例
package main
import (
"context"
"fmt"
"github.com/xxx/xredis"
)
func main() {
// 创建xredis客户端
client := xredis.NewClient(&xredis.Options{
Addr: "localhost:6379",
Password: "", // 无密码
DB: 0, // 默认DB
})
ctx := context.Background()
// 设置字符串值
err := client.Set(ctx, "key", "value", 0).Err()
if err != nil {
panic(err)
}
// 获取字符串值
val, err := client.Get(ctx, "key").Result()
if err != nil {
panic(err)
}
fmt.Println("key", val)
// 设置带过期时间的键
err = client.SetEX(ctx, "temp_key", "temp_value", 10*time.Second).Err()
// 哈希表操作
err = client.HSet(ctx, "user:1", map[string]interface{}{
"name": "John",
"age": 30,
"email": "john@example.com",
}).Err()
// 获取哈希表字段
name, err := client.HGet(ctx, "user:1", "name").String()
age, err := client.HGet(ctx, "user:1", "age").Int()
// 管道操作
pipe := client.Pipeline()
pipe.Set(ctx, "pipe1", "value1", 0)
pipe.Set(ctx, "pipe2", "value2", 0)
_, err = pipe.Exec(ctx)
}
高级特性
1. 自定义命令
// 定义自定义命令
func (c *Client) MyCustomCommand(ctx context.Context, key string, value interface{}) *xredis.StringCmd {
cmd := xredis.NewStringCmd(ctx, "MYCUSTOM", key, value)
c.Process(ctx, cmd)
return cmd
}
// 使用自定义命令
result, err := client.MyCustomCommand(ctx, "mykey", "myvalue").Result()
2. 中间件支持
// 定义中间件
func loggingMiddleware(next xredis.HandlerFunc) xredis.HandlerFunc {
return func(ctx context.Context, cmd xredis.Cmder) error {
start := time.Now()
err := next(ctx, cmd)
duration := time.Since(start)
fmt.Printf("cmd=%s, args=%v, duration=%s, err=%v\n",
cmd.Name(), cmd.Args(), duration, err)
return err
}
}
// 应用中间件
client.WrapProcess(loggingMiddleware)
3. 类型安全操作
// 获取整数
count, err := client.Get(ctx, "counter").Int64()
// 获取布尔值
enabled, err := client.Get(ctx, "feature_enabled").Bool()
// 获取浮点数
price, err := client.Get(ctx, "product_price").Float64()
// 获取时间
expireAt, err := client.Get(ctx, "expire_at").Time()
4. 连接池配置
client := xredis.NewClient(&xredis.Options{
Addr: "localhost:6379",
Password: "",
DB: 0,
PoolSize: 100, // 连接池大小
MinIdleConns: 10, // 最小空闲连接数
MaxConnAge: 30 * time.Minute, // 连接最大存活时间
})
最佳实践
- 重用客户端:xredis客户端是线程安全的,应该重用而不是频繁创建销毁
- 使用上下文:传递context以便实现超时和取消
- 合理配置连接池:根据应用负载调整连接池大小
- 错误处理:始终检查命令执行错误
- 使用管道:批量操作时使用管道减少网络往返
性能考虑
xredis在标准Redis客户端基础上增加的类型安全层带来的开销极小,几乎可以忽略不计。主要的性能影响来自于:
- 连接池配置
- 网络延迟
- Redis服务器性能
通过合理配置连接池和使用管道,可以最大化性能。
xredis为Golang开发者提供了一个既安全又灵活的Redis客户端解决方案,特别适合需要严格类型检查和自定义扩展的中大型项目。